Gold tables and context documents
Index, definitions and answer protocol
Answer with number, cut and load date
Slack, WhatsApp or CRM chat
What it solves
- The same question gets the same number, for anyone and in any channel.
- The agent says which metric it used, for which period and when the data was last updated.
- People without access to a piece of data do not get it, and the agent says where to look.
Business questions it answers
Ask your agent these questions once the case is live.
What you need
- The main metrics in gold tables, with closed rules
- Context documents with definitions, routing by topic and an answer protocol
- The channel (Slack, WhatsApp, CRM chat) connected to an agent with the Nekt MCP
What you get
- Semantic tables per purpose, with columns annotated for the AI
- An entry index that tells which document to read for each topic
- Tokens scoped by audience: leadership, manager, team
- A question and answer log and a test set to measure the agent
Where to activate
The team asks in the channel it already uses and gets the number with the cut and the load date.
Short executive questions, with a token restricted to leadership tables.
Channel questions and answers become a table to measure accuracy and time and fix documents.
The gold tables usually exist. The effort is writing definitions, the protocol and test questions, and reviewing answers in the first weeks. The detailed view has the business rules, the pitfalls and the acceptance test. Or send everything straight to your agent with the Nekt MCP.
The agent gets access to every table and picks on its own. It reads a test table with a name close to the official one, averages a column that is already an average, treats a day that has not loaded yet as zero and explains the drop with a cause that exists nowhere. Two people ask the same question and get different numbers, and nobody can audit where each one came from.
How it is usually done, and the rule
Each row is a mistake that already happened in practice.
Create consumption tables per purpose (daily sales by branch, funnel by month, revenue by customer), with the grain stated in one sentence in the description. When the rule is complex, the table already carries the result in a column (for example, a boolean that says whether the row counts toward the metric) and the document tells the agent to use that column instead of rewriting the formula. Scratch tables (prefixes debug_, test_, tmp_, suffixes _log, _dryrun, names with dates) are never a source of numbers.
Start the column description with a tag: @pk (grain key), @fk (foreign key), @measure additive (sums across any dimension), @measure non_additive (average ticket, percentage, rate), @grain. Then state the origin, the rule and the pitfall. Every monetary measure says whether it is gross or net. Document the table, not only the transformation: whoever looks for the data finds the table.
A root document lists every document with one line saying when to read it. The agent reads every document that matches the request; chained metrics are read together (NRR also reads MRR and churn). If no document covers the request, the agent says so instead of improvising. In semantic search, ask for the concept and the metric: a proper name surrounded by weak words makes the search return zero documents. The name is for filtering in SQL.
Fixed order: fetch context with the original question, read the documents, check the last load, generate and run the query, check the order of magnitude against a reference number in the document. The agent never answers a number without running the query and never refuses for lack of data before reading the table structure. Null is absence, not zero. Metrics flagged 'to be validated' are not inferred.
The answer names the metric (net or gross), the period with start and end dates and the date and time of the last load. The current day is partial: compare only closed days. An open month does not count as actuals; use the table's closed-month flag when there is one.
ERP date fields stored as midnight UTC are already the business day. The agent computes today and yesterday in local time and compares directly, without converting the field. The rule is written in the column description and in the protocol.
The agent breaks the change down (volume versus ticket, which branch explains the difference in reais), but does not explain why it fell or recommend action without data to back it. A comparison base of zero or very small becomes 'low base', with the change in reais. Rates change in percentage points. Percentages and averages are not summed across rows: recompute the ratio from the totals.
Each audience has its own MCP token with table scope: leadership reads the whole network, a manager reads the view of their own branch. A catalog folder is organization, not security. Data that identifies a person (operator, contact, student) stays out of broad views. An access error is the scope working: the agent says where the answer lives, without asking for new permissions.
Rules are stable; counts (active customers, number of tables, totals) are a snapshot of a date and age within days. If the document disagrees with the query, the query wins. Every document carries an owner, a status (validated or not) and the last review date. When the agent uses an unvalidated rule, it says so.
Keep a set of real questions with the expected answer and run it on every document change. Store the channel history pairing each question with the final answer. Intermediate messages ('analyzing your question') do not count as an answer or toward response time.
The documents the agent reads
Each one has a role. On conflict, the domain document wins on calculation and the protocol wins on form.
Definitions
Pitfalls that already happened
The agent returned a store's gross sales as net and was off by six digits on a single day.
State gross or net on every monetary column and set the default in the protocol.
The agent converted the time zone of a field that was already the business day and returned zero sales on a high-sales day.
Write in the column description that the date takes no time zone.
The agent blamed a drop on team productivity and recommended action, in a base that only had sales, cancellations and sign-ups.
Protocol: facts, not causes; close with what the base cannot answer.
With no index, the agent aggregated an investigation table whose name was close to the official one.
List the consumption tables in the index and mark scratch prefixes as forbidden.
The branch views were created with a manual trigger and went more than a week without refreshing while the source was up to date.
Event trigger and load date in every answer.
Questions made of a proper name and weak words returned no documents, and the agent answered with no rules.
Search by concept and metric; use the name only to filter in SQL.
Acceptance test
The case is done when every item passes.
- On a set of at least 30 real questions with expected answers, the agent gets the number right on every official-metric question and says the data does not exist on the ones the base does not cover.
- The same question asked by two people, in two channels, returns the same number and the same load date.
- With a manager's token, querying another branch's view returns an access error.
- Every numeric answer in the log carries metric, period and last load date.
- Net sales for a closed day returned by the agent match the official ERP report for the same day.
Agent package
Paste into Claude, ChatGPT or any client with the Nekt MCP connected.
Data agent protocol - Before any SQL, fetch context with the original question and read the documents listed in the index <index name>. - Use only the listed consumption tables: <list>. Never use tables with prefix debug_, test_, tmp_ or suffix _log, _dryrun. - Do not answer a number without running the query. Do not refuse for lack of data before reading the table structure. - Every numeric answer carries the metric, the period with start and end dates and the date and time of the last load. - 'How much did we sell' = <default metric, e.g. net sales>. Gross only when asked. - Business dates take no time zone conversion. Today and yesterday in America/Sao_Paulo. - The current day is partial: compare only closed days. Count as actuals only months with <closed-month flag> true. - Percentages, averages and ticket are not summed across rows: recompute from the totals. - Comparison base of zero, negative or less than a quarter of the current value: write 'low base' and show the change in reais. - State the fact, never the cause. Do not recommend action. Close with what the base cannot answer. - Null is absence, not zero. Metrics flagged 'to be validated' are not inferred. - List people only when asked, up to 50 rows, without phone, email or ID number. - Access error: say it is outside your scope and where the answer lives. - If a number written in a document disagrees with the query, the query wins. Client exceptions: - <client>: 'lead' with no qualifier = <definition>. - <client>: managers read only <branch view>; leadership reads <network view>. - <client>: reference number for <closed month>: <metric> = <value>.
Build the "Data agent on Slack or WhatsApp" case in my Nekt workspace following the rules at https://academy.nekt.com/en/casos/agente-slack.md. 1) Find the source tables and confirm the columns the rules use. 2) Create a transformation at the stated grain applying every rule. 3) Run the acceptance test and show me the result of each item. 4) Create the case's context document in the workspace, leaving my clients' exceptions open for me to fill in.
Variations
At agencies and consultancies, a routing document per client and a precedence order between global rule and exception.
The same protocol, triggered on a schedule: it reads the scoreboard and only speaks when something goes out of range.
With the MCP live tools, the agent also performs actions in the tools, such as settling an installment in the ERP or adjusting a campaign, always with confirmation.