# Enrichment agent flags reference

> agent_runner.py flags by mode: table, doc, context_overlay; source inputs, usage signal, glossaries, feedback, GitHub MCP, refinement, and required Vertex project and model values.

- Repository: GoogleCloudPlatform/knowledge-catalog
- GitHub: https://github.com/GoogleCloudPlatform/knowledge-catalog
- Human docs: https://grok-wiki.com/public/docs/googlecloudplatform-knowledge-catalog-9cee6ee3cba5
- Complete Markdown: https://grok-wiki.com/public/docs/googlecloudplatform-knowledge-catalog-9cee6ee3cba5/llms-full.txt

## Source Files

- `agents/enrichment/src/agent_runner.py`
- `agents/enrichment/README.md`
- `agents/enrichment/src/modes/table_mode.py`
- `agents/enrichment/src/modes/doc_mode.py`
- `agents/enrichment/src/tools/feedback_tools.py`
- `agents/enrichment/src/tools/bq_usage_tools.py`
- `agents/enrichment/src/linking.py`

---

---
title: "Enrichment agent flags reference"
description: "agent_runner.py flags by mode: table, doc, context_overlay; source inputs, usage signal, glossaries, feedback, GitHub MCP, refinement, and required Vertex project and model values."
---

`agents/enrichment/src/agent_runner.py` is the unified CLI entrypoint for the Knowledge Catalog enrichment agent. It parses Abseil flags, configures Vertex AI from `--project`, `--location`, and `--model`, then dispatches to `doc_mode`, `table_mode`, or `context_overlay_mode`. The agent runs read-only `kcmd init` and `kcmd pull` (or `kcmd reference` in overlay mode); you publish with `kcmd push`.

<Note>
Set `PYTHONPATH=agents/enrichment/src` before invoking the runner. Run `python3 agents/enrichment/src/agent_runner.py --help` for the live flag list.
</Note>

## Invocation

```bash
export PYTHONPATH=agents/enrichment/src

python3 agents/enrichment/src/agent_runner.py \
  --mode=<doc|table|context_overlay> \
  --project=<gcp_project> \
  --model=<vertex_model> \
  --output_dir=<local_dir> \
  [mode-specific flags]
```

On startup the runner sets:

| Environment variable | Source |
|---|---|
| `GOOGLE_GENAI_USE_VERTEXAI` | `True` |
| `GOOGLE_CLOUD_PROJECT` | `--project` |
| `GOOGLE_CLOUD_LOCATION` | `--location` (default `global`) |

## Mode selection

<ParamField body="mode" type="enum">
One of `doc`, `table`, or `context_overlay`. Empty string triggers inference: if `--dataset` is set, mode becomes `table`; otherwise `doc`. `context_overlay` is never inferred — pass `--mode=context_overlay` explicitly.
</ParamField>

```mermaid
flowchart TD
  A[agent_runner.py] --> B{--refine_instruction set?}
  B -->|yes| R[refine.run_one_refinement]
  B -->|no| C{--mode or inferred}
  C -->|doc| D[doc_mode.run]
  C -->|table| T[table_mode.run]
  C -->|context_overlay| O[context_overlay_mode.run]
```

| Mode | Target | kcmd behavior | Primary output |
|---|---|---|---|
| `table` | BigQuery dataset | `kcmd init --bigquery-dataset` + `pull` | Enriched overviews on live `@bigquery` entries |
| `doc` | Knowledge-base entry group | `kcmd init --entry-group` + `pull` | LLM-emitted generic KB entries |
| `context_overlay` | Dataset + editable entry group | `kcmd reference` (read-only 1P tables) | New overlay entries in `--entry_group` |

## Required configuration

These flags are validated in `main()` before any mode runs:

<ParamField body="project" type="string" required>
Google Cloud project that hosts the Vertex AI model. Raises `UsageError` when omitted.
</ParamField>

<ParamField body="model" type="string" required>
Vertex AI model ID for reasoning-heavy steps (for example `gemini-2.5-pro`). Raises `UsageError` when omitted. Structured sub-steps use a pinned Flash model internally.
</ParamField>

<ParamField body="location" type="string">
Vertex AI region for the model. Default: `global`. Example: `--location=us-central1`.
</ParamField>

<ParamField body="output_dir" type="string">
Local directory for the generated mdcode tree, `trajectory.json`, and `refine_session.json`. Required for enrichment runs (modes exit early without it) and mandatory with `--refine_instruction`.
</ParamField>

### Mode-specific requirements

