67-Agent工具定义与调用-搜索引擎-数据库-代码执行器集成

文章目录

  • 【67.Python+AI】Agent工具定义与调用:搜索引擎、数据库、代码执行器集成实战
    • 导入语
    • 1 ~> 工具的定义规范
      • 1.1 一个标准 Tool 的结构
      • 1.2 工具描述的黄金法则
    • 2 ~> 工具一:搜索引擎集成
      • 2.1 使用 Tavily Search API
      • 2.2 免费替代方案
    • 3 ~> 工具二:数据库查询
      • 3.1 让 Agent 安全地查数据库
      • 3.2 带着表结构描述的 Tool
    • 4 ~> 工具三:Python 代码执行器
      • 4.1 为什么要让 Agent 执行代码
      • 4.2 沙箱式代码执行
    • 5 ~> 三合一 Agent 实战
      • 5.1 架构
      • 5.2 完整代码
      • 5.3 执行过程
    • 思考 && 总结
    • 结尾

【67.Python+AI】Agent工具定义与调用:搜索引擎、数据库、代码执行器集成实战

📖文章简介:本文聚焦Agent开发中最关键的环节——工具(Tool)的定义与集成。文章从"一个好的工具描述长什么样"开始,拆解Tool的四大要素(名称、描述、参数schema、执行函数),然后逐一讲解三种最常用工具的集成方式:搜索引擎(Tavily API)、数据库查询(SQLite + 安全检查)、Python代码执行器(沙箱模式)。最后给出一个"三合一"Agent的完整代码——能上网搜索、能查数据库、能写代码计算,配上Mermaid架构图展示工具调度流程。适合正在写ReAct Agent、需要给Agent扩充能力的开发者。


🎬 个人主页:源码骑士

专栏传送门:《Android开发基础》《python基础课程》

⭐️热衷从源码视角拆解技术底层原理,将复杂架构讲得通俗易懂


🎬 源码骑士的简介:
5年Android Framework系统开发经验,曾主导多项系统级性能优化专项
技术栈覆盖Android系统全链路(Binder/Handler/AMS/WMS/启动流程)及Java后端全家桶(Spring + MyBatis + Redis + Oracle)
累计产出原创技术文章100+篇,文章以流程图为特色,被读者评价为"看一篇胜过啃一周源码"


导入语

Agent 的"智能"从哪里来?一半来自 LLM 的推理能力,另一半来自它能调用的工具的广度——能搜到多少信息、能操作多少系统、能执行多少命令。

一个只有"搜索"工具的Agent,就是个加了联网功能的ChatGPT。但如果你的Agent能搜网页、能查数据库、能执行Python代码——它突然就有了"手和脚",能干真正的活了。

这篇文章就聚焦这个关键环节:怎么定义工具才能被LLM准确调用、三种最常用工具怎么集成、以及它们组合起来能解决什么问题。看完全文你会得到一个可复用的"三合一工具集",直接嵌入你的ReAct Agent。


1 ~> 工具的定义规范

1.1 一个标准 Tool 的结构

frompydanticimportBaseModel,FieldclassTool:"""标准工具定义"""def__init__(self,name:str,description:str,func,args_schema=None):self.name=name self.description=description self.func=func self.args_schema=args_schemadefexecute(self,**kwargs):returnself.func(**kwargs)

1.2 工具描述的黄金法则

法则好的描述坏的描述
说清楚做什么“输入公司名称,返回该公司最新股价”“查股票”
说清楚输入格式“参数 keyword: 搜索关键词,多个词用空格分隔”“搜索”
说清楚输出格式“返回JSON:{price, change, volume}”无描述
写典型使用场景“当你需要获取实时信息时使用此工具”
# ✅ 好:LLM能准确理解什么时候该用、怎么用search_tool=Tool(name="web_search",description="在互联网上搜索实时信息。当你需要最新资讯、事实核查时使用。""参数 query: 搜索关键词,尽量精简。返回前5条结果的标题和摘要。",func=web_search,)# ❌ 差:LLM不知道什么时候该调用bad_tool=Tool(name="s",description="search",func=web_search,)

