LangChain 工具调用异常:arg1 参数错误的成因与解决方案

9次阅读

LangChain 工具调用异常:arg1 参数错误的成因与解决方案

langchain 代理在调用自定义工具时意外传入 `arg1` 参数,导致 `typeerror`,根本原因是工具签名未被正确识别——使用 `basetool` 子类时未声明 `args_schema`,而 langchain v0.1+ 默认采用 pydantic 模型解析参数,需显式定义输入结构。

langchain(尤其是 v0.1.x 及以上版本)中,当 Agent 执行工具调用时,它不再简单地将字典解包为位置参数,而是基于工具的输入 schema 进行结构化解析。若你继承 BaseTool 但未定义 args_schema,LangChain 会 fallback 到一个默认行为:将传入的单个参数字典(如 {‘arg1’: ‘…’})强行映射为名为 arg1 的关键字参数,从而引发 _run() 方法接收未声明参数的错误。

✅ 正确做法:为 BaseTool 显式声明 args_schema

你需要使用 Pydantic BaseModel 定义输入结构,并将其赋值给 args_schema 类属性:

from langchain.tools import BaseTool from pydantic import BaseModel, Field  class SQLFilterInput(BaseModel):     query_input: str = Field(..., description="用户自然语言查询,例如 '2023年8月计算机设备的平均温度'")  class SQLFilterTool(BaseTool):     name = "filter_user_query"     description = "根据用户自然语言问题生成结构化SQL过滤条件(用于后端数据筛选)"     args_schema: type[BaseModel] = SQLFilterInput  # ← 关键!必须显式声明      def _run(self, query_input: str) -> str:         return sql_filter_vanna(query_input)      async def _arun(self, query_input: str) -> str:         # 注意:_arun 应为 async def,且返回 awaitable 或使用 asyncio.to_thread(如需同步函数)         return await asyncio.to_thread(sql_filter_vanna, query_input)

⚠️ 注意事项:args_schema 必须是 pydantic.BaseModel 的子类,字段名需与 _run 方法参数名严格一致(此处为 query_input);若 _run 接收多个参数(如 query_input: str, db_name: str),则 SQLFilterInput 中需对应定义全部字段;async def _arun 的签名也应与 _run 保持语义一致(参数名可不同,但逻辑输入应匹配);

✅ 更简洁方案:优先使用 @tool 装饰器(推荐)

正如答案中所示,@tool 是 LangChain 官方推荐的轻量级工具定义方式,它自动推导 schema(基于类型注解 + docstring),无需手动管理 BaseModel:

from langchain.agents import tool  @tool def filter_user_query(query_input: str) -> str:     """根据用户自然语言问题生成SQL过滤条件。      例如输入:"2023年8月计算机设备的平均温度" → 输出:"WHERE device_type = 'computer' AND month = 8 AND year = 2023"     """     return sql_filter_vanna(query_input)

该方式自动注册为 Tool 实例,支持多参数、类型校验、描述提取,且与最新 Agent(如 openaiToolsAgent、reactAgent)完全兼容。

? 补充说明:为什么之前能运行,现在报错?

  • 你提到“几天前代码正常”,大概率是升级了 LangChain 版本(如从 0.0.x 升至 0.1.0+);
  • 旧版 LangChain 对 BaseTool 的参数解析较宽松,新版强化了 schema 驱动机制以提升可靠性与可调试性;
  • @tool 装饰器在各版本中行为更稳定,是生产环境首选。

✅ 总结

方案 是否推荐 关键要求
BaseTool 子类 ⚠️ 仅需高度定制时用 必须实现 args_schema,字段名与 _run 参数严格对齐
@tool 装饰器 ✅ 强烈推荐 使用类型注解 + docstring,零配置即用

选择 @tool 可大幅降低维护成本,避免隐式参数映射陷阱。如需扩展功能(如异步支持、自定义序列化),再考虑 BaseTool 并严格遵循 schema 规范。

text=ZqhQzanResources