| Flag | `doc` | `table` | `context_overlay` |
|---|---|---|---|
| `--project` | required | required | required |
| `--model` | required | required | required |
| `--output_dir` | required* | required* | required* |
| `--dataset` | — | required | required |
| `--entry_group` | required | — | required |

\*Not enforced by `UsageError` in `main()`, but each mode prints an error and returns when `output_dir` is missing.

<ParamField body="dataset" type="string">
BigQuery dataset as `project.dataset` (for example `my-proj.analytics`). Required in `table` and `context_overlay` modes.
</ParamField>

<ParamField body="entry_group" type="string">
Entry group as `project.location.entryGroupId`. Required in `doc` and `context_overlay` modes. In **doc** mode the entry group must already exist (the agent does not create it). In **context_overlay** mode this is where new overlay entries are written.
</ParamField>

## Flag applicability by mode

`R` = required, `✓` = optional, `—` = not used by the mode.

| Flag | `doc` | `table` | `context_overlay` |
|---|---|---|---|
| `--mode` | ✓ | ✓ | ✓ |
| `--topic` | ✓ | ✓ | ✓ |
| `--folders` / `--folder` | ✓ | ✓ | ✓ |
| `--docs` | ✓ | — | ✓ |
| `--tables` | — | — | ✓ |
| `--include_usage` | — | ✓ | ✓ |
| `--usage_window_days` | — | ✓ | ✓ |
| `--usage_scope` | — | ✓ | ✓ |
| `--anonymize_users` | — | ✓ | ✓ |
| `--glossaries` | — | ✓ | — |
| `--feedback_dir` | ✓ | ✓ | ✓ |
| `--feedback_files` | ✓ | ✓ | ✓ |
| `--repo` | ✓ | ✓ | ✓ |
| `--repo_ref` | ✓ | ✓ | ✓ |
| `--repo_subdir` | ✓ | ✓ | ✓ |
| `--mcp_config` | ✓ | ✓ | ✓ |
| `--interactive` | ✓ | ✓ | ✓ |
| `--refine_instruction` | ✓ | ✓ | ✓ |

## Source context flags

<ParamField body="topic" type="string">
Free-text use case or instruction steering enrichment. Default: `Metadata enrichment`.
</ParamField>

<ParamField body="folders" type="list">
Comma-separated mixed list routed per entry: Google Drive folder URLs/IDs and/or local directories of `.md` files (read recursively). In **doc** mode, Drive folders seed depth-1 children; in **table** and **context_overlay** modes they join the relevance-router candidate pool.
</ParamField>

<ParamField body="folder" type="list">
Deprecated alias for `--folders`. Both lists are merged.
</ParamField>

<ParamField body="docs" type="list">
Comma-separated mixed list: Google Doc URLs/IDs and/or local `.md` files. **doc** mode: depth-0 spine documents. **context_overlay** mode: routed to tables alongside folder content. **Not passed to table mode** — use `--folders` there.
</ParamField>

<ParamField body="tables" type="list">
**context_overlay only.** Restrict enrichment to specific tables — short names or `proj.ds.table` FQNs. Empty means every table in `--dataset`.
</ParamField>

### Local vs Drive routing

Each entry in `--docs` or `--folders` is classified independently:

1. Starts with `http://` or `https://` → Google Drive
2. Ends in `.md` or `.markdown` → local Markdown file
3. Path-shaped (`/abs`, `./rel`, `../rel`, `~/path`, or contains `/`) → local directory or file
4. Bare name that exists on disk → local
5. Otherwise → Google Drive ID

Absolute paths are recommended; relative paths resolve from the agent's working directory.

## BigQuery usage signal

Applies to `table` and `context_overlay` modes. Fetches query history from `region-<R>.INFORMATION_SCHEMA.JOBS_BY_PROJECT` (with `JOBS_BY_USER` fallback) and emits a `<table>.queries.md` sidecar conforming to the Dataplex `queries` aspect type.

<ParamField body="include_usage" type="bool">
Fetch and emit per-table usage signals. Default: `true`. Set `--include_usage=false` to skip the BigQuery scan entirely.
</ParamField>

<ParamField body="usage_window_days" type="integer">
Days of query history to aggregate. Default: `30`.
</ParamField>

<ParamField body="usage_scope" type="enum">
One of `auto`, `project`, or `user`. Default: `auto`.

- `auto` — try `JOBS_BY_PROJECT`, fall back to `JOBS_BY_USER` on permission failure
- `project` — require `JOBS_BY_PROJECT`
- `user` — only the caller's own queries (always works, narrower signal)
</ParamField>

<ParamField body="anonymize_users" type="bool">
Replace user emails with stable SHA hashes in the usage signal. Default: `false`.
</ParamField>