2 ~> 工具一:搜索引擎集成

2.1 使用 Tavily Search API

Tavily 是为 AI Agent 设计的搜索引擎 API,返回结构化的搜索结果:

importrequestsdefweb_search(query:str)->str:"""调用Tavily搜索API"""api_key="your-tavily-api-key"response=requests.post("https://api.tavily.com/search",json={"api_key":api_key,"query":query,"search_depth":"basic","max_results":5,})data=response.json()# 格式化搜索结果results=[]forrindata.get("results",[]):results.append(f"标题:{r['title']}\n内容:{r['content']}\n链接:{r['url']}")return"\n\n---\n\n".join(results)search_tool=Tool(name="web_search",description="搜索互联网获取实时信息。参数 query: 搜索关键词。",func=web_search,)

2.2 免费替代方案

如果不想用付费API,可以考虑 DuckDuckGo 的免费搜索:

# 使用 duckduckgo_search 库fromduckduckgo_searchimportDDGSdeffree_search(query:str)->str:withDDGS()asddgs:results=list(ddgs.text(query,max_results=5))return"\n".join(f"{r['title']}:{r['body']}"forrinresults)

3 ~> 工具二:数据库查询

3.1 让 Agent 安全地查数据库

直接让LLM写SQL很危险——一条DROP TABLE就灾难了。需要用读写分离 + SQL白名单做安全控制:

importsqlite3classSafeDatabase:"""安全的数据库工具——只读查询 + SQL白名单"""ALLOWED_KEYWORDS={"SELECT","FROM","WHERE","JOIN","GROUP","ORDER","LIMIT","COUNT","AVG","SUM","MAX","MIN"}def__init__(self,db_path:str):self.db_path=db_pathdefquery(self,sql:str)->str:# 安全检查sql_upper=sql.strip().upper()# 只允许 SELECT 语句ifnotsql_upper.startswith("SELECT"):return"错误:只允许 SELECT 查询"# 检查危险关键词dangerous={"DROP","DELETE","UPDATE","INSERT","ALTER","CREATE"}ifany(kwinsql_upperforkwindangerous):return"错误:不允许修改数据的操作"# 执行查询try:conn=sqlite3.connect(self.db_path)cursor=conn.cursor()cursor.execute(sql)columns=[desc[0]fordescincursor.description]rows=cursor.fetchall()conn.close()# 格式化输出result=" | ".join(columns)+"\n"+"-"*40+"\n"forrowinrows[:20]:# 最多返回20行result+=" | ".join(str(v)forvinrow)+"\n"returnresultifrowselse"查询无结果"exceptExceptionase:returnf"查询错误:{e}"db_tool=Tool(name="database_query",description="查询SQLite数据库。参数 sql: 合法的SELECT语句。""表结构: users(id, name, department, salary), orders(id, user_id, amount, date)",func=SafeDatabase("company.db").query,)

3.2 带着表结构描述的 Tool

LLM 需要知道表结构才能写出正确的 SQL。所以在 Tool 描述中要写明表名和字段:

DATABASE_SCHEMA=""" 数据库包含以下表: - employees: id, name, department, salary, hire_date - departments: id, name, manager_id - projects: id, name, budget, status """

4 ~> 工具三:Python 代码执行器

4.1 为什么要让 Agent 执行代码

有些任务LLM推理做不了——比如"这组数据的标准差是多少"、“把这个JSON排序”。让Agent直接写代码执行,比让它"算"准确得多。

4.2 沙箱式代码执行

