Skip to main content
On this page

Model Fields

Formats, descriptions and AI context

Tell people and agents what each field means and how to show it, right beside its definition.

Audience
Data teams
Prerequisites
  • A model you can edit

Metadata is what makes a model usable without you in the room. A description tells a person what a field is. AI context tells an agent how to use it, and what not to do. A format tells every table and chart how to show it. In Kater all three sit beside the field’s definition, so they change together, and the Shared models editor lets you fill them in like a spreadsheet.

Where context lives

An agent reads context from several places, from the whole organisation down to one field. Put each fact at the narrowest level where it is true.

WhereWhat it holdsWho writes it
rules.md at the content rootYour organisation’s own rules for every request. Keep it short. See MCP server and tools.Admins
about.md, at the root and in each Personal folderFacts about the company, and about each person.Admins, and each person
connection_context.mdWhat to know about one connection and its data.Data team
Model frontmatterlabel, description, ai_context, business_questions, tagsData team
Comments above a field@description, @ai_context, @format, @business_questions, @tags, classificationData team
Comments above a join@label, @description, @ai_contextData team
A filter call and the comments above itlabel='…', @description, @ai_contextWorkspace owners
A parameter’s entrylabel, description, ai_contextWorkspace owners

Edit metadata in the editor

Open the model in Shared models. Every edit writes the directive or frontmatter key for you, saves itself, and undoes exactly.

Fields, many at once

Select Fields above the grid. The Fields sheet has a row per field, with its Description, Format, Values and AI context. Click a cell to edit it, or paste a whole column at once: it saves as one change. A field whose label is still its SQL name says No label.

The Fields sheet of Marketing Sessions: 60 fields, 21 with no label, Write labels with Ask, and the columns Field, Name, Source, Description and Format, with a description being typed in place
Descriptions edited in the Fields sheet.

Write labels or descriptions with Ask

The sheet’s header counts what is missing, such as “60 fields, 21 with no label” or “42 fields, none described”. Write labels with Ask or Write descriptions with Ask opens Ask with a prompt for your agent that lists those fields. Your agent writes them through the same operations, and you review them in the sheet.

One field

Click a field to open its panel: Label, Description, AI context, Format, Values, Tags and Business questions. The field menu also has Format and Values. See Fields.

The model

Select Details on the toolbar. The panel holds the model’s Label, Description and AI context, its Business questions and Tags, each with Add, and Always filtered: the filters with fixed values that apply to every reader. Show as YAML shows the frontmatter as the file has it.

The Model details panel for Marketing Sessions, verified: Label, Description and AI context as the file has them, Business questions 4 with Add, Tags with Add, and Show as YAML at the bottom
Model details.

A join

Click a join’s chip in the diagram. Its panel ends with About this join: Label, Description and AI context. See Relationships and joins.

Field directives

modeling/kater_objects/semantic_models/marts/AD_REPORTING.sql
-- @description Sum of platform-reported attributed conversion value using upstream definitions and attribution.
-- @format currency(union__currency, 2)
-- @ai_context Uses each advertising platform's reported conversion value and attribution. Values are combined without cross-platform deduplication or currency conversion.
MEASURE('sum__conversions_value', SUM(base.conversions_value), NOT_ADDITIVE_ACROSS(union__currency)) AS "Conversion Value"
modeling/kater_objects/semantic_models/marts/FCT_VELIR_GA4__CLIENT_KEYS.sql
-- @description Earliest event_date_dt for the row. It is a dimension, not a measure to aggregate.
-- @business_questions "When did each client first show up?" "How many new clients arrived per day?"
-- @tags "acquisition"
DIMENSION('first_seen_start_date', sessions.session_start_date) AS "First Seen Start Date",
DirectiveWhat it doesExample
AS "Label"The display label. A field has no @label directive.AS "Spend"
-- @descriptionOne or two sentences for people.-- @description Order amount before discounts.
-- @ai_contextGuidance for agents: caveats, what not to combine.-- @ai_context Values are combined without currency conversion.
-- @formatHow values show. From a closed list, below.-- @format percent(1)
-- @categorical, -- @continuousA category, or a quantity or point in time. Numeric IDs can be categorical. The editor calls this Values.-- @categorical
-- @business_questionsQuestions the field answers, each in double quotes."When did each client first show up?"
-- @tagsFree tags, each in double quotes.-- @tags "acquisition"

Write directives on the lines directly above the field. A trailing /* @format currency(currency, 2) */ after the field works too.

Formats

A format changes how a value shows, and nothing else: never the value, its grouping or its definition. Result tables, charts and definition cards use it.