## Glossary column linking

**table mode only.** When `--glossaries` is set, the agent pulls glossary terms as reference, runs the LinkingAgent (`linking.apply_column_linking`), and injects field-level `links.definition` into each `<table>.yaml`.

<ParamField body="glossaries" type="list">
Comma-separated Dataplex glossaries as `project.location.glossaryId` (for example `my-proj.us.business-glossary`). Invalid entries disable linking with a warning.
</ParamField>

## User feedback proposals

All three modes accept feedback. Proposals are the **highest-priority** context source and override conflicting information from Drive docs, semantic search, and `INFORMATION_SCHEMA` patterns.

<ParamField body="feedback_dir" type="string">
Directory walked recursively for `.md` and `.json` feedback files. Each file holds pure JSON shaped `{"proposals": [...]}`.
</ParamField>

<ParamField body="feedback_files" type="list">
Explicit comma-separated feedback file paths. Combinable with `--feedback_dir`.
</ParamField>

Each proposal includes `target_asset` (TABLE or COLUMN FQN), `proposed_enrichment`, and optionally `eval_candidate.golden_sql`. In table and overlay modes proposals route per table; in doc mode they apply globally. Valid `golden_sql` values become `[Source: User Feedback]` entries in the queries aspect.

<AccordionGroup>
<Accordion title="Proposal JSON shape">
```json
{
  "proposals": [
    {
      "classification": {"detection_signal": "...", "gap_type": "..."},
      "target_asset": {"type": "COLUMN", "name": "proj.ds.table.column"},
      "current_context_flaw": "what was wrong",
      "proposed_enrichment": {"action": "ADD_SYNONYM", "value": "..."},
      "evidence": {"reasoning": "...", "trajectory_quote": "..."},
      "confidence_grade": 0.9,
      "eval_candidate": {
        "is_valid_candidate": true,
        "user_query_intent": "How many orders last week?",
        "golden_sql": "SELECT COUNT(*) FROM `proj.ds.orders` ..."
      }
    }
  ]
}
```
</Accordion>
</AccordionGroup>

## GitHub source-code input

All modes accept an optional GitHub repository explored agentically via the GitHub MCP server. Failure is non-fatal — the run degrades to no code context.

<ParamField body="repo" type="string">
GitHub repo as `owner/name` or a GitHub URL. Empty disables code context.
</ParamField>

<ParamField body="repo_ref" type="string">
Branch, tag, or SHA. Empty uses the repo default branch.
</ParamField>

<ParamField body="repo_subdir" type="string">
Path prefix to scope exploration (for example `src/server`).
</ParamField>

<ParamField body="mcp_config" type="string">
Path to an `mcp.json` describing the GitHub MCP server. Falls back to `KC_ENRICH_MCP_CONFIG`, then the built-in remote HTTP server.
</ParamField>

| Environment variable | Purpose |
|---|---|
| `GITHUB_PERSONAL_ACCESS_TOKEN` | Token for the MCP server (default env var name) |
| `KC_ENRICH_MCP_CONFIG` | Path to `mcp.json` when `--mcp_config` is unset |
| `KC_ENRICH_GITHUB_MCP_SERVER` | Server key in `mcp.json` (default `github_remote`; use `github` for local stdio) |
| `KC_ENRICH_GITHUB_MCP_URL` | Override remote MCP URL (default `https://api.githubcopilot.com/mcp/`) |

In **doc** mode, code component cards surface as their own KB entries. In **table** and **context_overlay** modes, cards join the relevance-router pool so code referencing a table grounds that table's overview and queries aspect.

<RequestExample>
```bash
export GITHUB_PERSONAL_ACCESS_TOKEN=ghp_...
export PYTHONPATH=agents/enrichment/src

python3 agents/enrichment/src/agent_runner.py \
  --mode=table \
  --dataset=my-proj.analytics \
  --folders=./local_md_corpus \
  --repo=my-org/etl-pipeline --repo_ref=main \
  --project=my-gcp-project \
  --model=gemini-2.5-pro \
  --output_dir=/tmp/enrich_out
```
</RequestExample>

## Refinement flags

After the initial run, refinement reuses loaded context and never re-reads source docs or re-pulls the dataset.

<ParamField body="interactive" type="bool">
Stay in a `refine>` REPL after enrichment for free-text changes. Default: `false`. No-op on a non-TTY.
</ParamField>

<ParamField body="refine_instruction" type="string">
Apply one refinement turn to the saved session in `--output_dir`, then exit. Skips the enrichment pipeline entirely. Requires a prior run's `refine_session.json`. Used by the webapp persist-and-re-invoke flow.
</ParamField>

