n8n 智能体已经给出答复,要把它交给表格或后续规则节点时,可以增加一个独立 Basic LLM Chain,附接 Structured Output Parser,按固定 JSON Schema 提取字段。最后再用 Code 核对字段类型和业务边界,避免把一段“看起来像 JSON”的文字直接当成业务记录。
本文适合已有 AI Agent 流程、需要稳定字段输出的读者。依据为 2026 年 10 月 1 日读取的 n8n 官方文档,没有在读者实例或模型账号上执行。工单及下面的预期对象都是虚构演示,不是客户案例或实测模型输出。

为何把解析放到独立 LLM Chain
Structured Output Parser 常见问题说明,直接解析 agents 的结构化输出通常不够可靠,建议用独立的 LLM Chain 接收智能体结果再解析。它还强调解析器用于最终输出,不是把工具之间的中间步骤统一改成 JSON。
按主线连接:AI Agent → Basic LLM Chain → Code。另为 Basic LLM Chain 附接可用的 Chat Model 和 Structured Output Parser。这个格式化步骤会增加一次模型调用,成本与耗时要单独计入;无需给格式化模型新增任何业务写入工具。
先用固定文本测试,不接真实工单
已有 AI Agent 的最终文本若在 output 字段,可以直接引用。为了独立验证解析流程,也可以先用 Manual Trigger → Code 模拟输入,Code 设 JavaScript、Run Once for All Items:
return [{json: {
output: "演示工单 A-100:用户表示未收到包裹并要求退款。系统签收信息还未核对,需交人工核实。"
}}];
在 Basic LLM Chain 中将 Prompt 设 Define below,在 Prompt (User Message) 切换 Expression,填写:
{{ '把下面的最终答复提取为工单字段。只使用文本中明确给出的信息,不推断订单状态,不批准退款。request_id 没有提供时填空字符串,并设 needs_human 为 true。category 只允许 billing、delivery、refund、unknown。无法判断时选 unknown。summary 写一句忠实摘要。文本如下:\n' + $json.output }}
执行前预览表达式,确认没有 undefined,且确实包含 A-100 的演示文本。若你的 Agent 用 text 字段输出,应按实际结果把表达式里的 output 改为 text。Basic LLM Chain 文档说明 Define below 与自动读取 chatInput 两种输入方式;这里明确使用前者。
手动定义 JSON Schema
开启 Basic LLM Chain 的 Require Specific Output Format,在出现的 Output Parser 连接点添加 Structured Output Parser。Schema Type 选择 Define using JSON Schema,粘贴:
{
"type": "object",
"properties": {
"request_id": {"type": "string"},
"category": {
"type": "string",
"enum": ["billing", "delivery", "refund", "unknown"]
},
"needs_human": {"type": "boolean"},
"summary": {"type": "string", "minLength": 1}
},
"required": ["request_id", "category", "needs_human", "summary"],
"additionalProperties": false
}
解析器文档指出,Generate from JSON Example 会采用字段名与类型、忽略示例值,并把所有字段当作必填。所以示例中写了 refund,不表示枚举自动限制为 refund;需要明确写 enum。本例不使用该节点不支持的 $ref。
本例 request_id 允许空字符串,是为了表示源文本缺少编号;不是让模型补一个编号。需要强制订单编号的后续操作,应由业务节点检查而不是由格式化模型猜测。
在 Code 节点做第二道检查
先执行 LLM Chain,查看它实际输出的 JSON。不同根节点或配置可能把解析对象放在 text、output 或直接作为字段;下面的 Code 兼容这些常见包装。如果收到字符串,它只尝试合法 JSON 解析,不剥除 Markdown 围栏来掩盖格式错误。
const allowed = ["billing", "delivery", "refund", "unknown"];
const keys = ["category", "needs_human", "request_id", "summary"];
return $input.all().map(item => {
let obj = item.json.text ?? item.json.output ?? item.json;
if (typeof obj === "string") {
try { obj = JSON.parse(obj); }
catch { throw new Error("格式化结果不是合法 JSON"); }
}
if (!obj || Array.isArray(obj) || typeof obj !== "object") {
throw new Error("格式化结果必须是对象");
}
if (JSON.stringify(Object.keys(obj).sort()) !== JSON.stringify(keys)) {
throw new Error("字段缺失或出现额外字段");
}
if (typeof obj.request_id !== "string"
|| !allowed.includes(obj.category)
|| typeof obj.needs_human !== "boolean"
|| typeof obj.summary !== "string"
|| !obj.summary.trim()) {
throw new Error("字段类型或取值不符合约定");
}
if (!obj.request_id.trim() && !obj.needs_human) {
throw new Error("缺少工单编号,必须进入人工核实");
}
return {json: obj};
});
验证通过只表示字段结构合格。它无法证明 summary 的事实正确,也不能证明 request_id 属于当前用户。因此,下游先展示给人工或进入只读核对流程,不根据 needs_human=false 自动退款。
用两个正常输入和一个反例验收
| 输入或反例 | 应检查的结果 | 失败判据 |
|---|---|---|
| 上面的 A-100 演示文本 | request_id=A-100,category=refund,needs_human=true;摘要保留签收信息待核对 | 擅自写“已批准退款”或“确定未送达” |
| “演示:用户想补开发票,没有提供工单编号。” | request_id 为空,category=billing,needs_human=true | 凭空补编号,或绕过人工核实 |
| 直接给末尾 Code 一份 needs_human 为字符串 “false” 的对象 | Code 抛出字段类型错误 | 把字符串当成布尔值继续处理 |
反例可以在独立测试副本中用 Code 固定返回错误对象,再连接验证 Code;不要把它混进实际 AI Agent 输出。这样分别检查“模型是否按事实提取”和“验证节点是否拦截错误类型”,避免只看一次成功就结束。
解析失败时不要无限加自动修复
先核对 Prompt 输入是否为空、Schema 是否有不支持的引用、响应是否被截断,再检查原始模型输出。根据官方建议保持“智能体结果 → 独立 Chain → 固定 Schema”的边界。若增加自动修复模型,应限制次数并重新核对事实,因为改出合法 JSON 不等于保留了原始事实。
动态 schema 如果使用多项输入,子节点还有首项取值的限制;本例使用静态 schema,并先以一条输入验收。需要批量处理时,为每条保留可信工单标识和对应结果,检查数量与关联,不让格式化模型承担归属判断。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31398.html