FormatShows
number(2)Two decimal places, with thousands separators. Takes 0 to 20 places.
percent(1)A fraction as a percentage: 0.25 shows as 25.0%.
big(1)Large numbers short: 1,200,000 shows as 1.2M.
idAn identifier: a whole number with no separators. Explore reads a field formatted id as a key.
plainA number as written, such as a year: 2026, not 2,026.
currency('USD', 2)One currency for every row.
currency(currency, 2)Each row’s own currency, read from a dimension the same SELECT declares or passes through. Pair it with NOT_ADDITIVE_ACROSS on that dimension.

Operations write a format when they add a field: percent(1) for a share of total or a percent change, number(0) for a count or a rank, plain for a date part such as a year, and the source field’s format for a sum or a running total. A pass-through or an EVAL of a field keeps its format. In the editor, a field with no format of its own says Automatic.

Model metadata

modeling/kater_objects/semantic_models/marketing/MARKETING_SESSIONS.sql
---
name: marketing_sessions
model_type: semantic
label: Marketing Sessions
description: One row per GA4 session with acquisition, landing, device, geography, lifecycle identity, first-seen cohort, and matched paid-media context, for lifecycle marketing questions.
ai_context: Select from this model alone for lifecycle marketing questions; it joins the session dimension, the lifecycle identity, and daily paid media on every query. Grain is one row per session, client key, and stream, so every count is a session count unless the field says identity or lifetime. ...
business_questions:
- Which channels and campaigns bring sessions that engage, and how does that change month to month?
- What does a session cost per campaign, and which paid campaigns send traffic that does not engage?
tags:
topic:
- Marketing/Sessions
team:
- marketing/lifecycle
- sales
source_data:
- ga4
---
  • Model tags are a map. Each key holds a list. Suggested keys are team, source_data, topic and curated. A slash path such as marketing/lifecycle sits under marketing when you select by tag, as in kater test --select tag:team=marketing.
  • Field tags are a plain list. -- @tags "acquisition" has no keys.
  • Tags never grant anything. They do not set ownership or verification.

How metadata carries through

Seven keys carry through a direct reference to a field: label, description, AI context, business questions, tags, classification and format. A pass-through, a plain EVAL, an alias or a cast keeps them. A directive in the reading model overrides one key at a time. A calculation over a field, such as EVAL(a) / EVAL(b), keeps only the metadata written on it.

Where to edit each kind

To changeIn the editorElsewhere
A field’s labelLabel in the field panel.The field.relabel operation.
A field’s formatFormat in the field panel, the field menu or the Fields sheet.The format.display operation.
A field’s classificationValues in the field panel, the field menu or the Fields sheet.The field.classify operation.
A field’s description or AI contextThe field panel or the Fields sheet, or Write descriptions with Ask.Write the comment in the SQL, or ask your agent.
A field’s tags or business questionsTags and Business questions in the field panel.Write the comment in the SQL, or ask your agent.
A model’s frontmatterDetails.Edit the file, or run kater source patch FILE --edits '[{"at": "description", "value": "…"}]'. Every other line stays as written.
A filter that always appliesAlways filtered in Details, Always filter in the field menu, or Edit › Add a filter that always applies.REQUIRED_FILTER in the SQL.
A join’s label, description or AI contextAbout this join in the join panel.The comments above the join.
A filter’s or parameter’s label and descriptionNot in a shared model.The update_filter and update_parameter edits. See Filters and parameters.

Write context that helps

  1. State the grain. “Daily ad grain within source_relation, platform, account, campaign, and ad group.” An agent then groups at the right level.
  2. Say what not to combine. “Other shared ad reports are overlapping rollups; do not add their totals to this model’s totals.”
  3. Put a caveat where it applies. A join’s matching gap goes in the AI context of that join, not in the model’s frontmatter.
  4. Write business questions as people ask them. Agents search them, and the Tests tab and kater test generate --from-questions turn them into tests.
  5. Format every number. A format stops a currency from showing as a bare decimal, and an ID from showing with separators.

Agents search labels, descriptions, tags and business questions through the MCP’s catalog search, so plain words here make fields easier to find.

Common errors

CodeCauseFix
invalid_formatA format outside the list, or a currency(dim, n) whose dimension the SELECT does not hold.Use a listed format, and select the currency dimension.
unsupported_field_metadataAn unknown directive, such as @label on a field.Use AS "Label" for the label.
malformed_field_metadataA list directive without double quotes, or arguments on @categorical.Write @tags "first" "second".
orphaned_field_metadataA directive with no field under it.Put it directly above a projection, with no blank line.
field_metadata_on_starA directive above SELECT *.Select the field by name, then describe it.
filter_label_directive@label above a filter.Write the label in the call: label='Region'.