OpenManus 添加自定义工具完整教程
OpenManus的工具系统基于「插件化设计」,所有自定义工具需继承框架的 确认目录结构:在OpenManus项目根目录下,建议创建 核心依赖:确保已安装基础依赖(无需额外安装,框架自带工具基类): 所有自定义工具必须继承 创建 修改OpenManus的核心配置文件 找到 编写测试代码,验证自定义工具是否能被AI智能体识别并调用: 若工具需要多个输入参数(如「根据城市和日期查询天气预报」),修改工具类的 测试指令可改为: 解决: 解决: 解决:核心原则
BaseTool基类,实现标准化接口,再通过配置文件注册,即可被AI智能体识别和调用。一、前置准备
custom_tools目录存放自定义工具(便于管理):mkdir custom_tools # 项目根目录执行pip install openmanus # 若未安装框架核心包二、步骤1:编写自定义工具类(核心)
BaseTool基类,并实现3个核心要素:name:工具唯一名称(AI通过名称识别工具)description:工具描述(关键!AI通过描述判断何时调用该工具,需清晰说明「用途+输入格式」)run():工具执行逻辑(接收输入参数,返回执行结果)示例:开发「实时天气查询工具」
custom_tools/weather_tool.py文件,写入以下代码(含完整注释):# 导入框架核心基类和结果封装类
from openmanus.tools.base import BaseTool, ToolResult
# 按需导入第三方依赖(如请求网络需requests)
import requests
# 自定义工具类,必须继承BaseTool
class WeatherQueryTool(BaseTool):
# 1. 工具唯一名称(不可重复,建议英文)
name = "WeatherQueryTool"
# 2. 工具描述(核心!需明确:用途+输入格式+输出说明)
description = """
用于查询指定城市的实时天气信息,输入格式为「城市名」(如:北京、上海),
输出格式为「城市名 + 温度 + 天气状况」(如:北京 18℃ 晴)。
仅当用户询问天气相关问题时调用该工具。
"""
# 3. 工具执行逻辑,必须实现run方法
def run(self, city: str) -> ToolResult:
"""
参数说明:
- city: 字符串,用户输入的城市名
返回值:ToolResult对象(封装执行结果,必填)
"""
try:
# 步骤1:校验输入(可选,增强健壮性)
if not city or len(city) > 10:
return ToolResult(
success=False, # 执行失败标记
content="输入无效!请输入正确的城市名(如:北京)"
)
# 步骤2:核心业务逻辑(调用免费天气API)
# 替换为可靠的天气API,此处使用wttr.in(无需密钥)
url = f"http://wttr.in/{city}?format=3" # 精简格式:城市名: 天气 温度
response = requests.get(url, timeout=10)
# 步骤3:处理响应并封装结果
if response.status_code == 200:
weather_info = response.text.strip()
return ToolResult(
success=True, # 执行成功标记
content=f"✅ {weather_info}" # 返回给AI的内容
)
else:
return ToolResult(
success=False,
content=f"❌ 天气查询失败,API响应码:{response.status_code}"
)
# 异常处理(必加,避免工具崩溃)
except requests.exceptions.Timeout:
return ToolResult(success=False, content="❌ 网络超时,无法查询天气")
except Exception as e:
return ToolResult(success=False, content=f"❌ 查询出错:{str(e)}")关键说明:
ToolResult:框架规定的结果封装类,必须返回该类型,包含success(布尔值)和content(字符串)两个核心字段。description的精准性:AI完全依赖这段描述判断「是否调用该工具」,需明确:三、步骤2:配置文件注册自定义工具
config.yaml(无则从config.example.yaml复制),将自定义工具添加到tools列表中:1. 复制配置模板(首次需做)
cp config.example.yaml config.yaml # 项目根目录执行2. 编辑
config.yaml,添加工具配置tools节点,新增自定义工具的配置项:# config.yaml 核心配置片段
llm:
type: openai
model: gpt-4-turbo
api_key: "sk-xxxxxx" # 替换为你的LLM密钥
base_url: "https://api.openai.com/v1"
# 工具注册列表(内置工具 + 自定义工具)
tools:
# 保留框架内置工具(按需取舍)
- name: BrowserTool # 浏览器工具
- name: CodeExecutorTool # 代码执行工具
- name: FileTool # 文件操作工具
# 新增自定义工具(关键配置)
- name: WeatherQueryTool # 必须和工具类的name一致
path: custom_tools/weather_tool.py # 工具文件的绝对/相对路径
enabled: true # 是否启用该工具(默认true)配置说明:
name:必须和自定义工具类中定义的name完全一致(大小写敏感)。path:工具文件的路径,支持相对路径(相对于项目根目录)或绝对路径。enabled:是否启用该工具,设为false则AI不会调用。四、步骤3:测试自定义工具
1. 创建测试文件
test_custom_tool.pyimport asyncio
from openmanus.agent import Agent # 单智能体
from openmanus.config import Config # 配置加载类
# 异步测试函数(OpenManus核心逻辑为异步)
async def test_weather_tool():
# 步骤1:加载配置文件
config = Config.from_file("config.yaml")
# 步骤2:初始化AI智能体
agent = Agent(config=config)
# 步骤3:发送包含工具调用的任务指令
task = "查询深圳市的实时天气"
# 步骤4:执行任务并获取结果
result = await agent.run(task)
# 步骤5:打印结果
print("=== 自定义工具调用结果 ===")
print(result)
# 执行测试
if __name__ == "__main__":
asyncio.run(test_weather_tool())2. 运行测试代码
python test_custom_tool.py预期输出:
=== 自定义工具调用结果 ===
✅ 深圳: 晴 25℃五、进阶:支持多参数的自定义工具
run方法即可:示例:多参数天气工具
class WeatherQueryTool(BaseTool):
name = "WeatherQueryTool"
description = """
查询指定城市指定日期的天气预报,输入格式为「城市名,日期」(日期格式:YYYY-MM-DD,例:北京,2026-01-20)。
若未指定日期,则查询实时天气。
"""
def run(self, input_str: str) -> ToolResult:
# 解析多参数
parts = input_str.split(",")
city = parts[0].strip()
date = parts[1].strip() if len(parts) > 1 else None
# 核心逻辑(示例)
if date:
content = f"✅ {city} {date} 的天气预报:晴 22-30℃"
else:
content = f"✅ {city} 实时天气:晴 25℃"
return ToolResult(success=True, content=content)查询上海2026-01-20的天气预报。六、常见问题与排查
问题1:AI不调用自定义工具
description描述不清晰,AI无法判断何时调用;或工具名称/路径配置错误。description,明确「触发条件+输入格式」;config.yaml中工具name是否和类名一致;问题2:工具执行报错「找不到模块」
BaseTool。config.yaml中path是相对项目根目录的路径;from openmanus.tools.base import BaseTool。问题3:工具返回结果为空
run方法未正确返回ToolResult对象,或业务逻辑出错。run方法最后return ToolResult(...);run方法中添加日志(如print(city)),调试业务逻辑。总结
description是AI调用工具的核心依据,需精准描述用途和输入格式;ToolResult是结果返回的标准格式,必须使用。