news 2026/8/7 6:47:05

自定义工具开发实战:把任意Python函数变成AI Agent可用的工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
自定义工具开发实战:把任意Python函数变成AI Agent可用的工具

自定义工具开发,把任意Python函数变成Agent工具

内置工具只能解决通用问题。真正做项目的时候,你肯定需要写自己的工具。

比如对接公司内部的API,操作特定的业务系统,调用内部的数据库。这些都得自己写。

好消息是,在LangChain里写自定义工具特别简单。把一个普通的Python函数装饰一下,Agent就能调用了。

这一篇我们从最简单的开始,一步步讲怎么写工具、怎么写好工具描述、怎么处理异常,以及实际项目里的一些经验。


最简单的写法

用@tool装饰器,是最简单的方式。

fromlangchain.toolsimporttool@tooldefadd_numbers(a:int,b:int)->str:"""把两个数字相加,返回相加的结果。"""returnf"结果是{a+b}"

就这么简单。一个普通的函数,加上@tool装饰器,就变成了Agent能用的工具。

函数名就是工具名。函数的文档字符串就是工具的描述。函数的参数类型注解,就是参数的类型说明。

这三样东西都很重要。Agent靠它们来理解这个工具是干什么的、什么时候该用、参数怎么传。

写的时候注意几点。

函数名要直观。一看就知道这个工具做什么的。别起太抽象的名字。

文档字符串要写详细。别只写一句话。说清楚功能、参数含义、什么时候用、举个例子。后面会专门讲怎么写好描述。

参数类型要标清楚。int、str、float这些基本类型直接写就行。复杂类型用Pydantic模型。


用Pydantic定义输入

参数简单的时候,直接写类型注解就行。参数多了,或者参数有嵌套结构,最好用Pydantic模型来定义。

fromlangchain.toolsimporttoolfrompydanticimportBaseModel,FieldclassWeatherInput(BaseModel):city:str=Field(description="城市名称,比如北京、上海、广州")date:str=Field(description="查询的日期,格式为YYYY-MM-DD,比如2026-08-06")@tool(args_schema=WeatherInput)defget_weather(city:str,date:str)->str:"""查询指定城市指定日期的天气情况。 返回天气状况、温度、湿度、风力等信息。 例如用户问'明天北京天气怎么样'的时候可以调用这个工具。 """# 实际项目中这里调用天气APIreturnf"{city}{date}的天气是晴,25度。"

用Pydantic的好处是,你可以给每个参数加description,还可以加校验规则。Agent能更准确地理解参数的含义,参数传错的概率会降低。

参数超过两个的时候,我建议都用Pydantic来定义。多写几行代码,省很多调试的时间。


工具描述怎么写才好用

工具能不能用好,描述占了八成。

描述写得好,Agent用得准。描述写得烂,Agent经常选错工具、填错参数。

我自己总结了几个写工具描述的经验。

第一,说清楚能做什么,也说清楚不能做什么。边界清楚了,Agent才知道什么时候该调用、什么时候不该调用。

第二,举例子。在描述里加一两个使用场景的例子。比如"当用户问’某某城市天气怎么样’的时候,可以调用这个工具"。例子对大模型特别有效。

第三,参数说明要具体。每个参数是什么意思、什么格式、有什么限制,都写清楚。有可选值就列出来。日期格式、数字范围、单位,都说明白。

第四,说明返回值的格式。告诉Agent工具会返回什么样的结果,它拿到结果以后知道怎么处理。

举个反例和正例对比一下。

反面教材。

@tooldefsearch(query:str)->str:"""搜索工具。"""...

这种描述等于没写。Agent根本不知道什么时候该用、参数怎么传。

正面教材。

@tooldefsearch(query:str)->str:"""通过搜索引擎查询互联网上的最新信息。 当你需要回答以下类型的问题时使用这个工具: - 实时新闻和热点事件 - 最新的产品价格、发布日期 - 不确定的知识,或者你的训练数据里可能没有的信息 - 具体的事实核查 参数说明: query: 搜索关键词。用中文或英文都可以。不要太长,20个字以内效果最好。 返回:搜索结果的摘要,包含标题、摘要和链接。 """...

这样写,Agent就很清楚什么时候该调用、怎么传参数。


处理异常和错误

工具调用总会出错。网络断了,API限流了,参数不对,数据库连不上。各种情况都可能发生。

出错了怎么办。两个原则。

第一,工具内部要捕获异常,不要直接抛出去。Agent拿到异常信息也不知道怎么处理。

第二,返回给Agent的错误信息要有意义。告诉它哪里错了、可能的原因、建议的处理方式。它才能决定是重试、换个方式,还是告诉用户。

比如这样。

@tooldefget_weather(city:str)->str:"""查询城市天气。"""try:result=call_weather_api(city)returnresultexceptNetworkError:return"网络连接失败,无法查询天气。请稍后再试。"exceptCityNotFoundError:returnf"找不到{city}的天气数据。请确认城市名称是否正确,或者换一个城市试试。"exceptExceptionase:returnf"查询天气时出现未知错误,{e}。"

