主题
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 校验项
- Schema — 每个声明带
cite,kind合法 - Tool 解析 —
tool_call_id在本次 turn 的 trace 中真实存在 - 值匹配 —
value等于 Tool 实际返回的值 - Competence 解析 —
competence_id已注册 - Freshness — 数值类(tool-sourced)的
as_of在配置的 staleness budget 内- 默认值待 01 数据层 提供
失败处理
- 第 1 次失败:把 Verifier 反馈注入下一轮 prompt,让 Agent 重试
- 第 2 次仍失败:直接报告给用户。不静默 fallback 到未校验输出。
为什么不让另一个 LLM 当 Critic
投研里最多的失败是编造数字,不是错误推理。编造数字 90% 都能被确定性代码抓到(schema、resolution、value match)。LLM Critic 贵、慢、还会有它自己的 hallucination。先用代码兜住基本盘,需要时再加 LLM Critic。