Agent 工具调用与结构化输出
2026/9/4大约 3 分钟
Agent 工具调用与结构化输出
为什么不能只拿一段文本
模型输出一段自然语言时,人可以理解,程序却很难稳定判断它是否包含候选对象、分类信息和后续动作。平台使用 Pydantic 定义结构化结果模型,把 Agent 输出变成后端可以继续处理的契约。
工具调用的完整链路
系统 Prompt + 工具 schema
│
▼
模型选择工具
│
▼
ToolCallController 校验
│
├─ 通过:执行工具并记录结果
└─ 拒绝:返回可解释的错误
│
▼
工具结果回到对话上下文
│
▼
模型继续推理
│
▼
Pydantic 校验最终输出工具 schema 至少要说明名称、用途、参数类型、必填字段和使用时机。描述太笼统时,模型可能不调用正确工具,或者在不需要时反复调用。工具返回值也不能只写 Error,应区分网络超时、参数错误、权限不足和资源不存在,并告诉模型下一步能否重试。
结构化输出的防线
Agent 运行器在运行前解析当前模型支持的输出 schema,启用 structured outputs,并在响应回来后按以下顺序解析:
- 已经是结果模型实例,直接返回。
- 是 JSON 字符串,使用
model_validate_json。 - 是字典,使用
model_validate。 - 其他类型尝试转成 JSON;仍失败则抛出明确异常。
这条路径拒绝“看起来像 JSON 但字段不完整”的结果,避免错误继续传到后续整理阶段。对外输出的字段还要区分主要候选、噪声候选、被忽略对象和工具返回的详情,不能把中间候选误当成最终结果。
超时、重试和模型降级
Agent 同时设置单次运行超时、工具调用上限、模型重试次数和 fallback models。可以重试的通常是网络抖动、限流和暂时不可用;参数校验失败和权限不足应尽快返回。模型降级不是简单换一个模型,而是要保证备用模型仍支持相同输入和输出 schema,否则会把“模型不可用”变成“解析失败”。
评分与完整分析 Agent 的契约
评分 Agent 只负责六维评分和 hard cap,程序计算最终分数;模型不能反向修改总分和等级。调度器使用评分结果与流程快照决定是否触发完整分析 Agent,触发结果记录成功、等待、跳过或失败状态。将“模型推理”和“触发决策”分离后,规则更容易测试,成本也更可控。
我的实践要点
- 先设计输入输出,再写 Prompt 和工具。
- 工具结果要让模型知道“发生了什么”和“还能做什么”。
- 每个失败分支都要有状态、原因和可观测字段。
- 对结构化结果做严格校验,宁可显式失败,也不让脏数据进入下游。
小结
工具调用解决 Agent 如何获得外部信息,结构化输出解决后端如何可靠消费模型结果。两者都必须通过 schema、超时、错误分类和验证闭环,才能从 Demo 走向可维护服务。
