系列:Agent-10-00 索引 · 下一篇:02 Tool Calling
1. 行业常见问题
| 现象 | 业务影响 |
|---|---|
| 回答结构每次不同 | 下游无法解析、无法渲染 UI |
| 口吻随意、越权建议 | 合规风险(医疗/金融/法务) |
| 输出夹杂 Markdown 废话 | 自动化流水线需要复杂正则清洗 |
| 「看起来对」但字段缺失 | 批量任务 silent failure |
典型场景:调研报告要固定四段、工单要 JSON、实验参数要可校验的 schema。
2. 该技术如何解决
通过 消息角色(system / user / assistant)约束任务边界,再用 结构化输出 把生成空间限制在可解析的类型上。
- System Prompt:角色、禁止项、输出格式说明
- Structured Output:JSON Schema / Pydantic 模型,让模型返回可校验对象
- 低温度(temperature):减少格式漂移
段末注释:temperature 控制采样随机性;结构化任务通常取 0–0.3。
3. 核心原理
3.1 Chat Completions 消息栈
1 | system: 你是…必须按以下 JSON 输出… |
模型并不「记住程序状态」;每次请求携带的 messages 即上下文。
3.2 结构化输出的两种主流路径
| 路径 | 机制 |
|---|---|
| JSON mode / response_format | API 层约束输出为 JSON |
| Pydantic + parse | 先自然语言生成,再解析校验(或 native structured output) |
校验失败应 重试或报错,不能把脏 JSON 当成功。
4. 典型实现与代码示例
本仓库 Planner 使用 LangChain structured output,而非手写 JSON 解析。
4.1 Pydantic 契约
1 | # agent/uni/contracts/research_plan.py |
4.2 LangChain:with_structured_output
1 | # agent/planner/llm.py(节选) |
要点:
with_structured_output(ResearchPlan)替代response_format+ 手工json.loads- 读取上游 artifact(
transcripts.json、literature_manifest.json)作为 user 上下文 - LLM 失败时 规则回退
build_research_plan(),保证流水线可跑
4.3 工程验收
1 | # 规则版(无 API Key) |
5. 替代方案与优缺点
| 方案 | 优点 | 缺点 |
|---|---|---|
| 纯 Prompt 要求 Markdown 标题 | 人类可读 | 解析脆弱、多语言/多模型不稳定 |
| JSON mode + Pydantic | 可校验、可测试 | 需处理偶发 schema 违规 |
| Function/Tool Calling 返回结构化参数 | 与 Agent 循环统一 | 过度用于「无工具」场景时复杂 |
| 后处理 LLM「再整理一遍」 | 救场脏输出 | 成本翻倍、仍可能幻觉 |
| 模板填空(slot filling) | 极稳 | 灵活性差,适合字段固定表单 |
6. 自检题
- 为什么结构化任务通常降低 temperature?
- system 与 user 分工应如何划分「角色」与「任务数据」?
- JSON 解析失败时,生产系统应重试、降级还是直接失败?各适用什么场景?