给 AI Agent 的查询接口
本章要解决的问题
Agent 应该通过哪些结构化工具查询代码图谱?
读者读完应获得什么
- 能给出最小工具 schema。
- 能返回带来源与置信度的结果。
- 能记录 query_trace。
本章不讲什么
- 不实现完整权限系统。
- 不让 Agent 直接任意写图谱。
设计原则
- 输入明确、输出结构化
- 结果带来源证据
- 标注不确定性
- 查询可追踪
- 写操作与查询分离
接口设计的第一层挣扎:什么算“一个工具”
第一次给 Agent 开口时,容易掉进两个极端:要么只给一个“问仓库”的万能工具,要么把每个小查询都做成工具。前者等于没有契约,Agent 只是换了个方式读文本;后者会让 Agent 在选择工具上耗尽上下文——Anthropic 在 context engineering 里也强调“人类工程师说不清该用哪个工具时,模型只会做得更差”。
折中判据是看下游消费:一个查询结果要被哪些字段消费,就独立成一个工具。related_tests 之所以独立于 find_callers,是因为验证报告和测试门禁只吃 tests 字段;architecture_rules 独立,是因为 CI 门禁和 Review 证据只吃 rules。工具边界跟着消费端走,而不是跟着实现难度走。
对这 5 个工具,它们恰好覆盖了 Agent 改码周期的完整闭环:
定位(find_symbol)→ 扩展(find_callers/callees)→ 影响(impact_analysis)→ 验证(related_tests)→ 约束(architecture_rules)
少一个,闭环就断一环:没有 related_tests,Agent 就不知道要跑什么测试;没有 architecture_rules,它只会“看起来合理地”跨模块。
工具清单
find_symbol
{
"name": "find_symbol",
"input": {"query": "DiscountPolicy.apply"},
"output": {
"matches": [
{
"id": "method:DiscountPolicy#apply",
"file": "src/main/java/com/minishop/pricing/DiscountPolicy.java",
"start_line": 4,
"end_line": 9
}
]
}
}
find_callers / find_callees
{
"name": "find_callers",
"input": {"symbol": "method:DiscountPolicy#apply", "depth": 3},
"output": {
"callers": [
{"id": "method:PricingService#calculateTotal", "confidence": "high"}
]
}
}
impact_analysis
输入 Diff 或 changed files,输出与影响面章节一致的结构。
related_tests
{
"input": {"symbol": "method:DiscountPolicy#apply"},
"output": {
"tests": [
"test:PricingServiceTest#shouldApplyVipDiscount",
"test:OrderServiceTest#shouldCreateVipOrderWithDiscount"
]
}
}
语义约定:返回直连该符号的 tests 边 ∪ 直连其调用方闭包的 tests 边。上例中 PricingServiceTest 直连 apply;OrderServiceTest 直连 calculateTotal(apply 的调用方),经闭包并入。金标 code-graph.json 中没有 OrderServiceTest -> apply 直连边,实现按闭包查询才能与影响面报告对齐;响应宜附命中层级,避免与“仅直连”语义混淆。
architecture_rules
{
"input": {"module": "pricing"},
"output": {
"rules": [
{
"id": "rule:pricing-no-payment",
"status": "pass"
}
]
}
}
查询轨迹
每次调用追加:
{
"tool": "find_callers",
"args": {"symbol": "method:DiscountPolicy#apply"},
"summary": "1 caller found",
"ts": "2026-07-22T12:00:00Z"
}
轨迹应进入上下文包与验证报告。
MCP / 本地 API 映射
可先实现 CLI:
cv-query find_symbol --q DiscountPolicy.apply
cv-query find_callers --id method:DiscountPolicy#apply
再包装为 MCP tools 或 HTTP JSON。
错误处理:失败必须结构化,否则会被当成“无影响”
接口最常见的隐性缺陷是:查询失败时返回一个空数组。Agent 收到 [] 后不会认为“查询出错了”,而会认为“没有相关信息”——这对 impact_analysis 是灾难性的:空影响面会被解读成“改动没有影响,可以合并”。
因此错误必须用结构区分于空结果:
空结果(真实) : ok=true, result=[]
失败(系统性) : ok=false, error=UNKNOWN_SYMBOL / INDEX_STALE / PERMISSION_DENIED
具体约定:
- 未知符号:返回
ok=false+suggestion(如“是否指DiscountPolicy.apply?”) - 低置信结果:
confidence=low且needs_confirmation=true - 图未索引:明确错误,绝不用幻觉补全
一句话判断:如果失败被当成空结果会误导决策,就必须区分。 这是查询接口与普通 REST API 的关键差别——因为消费方是会把“空”当结论的 Agent。
验收
- 对 mini-shop 图谱 5 类工具可用
- 结果可被 Agent 直接序列化进上下文包
- 轨迹完整
工具调用与轨迹
查询接口章要把“Agent 会用工具”落成 API 合同:请求什么、返回什么、失败什么样、轨迹如何记录。最危险的实现是失败时返回空影响面——模型会把它解释成“无影响”,从而大胆合并。
请把错误视为一等公民:未知 ID、图过期、权限不足都应结构化返回。成功响应则至少能支撑上下文包与验证报告的字段填充。契约稳定后,换 MCP 还是 HTTP 都只是传输层选择。
局限
- 接口不负责保证 Agent 一定正确使用结果。
- 无权限模型时不适合直接暴露到公网。
- 图不完整时,工具会诚实返回空/低置信,而不是编造。
小结
- 工具少而稳,胜过自由对话式乱读仓库。
- schema 与证据字段是接口核心。
- 查询轨迹是审计能力。
- 实现可从 CLI 平滑升级到 MCP。
- 失败必须与空结果结构化区分——Agent 会把“空”当结论。
安全与权限最小集
即便是教学系统,也建议预留:
- 只读查询默认开启
- 写操作(若有)与查询分离
- 返回体避免塞入密钥/本地绝对路径敏感信息
- 对超大结果强制 limit + pagination
示例:
{
"ok": false,
"error": "RESULT_TOO_LARGE",
"hint": "reduce depth or add filter"
}
Agent 面对该错误应收缩查询,而不是改去全文读取仓库绕过图谱。
契约测试
为防止接口漂移,实践项目应为每个工具准备契约样例:
- 输入 fixture
- 期望输出关键字段
- 在
mini-shop图谱上的金标结果
例如 find_callers(DiscountPolicy.apply) 的金标应包含 PricingService.calculateTotal。
工具响应示例
impact_analysis 响应应可直接渲染:
{
"tool": "impact_analysis",
"input": {"changed": ["method:DiscountPolicy#apply"]},
"result": {
"paths": [["method:DiscountPolicy#apply", "method:PricingService#calculateTotal", "method:OrderService#createOrder", "method:OrderController#create"]],
"related_tests": ["test:PricingServiceTest#shouldApplyVipDiscount"],
"risk": "medium"
},
"trace_id": "q-17"
}
错误响应也要结构化(未知 ID、图过期、权限不足),避免 Agent 把失败当成空影响面。
关键要点复盘
围绕「给 AI Agent 的查询接口」,读者离开本章前应能做到:
- 实现核心工具响应 JSON
- 返回 trace_id
- 结构化错误(未知 ID/图过期)
- 与上下文包字段对齐
- 衔接到验证报告
若任一做不到,请先复习本章例子与练习,再继续向后读。
练习
- 为
find_callers写 JSON schema(输入/输出)。 - 设计未知符号与低置信结果的错误返回。
- 记录 PR-42 的完整 query_trace(至少 4 步)。
常见问题:查询接口
REST 还是 MCP?
都能;关键是工具契约稳定与可审计轨迹。
图过期如何处理?
返回结构化错误并提示重建索引。
本章导航
- 上一章:构建可视化界面
- 下一章:AI 修改后的验证报告
- 相关章:代码图谱:节点、边与属性;Agent 上下文工程
延伸阅读与参考资料
- Model Context Protocol。资料卡:
../docs/research-cards/rc-mcp.md - JSON Schema
- LSP。资料卡:
../docs/research-cards/rc-lsp.md - OpenAPI 参考:若走 HTTP API 的契约思路
- GitHub Copilot tool/platform docs
- 样例:
agent-context-pack.json