
本文详解如何解决CrewAI中因直接传入LangChain原生Tool实例导致的Input should be a valid dictionary or instance of BaseTool验证错误,核心在于将LangChain工具正确封装为符合CrewAI规范的自定义BaseTool子类。
本文详解如何解决crewai中因直接传入langchain原生tool实例导致的`input should be a valid dictionary or instance of basetool`验证错误,核心在于将langchain工具正确封装为符合crewai规范的自定义`basetool`子类。
CrewAI要求所有传入Agent的tools必须是继承自crewai.tools.BaseTool的实例(或其字典表示),而LangChain的DuckDuckGoSearchResults返回的是langchain.agents.Tool对象——二者类型不兼容,因此触发Pydantic验证失败。
要修复该问题,需创建一个适配器类,继承BaseTool并桥接LangChain工具逻辑。以下是完整、可直接运行的修复方案:
✅ 正确封装LangChain工具为CrewAI兼容工具
from typing import Type
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
from langchain_community.tools import DuckDuckGoSearchResults
# 1. 定义输入Schema(强制校验query参数)
class DuckDuckGoSearchInput(BaseModel):
query: str = Field(..., description="待搜索的关键词或问题,例如 '2024年大模型最新进展'")
# 2. 创建自定义工具类,继承BaseTool
class DuckDuckGoSearchTool(BaseTool):
name: str = "DuckDuckGo网络搜索"
description: str = "通过DuckDuckGo搜索引擎获取实时网页结果,适用于事实核查与趋势调研。"
args_schema: Type[BaseModel] = DuckDuckGoSearchInput
def _run(self, query: str) -> str:
"""执行搜索并返回结构化文本结果"""
tool = DuckDuckGoSearchResults()
try:
result = tool.invoke({"query": query}) # 注意:新版LangChain要求传入dict
return result[:2000] # 截断过长响应,避免token超限
except Exception as e:
return f"搜索失败:{str(e)}"
✅ 替换原始代码中的工具初始化
将原代码中:
duckduckgo_search = DuckDuckGoSearchResults()
替换为:
duckduckgo_search = DuckDuckGoSearchTool() # ✅ 实例化自定义工具
同时确保已安装依赖:
pip install crewai langchain-community duckduckgo-search
⚠️ 关键注意事项:
- LangChain DuckDuckGoSearchResults 的 .invoke() 方法在较新版本中必须接收字典参数(如 {"query": "xxx"}),而非纯字符串,否则会报错;
- BaseTool.args_schema 不仅用于文档生成,更是CrewAI自动构建工具调用参数的依据,缺失或类型不符将导致任务执行中断;
- 若需支持多参数(如num_results, region),应在DuckDuckGoSearchInput中扩展字段,并在_run中透传;
- 生产环境建议添加重试机制与超时控制(可通过tool = DuckDuckGoSearchResults(max_results=5)配置)。
完成上述修改后,researcher Agent即可正常加载工具,Crew将按序执行研究与写作任务,不再触发Pydantic类型校验异常。此模式同样适用于YouTubeSearchTool、ArxivQueryRun等任意LangChain工具的CrewAI集成。