不同的错误返回不同的提示。Agent能根据提示决定下一步怎么做。城市找不到就换个名字,网络错了就重试。

如果只返回"出错了"三个字,Agent也不知道该怎么办,任务就卡住了。


同步和异步

默认的工具是同步的。如果你的工具里有IO操作,比如网络请求、数据库查询,可以写成异步的,性能更好。

@toolasyncdefasync_get_weather(city:str)->str:"""异步查询天气。"""result=awaitasync_weather_api(city)returnresult

用的时候,调用ainvoke而不是invoke。

简单的工具无所谓同步异步。IO密集型的工具,做成异步的,并发调用的时候速度会快很多。


完整示例

最后给一个完整的自定义工具例子,你可以照着写。

fromlangchain.toolsimporttoolfrompydanticimportBaseModel,FieldimportrequestsclassTranslateInput(BaseModel):text:str=Field(description="要翻译的文本,可以是中文或英文")target_lang:str=Field(description="目标语言,可选值:zh(中文)、en(英文)、ja(日文)",)@tool(args_schema=TranslateInput)deftranslate(text:str,target_lang:str)->str:"""文本翻译工具。支持中文、英文、日文互译。 当用户要求翻译文本,或者用户说的语言和默认语言不同时,可以使用这个工具。 例如用户说'把这句话翻译成英文'、'这个日语是什么意思'的时候。 参数说明: text: 要翻译的原文内容,长度不超过5000字 target_lang: 翻译后的目标语言代码 返回:翻译后的文本内容。 """try:# 这里替换成实际的翻译API调用response=requests.post("https://api.translation.example.com/translate",json={"text":text,"target":target_lang},timeout=10,)response.raise_for_status()result=response.json()returnf"翻译结果:{result['translated_text']}"exceptrequests.Timeout:return"翻译服务超时了,请稍后重试。"exceptrequests.HTTPErrorase:ife.response.status_code==429:return"翻译请求太频繁了,等一下再试。"returnf"翻译服务出错了,状态码{e.response.status_code}。"exceptExceptionase:returnf"翻译时出现未知错误,{e}。"

这个例子包含了Pydantic参数定义、详细的工具描述、异常处理。可以作为你写自定义工具的模板。


下一篇我们讲搜索引擎接入。搜索是Agent最重要的能力之一,我们深入讲一讲怎么接、怎么用好。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 6:46:49

LLM文件编写:从Prompt工程到Agent工作流的实战指南

1. 项目概述:为什么“LLM文件编写”是当下最值得投入的技能? 如果你最近在关注AI应用开发,尤其是大语言模型(LLM)的落地,那么“LLM文件编写”这个词组一定高频出现在你的视野里。它听起来可能有点技术化&a…

作者头像 李华
网站建设 2026/8/7 6:42:46

郴州建设工程信息网站:为每一块基石注入透明与诚信的力量,寻找本地项目真相

在这个信息爆炸却又充满了迷雾的时代,作为一名在建筑行业摸爬滚打多年的“老兵”,我深知大家心里那份沉甸甸的焦虑。每天醒来,第一件事不是看新闻,而是打开各种软件、网站,试图从纷繁复杂的线索里打捞出一两个靠谱的项目。尤其是对于咱们郴州本地的包工头、劳务班组,甚至…

作者头像 李华
网站建设 2026/8/7 6:35:03

网站建设项目内控单全流程深度解析:避坑指南、风险管控与高效执行策略全攻略

做网站建设项目,很多老板或者项目经理第一次接触“内控单”这个词的时候,脑海里浮现的可能是一张干巴巴的表格,或者是财务部门用来卡预算的繁琐流程。说实话,以前我也这么想。觉得这玩意儿就是增加工作量,还要填一堆没人看的文档。直到我亲手操盘了几个中型网站开发项目,…

作者头像 李华
网站建设 2026/8/7 6:33:37

Unity游戏数据持久化实战:Save Game Free插件核心应用与避坑指南

1. 项目概述:当Unity存档不再令人头疼如果你是一名Unity开发者,无论你是刚入门的新手,还是已经做过几个项目的熟手,我相信你一定在某个深夜,对着游戏存档功能挠过头。玩家进度丢了、存档文件被轻易篡改、跨平台读取乱码…

作者头像 李华
网站建设 2026/8/7 6:32:48

计算机专业实测:哪款 AI 工具最适合撰写毕业设计论文?四大主流平台效率、深度、专业度全面测评

毕业季,计算机专业毕业生总要深陷毕业论文难题:系统架构论述难懂、程序代码描述杂乱、ER‑UML 配图难制作、参考文献格式繁琐、查重与 AIGC‑AI 检测双重压力,加上开题报告、中期材料、答辩 PPT 等繁杂任务,无数同学熬夜攻坚却收效…

作者头像 李华