Skip to content

Citation 协议

每一个 Agent 输出的声明(claim)都必须带 cite 字段。Verifier 在每次输出后做确定性校验,不带 cite 或 cite 不可解析的输出会被拒绝。

cite 的形态:Tagged Union

ts
type Cite =
  | {
      kind: "tool";
      source: string;          // e.g. "tushare"
      table?: string;          // e.g. "daily_basic"
      fetched_at: string;      // ISO 8601
      tool_call_id: string;    // must exist in trace
    }
  | {
      kind: "competence";
      competence_id: string;   // must be registered
    };

数值类声明

json
{
  "value": 42.5,
  "metric": "P/E",
  "code": "600519.SH",
  "as_of": "2026-04-27",
  "cite": {
    "kind": "tool",
    "source": "tushare",
    "table": "daily_basic",
    "fetched_at": "2026-04-28T08:14:22Z",
    "tool_call_id": "tc_abc123"
  }
}

知识类(定性)声明

json
{
  "claim": "A 股财年 12 月 31 日结束",
  "cite": {
    "kind": "competence",
    "competence_id": "comp.astock.fiscal_calendar.v1"
  }
}

Verifier 校验项

  1. Schema — 每个声明带 citekind 合法
  2. Tool 解析tool_call_id 在本次 turn 的 trace 中真实存在
  3. 值匹配value 等于 Tool 实际返回的值
  4. Competence 解析competence_id 已注册
  5. Freshness — 数值类(tool-sourced)的 as_of 在配置的 staleness budget 内

失败处理

  • 第 1 次失败:把 Verifier 反馈注入下一轮 prompt,让 Agent 重试
  • 第 2 次仍失败:直接报告给用户。不静默 fallback 到未校验输出。

为什么不让另一个 LLM 当 Critic

投研里最多的失败是编造数字,不是错误推理。编造数字 90% 都能被确定性代码抓到(schema、resolution、value match)。LLM Critic 贵、慢、还会有它自己的 hallucination。先用代码兜住基本盘,需要时再加 LLM Critic。

详见 ADR-0002: Citation 协议设计

Internal documentation