LangChain ReAct Agent 嵌套 JSON 报错?args_schema=None 解决 Field required

【导航台账】制造业数据与AI践行者老蒋的技术博客全系列文章汇总(持续更新)

📌 文章摘要

LangChain ReAct Agent 调用多参数工具时,反复报 Field required 错误,排查发现完整 JSON 被嵌套塞进第一个参数字段。本文深入剖析 ReAct Agent 参数打包机制,提供 args_schema=None 绕过 Pydantic 自动校验、手动解析参数的完整落地方案,彻底终结嵌套 JSON 问题。

问题现象

兄弟们,我在Case03多工具协同Agent的开发中,被同一个问题折磨了好几天。

明明代码逻辑没问题,工具定义也写清楚了,但Agent一调用 generate_work_order 就报错:

bash 复制代码
❌ 错误: 3 validation errors for WorkOrderInput
fault_code
  Field required [type=missing, input_value={'line_name': '{"line_nam...gned_shift": "白班"}'}, input_type=dict]
solution
  Field required [type=missing, input_value={'line_name': '{"line_nam...gned_shift": "白班"}'}, input_type=dict]
spare_parts_status
  Field required [type=missing, input_value={'line_name': '{"line_nam...gned_shift": "白班"}'}, input_type=dict]

我当时的第一反应是:这不科学啊......

Agent生成的 Action Input 明明包含了所有参数:

bash 复制代码
{
  "line_name": "交互屏组装A线",
  "fault_code": "E401",
  "solution": "重启工控机并检查USB连接线",
  "spare_parts_status": "充足",
  "assigned_shift": "白班"
}

但Pydantic告诉我 fault_codesolutionspare_parts_status 这三个字段缺失。

仔细一看报错信息里的 input_value ------ 整个JSON被嵌套( ReAct Agent 嵌套 JSON**)塞进了 line_name 字段**:

bash 复制代码
input_value={'line_name': '{"line_name": "交互屏组装A线", "fault_code": "E401", ...}'}

根因分析

说实话,Field required 报错原因让我翻来覆去查了好几天。不是代码写错了,而是 LangChain ReAct Agent 的"出厂设置"就是这样的

第一层:ReAct Agent 不支持多参数工具

LangChain 官方文档里其实藏着一句话:create_react_agent 创建的工具不支持多参数-。

ReAct Agent 在处理工具调用时,会把所有参数打包成一个JSON字符串 ,然后整个塞进第一个字段里-。这就是为什么 line_name 收到的不是字符串,而是一个完整的JSON对象。

第二层:Pydantic在校验之前就已经"阵亡"了

BaseToolargs_schema_run 方法执行之前就会对输入参数进行校验-。

当Agent把嵌套JSON传给工具时,Pydantic看到的是:

python 复制代码
{"line_name": '{"line_name": "交互屏组装A线", "fault_code": "E401", ...}'}

它只认识 line_name 这个字段,其他字段全被埋在了字符串内部,根本解析不到。于是报错 Field required

你在 _run 里面加再多的解析逻辑,都没用。因为Pydantic在校验阶段就把路堵死了。

第三层:这是一个社区公认的"老大难"问题

这个问题在LangChain社区里被反复讨论-。

有开发者尝试过把所有字段都设为 Optional,然后在 _run 里手动处理-。也有人尝试用正则表达式自己解析。但这些方案要么不彻底,要么治标不治本。

解决方案

别慌,一招搞定它。

核心思路:绕过Pydantic自动校验

args_schema 设为 None,让 _run 方法自己说了算。

python 复制代码
class GenerateWorkOrderTool(BaseTool):
    name: str = "generate_work_order"
    description: str = "生成智联工坊标准维修工单..."
    args_schema: Optional[Type[BaseModel]] = None  # 👈 关键:关闭自动校验

然后修改 _run 方法,手动解析Agent传入的所有参数:

python 复制代码
def _run(self, *args, **kwargs) -> str:
    # 收集所有可能的输入
    raw_input = None
    if args and len(args) > 0:
        raw_input = args[0]
    if not raw_input:
        raw_input = kwargs.get("line_name") or kwargs.get("input")
    
    # 解析嵌套JSON
    if isinstance(raw_input, str) and raw_input.strip().startswith('{'):
        try:
            import json, re
            cleaned = re.sub(r'^```json\s*', '', raw_input.strip())
            cleaned = re.sub(r'\s*```$', '', cleaned)
            data = json.loads(cleaned)
            # 从解析结果中提取所有字段
            line_name = data.get("line_name")
            fault_code = data.get("fault_code")
            solution = data.get("solution")
            spare_parts_status = data.get("spare_parts_status")
            assigned_shift = data.get("assigned_shift", "待分配")
        except json.JSONDecodeError:
            pass
    # 兜底默认值
    fault_code = fault_code or "未知"
    solution = solution or "请参考维修手册"
    # ... 生成工单逻辑