When `--refine_instruction` is set, only `--output_dir`, `--project`, and `--model` are needed (plus the instruction itself). The runner calls `refine.run_one_refinement` and returns without dispatching to a mode.

<RequestExample>
```bash
# Initial run
python3 agents/enrichment/src/agent_runner.py \
  --mode=doc \
  --docs="https://docs.google.com/document/d/abc123" \
  --entry_group=my-proj.us.my-kb \
  --project=my-gcp-project \
  --model=gemini-2.5-pro \
  --output_dir=/tmp/enrich_out

# Single refinement turn (no pipeline re-run)
python3 agents/enrichment/src/agent_runner.py \
  --refine_instruction="make the overview more concise" \
  --project=my-gcp-project \
  --model=gemini-2.5-pro \
  --output_dir=/tmp/enrich_out
```
</RequestExample>

## Supplementary environment variables

| Variable | Used by | Effect |
|---|---|---|
| `KCMD_BIN` | `kcmd_tools.py` | Override path to the `kcmd` binary |
| `KC_ENRICH_CACHE_MODE` | `drive_tools`, `bq_usage_tools` | `off`, `raw`, or `summary` (default `summary`) |
| `KC_ENRICH_CACHE` | `drive_tools` | Legacy alias: `off` forces cache off |
| `KC_ENRICH_USAGE_SNAPSHOT_TABLE` | `bq_usage_tools` | Reserved for a future snapshot-table fast path |

## Mode examples

<CodeGroup>
```bash title="Table mode"
python3 agents/enrichment/src/agent_runner.py \
  --mode=table \
  --dataset=my-proj.analytics \
  --folders=https://drive.google.com/drive/folders/abc,./corpus \
  --topic="Customer 360 data" \
  --glossaries=my-proj.us.business-glossary \
  --include_usage=true --usage_window_days=90 \
  --project=my-gcp-project \
  --location=us-central1 \
  --model=gemini-2.5-pro \
  --output_dir=/tmp/enrich_out
```

```bash title="Doc mode"
python3 agents/enrichment/src/agent_runner.py \
  --mode=doc \
  --docs="https://docs.google.com/document/d/abc,./notes/spine.md" \
  --folders=./local_md_corpus \
  --topic="Order pipeline documentation" \
  --entry_group=my-proj.us.my-kb \
  --project=my-gcp-project \
  --model=gemini-2.5-pro \
  --output_dir=/tmp/enrich_out
```

```bash title="Context overlay mode"
python3 agents/enrichment/src/agent_runner.py \
  --mode=context_overlay \
  --dataset=my-proj.analytics \
  --entry_group=my-proj.us.overlays \
  --tables=orders,customers \
  --folders=./corpus \
  --docs=./notes/table-notes.md \
  --project=my-gcp-project \
  --model=gemini-2.5-pro \
  --output_dir=/tmp/enrich_out
```
</CodeGroup>

## Error cases

| Condition | Result |
|---|---|
| Missing `--project` or `--model` | `UsageError` before mode dispatch |
| `context_overlay` without `--dataset` or `--entry_group` | `UsageError` |
| `doc` without `--entry_group` | `UsageError` |
| `--refine_instruction` without `--output_dir` | `UsageError` |
| Missing `--output_dir` on enrichment run | Mode prints error and exits (no mdcode written) |
| Extra positional arguments | `UsageError: Too many command-line arguments` |
| Invalid `--dataset` format | `ValueError` — must be `project.dataset` |
| Invalid `--entry_group` format | `ValueError` — must be `project.location.entryGroupId` |
| Unparseable `--repo` | `ValueError` from `github_tools.parse_repo` |
| GitHub MCP unreachable | Warning logged; run continues without code context |

<Warning>
Doc mode requires the target entry group to exist before the run. Create it with `gcloud dataplex entry-groups create` or equivalent, then pass `--entry_group`.
</Warning>

## Related pages

<CardGroup>
<Card title="Run the catalog enrichment agent" href="/run-catalog-enrichment-agent">
End-to-end workflow for table, doc, and context_overlay modes with Drive, feedback, and refinement.
</Card>
<Card title="Enrichment workflows" href="/enrichment-workflows">
How enrichment agents read metadata, ground on external sources, and hand off to kcmd push.
</Card>
<Card title="Installation" href="/installation">
Prerequisites, Python setup, ADC scopes, and Vertex AI credential configuration.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Auth, billing, glossary provisioning, and model credential failures.
</Card>
</CardGroup>