importsysfromioimportStringIOdefexecute_python(code:str)->str:"""在受限环境中执行Python代码,捕获输出"""# 禁止危险操作forbidden=["os.","subprocess","shutil","__import__","open(","eval(","exec("]forwordinforbidden:ifwordincode:returnf"安全限制:代码中不允许使用 '{word}'"# 重定向stdoutold_stdout=sys.stdout sys.stdout=captured=StringIO()try:exec(code,{"__builtins__":{"print":print,"len":len,"range":range,"int":int,"float":float,"str":str,"list":list,"dict":dict,"sum":sum,"max":max,"min":min,"sorted":sorted,"abs":abs,"round":round,"zip":zip,}})output=captured.getvalue()returnoutputifoutputelse"代码执行成功(无输出)"exceptExceptionase:returnf"执行错误:{type(e).__name__}:{e}"finally:sys.stdout=old_stdout code_tool=Tool(name="python_executor",description="执行Python代码进行数学计算或数据处理。""参数 code: Python代码字符串。""可用函数: print, len, range, int, float, str, list, dict, sum, max, min, sorted, abs, round, zip",func=execute_python,)

5 ~> 三合一 Agent 实战

5.1 架构

实时信息

数据查询

计算分析

用户提问

ReAct Agent

需要什么类型
的操作?

web_search
Tavily API

database_query
SQLite

python_executor
沙箱执行

生成最终回答

5.2 完整代码

tools={"web_search":web_search,"database_query":SafeDatabase("company.db").query,"python_executor":execute_python,}# 提供给LLM的工具描述TOOLS_DESC=""" - web_search[关键词]: 搜索互联网获取实时信息 - database_query[SQL]: 查询公司数据库(只读SELECT) - python_executor[代码]: 执行Python代码进行数学计算 数据库表: employees(id, name, dept, salary) """agent=ReActAgent(llm=ChatOpenAI(model="gpt-4"),tools=tools,tools_prompt=TOOLS_DESC,max_steps=10)# 复杂任务:需要三个工具协同result=agent.run("查一下技术部的平均薪资,然后搜索行业平均水平,""最后算算我们的薪资比行业高了多少百分比")

5.3 执行过程

Step1: Thought: 先查技术部平均薪资 → database_query[SELECT AVG(salary)FROM employees WHEREdept='技术部']→ Observation:15000Step2: Thought: 搜索行业平均薪资 → web_search[Python开发工程师 平均薪资2024]→ Observation: 全国平均约12000元 Step3: Thought: 计算差距百分比 → python_executor[(15000-12000)/12000*100]→ Observation:25.0Final Answer: 技术部的平均薪资为15000元,比行业平均水平(12000元)高出25%

思考 && 总结

  1. 工具描述是 Agent 准确调用的第一道关口:花时间把每个Tool的description写清楚——做什么、输入什么、返回什么、什么时候该用它。这比代码实现更重要。
  2. 搜索引擎让 Agent 突破了"知识截止日"的限制:不用微调、不用RAG,一个搜索API就能让Agent拥有实时信息获取能力。
  3. 数据库查询必须加安全层:你绝对不会想让LLM直接执行它生成的SQL。读写分离 + 关键词白名单 + 行数限制,三保险。
  4. 代码执行器需要沙箱:限制可用的builtins函数、禁止文件操作和系统调用、超时控制——否则你的服务器就是一颗定时炸弹。
  5. 工具的组合是 Agent 价值的放大器:单个工具能解决的问题有限,三个工具组合起来就能处理"搜索→分析→计算"的完整数据链路。

工具多了,Agent才真正有了"手和脚"。下次别人问你"Agent能做什么"的时候,把这三个工具的运行记录给他看——比说一百句都管用。


结尾

各位小伙伴,本文的内容到这里就全部结束了,源码骑士在这里再次感谢您的阅读!

源码骑士 — Android Framework & 全栈开发

👀关注:跟博主一起从源码视角深耕底层原理,见证每一次成长

❤️点赞:让优质内容被更多人看见,让知识传递更有力量

收藏:把核心知识点存好,在需要时随时查、随时用

💬评论:分享你的经验或疑问,评论区一起交流避坑

🔄一键四连:不要忘记给博主"一键四连"哦!

🗡️寄语:技术之路难免有困惑,但同行的人会让前进更有方向

结语:给Agent装工具就像给程序员配开发环境——工具越全,能做的事情就越多。本文的三个工具是你Agent工具箱的起点,之后你可以继续加邮件发送、文件操作、API调用……Agent的能力边界只受限于你的想象力。不要忘记给博主"一键四连"哦!