为什么这样做有效?

对比项 Pydantic校验(args_schema定义) 手动解析(args_schema=None
校验时机 _run执行之前 _run执行之中
嵌套JSON处理 ❌ 直接报错 ✅ 可以解析后再提取
容错能力 低(严格匹配字段) 高(可以处理各种格式)
灵活性 低(字段必须一一对应) 高(可以从各种来源提取参数)

验证结果

修改之后,Agent的调用不再报错:

python 复制代码
Action: generate_work_order
Action Input: {"line_name": "交互屏组装A线", "fault_code": "E401", ...}

Observation: {
  "order_id": "WO-20260804-4164",
  "status": "待执行",
  "line": "交互屏组装A线",
  "fault_code": "E401",
  ...
}

工单成功生成,嵌套JSON噩梦终于终结了。

经验总结

怕你忘了,我再啰嗦一遍😀😀😀create_react_agent 不支持多参数工具,它会把所有参数打包成嵌套JSON塞进第一个字段。与其跟Pydantic死磕,不如直接绕过它。

落到具体操作上就是三条:

  1. args_schema=None 是解药,不是毒药 。官方文档推荐用Pydantic做参数校验,但在ReAct Agent的多参数场景下,这套机制反而成了阻碍。关闭自动校验,在 _run 里手动解析,是更健壮的做法。

  2. 手动解析要足够"皮实"。Agent可能传入纯净JSON、带Markdown代码块的JSON、甚至夹杂多余文字的JSON。你的解析逻辑要能覆盖这些情况,而不是只处理理想格式。

  3. 兜底默认值很重要 。即使解析失败,也要让工具有合理的默认值,而不是直接崩溃。工具应该"尽量工作",而不是"完美地失败"。

说白了就是一句话:工具是给Agent用的,不是给Pydantic看的。让工具适配Agent的行为,比让Agent适配工具的校验规则更靠谱。

bash 复制代码
【注意】本方案针对 ReAct Agent 多参数工具嵌套 JSON 场景,并非所有场景都要关闭 Pydantic 校验。

单参数工具:仍推荐使用 args_schema 做类型校验,类型安全更有保障;
支持结构化输出的 Agent(如 OpenAI Functions Agent):原生支持多参数调用,无需此处理;
手动解析时必须增加异常捕获与兜底逻辑,避免非法输入导致工具崩溃。

系列导航

本文问题源自《智联工坊实战:多工具协同Agent》实战过程,完整源码及深度教程见该文:链接

💡 建议收藏 :下次遇到 Field required 报错时,可以先检查是否是嵌套JSON导致的问题。

互动与交流

你在使用LangChain ReAct Agent时,有没有遇到过类似的"嵌套JSON"问题?你是怎么解决的?欢迎评论区吐槽,咱们互相交流一下------说实话,这个问题我前前后后折腾了好几天才搞明白。

关于作者

制造业数据与AI践行者老蒋,23年IT老兵。聚焦制造业数据架构与AI融合落地。全流程实战,全源码开源。

相关推荐
gb42152875 小时前
python中unstructured库和langchain-unstructured库在解析pdf文件的时候的区别?
python·langchain·pdf
Tbisnic1 天前
LangChain的 六大核心组件与 RAG 知识库构建
人工智能·python·ai·langchain·rag·langgraph
gb42152871 天前
python中pypdf库和langchain-unstructured库在解析pdf文件的时候的区别?
python·langchain·pdf
badhope1 天前
用RAG做了个智能客服,上线第一天就被用户骂了——我的7天实战复盘
人工智能·langchain
Wang's Blog1 天前
AI Agent白手起家44: LangChain 文档切分实战 — 长度、文本架构与语义切片
人工智能·langchain
jaboo121 天前
postgresql从入门到精通
数据库·postgresql·langchain
闲猫2 天前
LangChain / Integrations / Integrations by component / Tool
java·数据库·langchain
程序员AI工坊2 天前
Agent 开发:ReAct 循环与工具调用实战——从单次调用到自主 Agent
人工智能·后端·python·langchain·agent·react
Wang's Blog2 天前
AI Agent白手起家41: LangChain 链的高级应用:函数、记忆、路由与容错
langchain