TableRAG configuration reference

August 13, 2026 ยท View on GitHub

TableRAG keeps project-specific paths and spreadsheet conventions in YAML. Start with projects/example.yaml, or generate a local configuration with table-rag init.

Local configurations should end in .local.yaml; that pattern is ignored by Git.

Complete example

project_id: my-project
name: My Project
language: zh-CN
database: ../.table-rag/my-project/{branch}.duckdb
knowledge: my-project.knowledge.yaml

sources:
  - path: D:/data/config
    recursive: false
    exclude_paths:
      - generated
      - temp/export

formal_names:
  enabled: true
  # Optional. When omitted, TableRAG checks <source>/strings/cn.
  path: D:/data/tables/strings/cn
  auto_discover: true
  locale: zh-CN
  name_candidates: [name, display_name, title, label]
  overrides:
    - file: legacy-product.xls
      key_field: id
      source_key_field: id
      display_field: display_name

watch:
  enabled: true
  debounce_ms: 750
  settle_ms: 750
  retry_attempts: 6
  retry_delay_ms: 500

layout:
  default:
    rows:
      zh_comment: 1
      en_description: 2
      field_name: 3
      field_type: 4
    data_start_row: 5
  overrides:
    - file: legacy-*.xls
      sheet: Sheet1
      rows:
        zh_comment: 1
        field_name: 2
        field_type: 3
      data_start_row: 4
    - file: legacy-*.xls
      sheet: Notes
      ignore: true

branches:
  enabled: true
  repository: D:/data/repository

detection:
  # Empty means all Sheets. Names are matched case-insensitively.
  included_sheets: [Sheet1]
  column_exclusion:
    black_fill: true
    semantic_prefix: "#"
  preferred_main_sheets: [Sheet1, data]
  schema_sheet_names: [config, schema]
  relation_sheet_names: [rule, reference]
  max_header_scan_rows: 10
  primary_key_strategy: first_unique_column

Source discovery

sources accepts one or more spreadsheet roots. Discovery is non-recursive by default: only supported files directly under each configured root are included. Set recursive: true only when subfolders intentionally belong to the same dataset.

exclude_paths accepts absolute paths or paths relative to the source root. Excluded directory trees are pruned before discovery. The Web workbench applies the same source, Sheet, and exclusion rules to preview, diagnostics, parsing, indexing, and source fingerprints.

Supported ordinary formats are .xls, .xlsx, .xlsm, and .csv.

Semantic layouts

Semantic row numbers are 1-based, matching Excel. field_name is required when an explicit layout is selected. Additional row roles are retained as searchable column metadata with cell evidence.

Columns whose field_name cell is empty are discarded completely, including their data. When layout is omitted, automatic detection remains active. A detected layout must still be confirmed before it becomes authoritative.

An override targets a filename pattern and, optionally, one Sheet. Set ignore: true for a Sheet that is intentionally outside the data model.

Sheet and column scope

detection.included_sheets: [] means all Sheets. A non-empty list limits preview, diagnostics, parsing, indexing, and source fingerprints to those case-insensitive names.

detection.column_exclusion provides two project-wide ways to exclude complete columns:

  • black_fill: true excludes a column when any configured semantic-row cell has an exact solid black fill (#000000). This applies to Excel formats.
  • semantic_prefix: "#" excludes a column when a semantic-row value begins with that prefix. This applies to both Excel and CSV.

Set black_fill: false or semantic_prefix: "" to disable either marker.

Formal names and localization

Formal names are a separate localization layer, not another ordinary data source. A localization workbook binds to exactly one root workbook with the same filename stem and joins localized records to the root table's primary key.

name_candidates are checked in order. Use a per-file override when localization and root IDs or the display-name field are project-specific. Ambiguous fields, duplicate IDs, unbound workbooks, and unmatched records are reported instead of silently resolved.

Query results retain the root record and add formal_name, formal_text, locale, and exact cell evidence. When present, formal_name is the authoritative output name.

Watch mode

The Web service starts the configured watcher after an index exists. table-rag watch provides the same behavior without the Web UI.

Saves are debounced, files must remain stable before parsing, and all writers share a lock beside the DuckDB file. Changed root workbooks and their corresponding localization are refreshed together. Transient read failures retain the last verified catalog and are retried. Startup reconciles changes that happened while the watcher was offline.

Branch-isolated catalogs

When branches.enabled is true, builds read the checked-out Git branch and require {branch} in the database path. A build updates only the current branch catalog. Read-only commands can select an existing catalog with --branch main; MCP fixes that selection at startup.

Branch names containing / are converted to collision-resistant filesystem names.

Field-scoped project knowledge

The project YAML can point to a separate reviewed knowledge file:

knowledge: my-project.knowledge.yaml
version: 1
fields:
  - table: orders
    field: product_id
    meaning:
      en: Product identifier referenced by an order
    value_shape:
      kind: scalar_id
    relations:
      - target_table: products
        target_field: id
    evidence:
      source: human_verified
    status: verified

New Web entries are saved as candidate. Confirmation validates the source field and each target field against the current branch catalog, deprecates an older verified revision for the same field, and changes the new revision to verified.

Only verified knowledge enters normal semantic search and relation traversal. Candidate and deprecated entries remain available through explicit status-filtered knowledge search.

For compound values, use value_shape.kind: tuple_list, declare named component indexes, and set source_component plus optional when values on relations. This is a bounded declarative parser; knowledge files never execute arbitrary Python expressions.