当前位置: 首页 > news >正文

9.2 入门案例:简单函数调用机器人

RAG 让 LLM 能「读」,Function Calling 让 LLM 能「做」。这篇带你从零实现一个​带工具调用能力的聊天机器人​——它能查天气、搜新闻、做算术,还能把结果整理成漂亮的格式返回。

📑 目录

  • 项目目标
  • 定义工具集
  • 核心循环:决策 → 执行 → 观察
  • 完整代码实现
  • 扩展方向

项目目标

最终效果: 用户:「北京今天天气怎么样?顺便帮我算下 23 * 47」 机器人: 🌤 北京今天:晴,气温 12~22°C,适合出行 🧮 23 × 47 = 1081 用户:「搜一下最新的 AI 新闻」 机器人:[调用搜索工具] 🔍 找到以下最新资讯: 1. OpenAI 发布 GPT-5 ... 2. Google DeepMind 宣布 ... 关键能力: ✅ 自动判断是否需要调用工具 ✅ 正确提取函数参数 ✅ 执行工具并将结果整合进回答 ✅ 多轮工具调用(一个问题可能需要调多个工具)

定义工具集

# bot/tools.pyimportjsonimportrandomfromdatetimeimportdatetimefromtypingimportCallable# 工具注册表:名称 → (函数, 描述, 参数Schema)TOOLS_REGISTRY:dict[str,dict]={}deftool(name:str,description:str,params_schema:dict):"""装饰器:注册一个工具函数"""defdecorator(func:Callable):TOOLS_REGISTRY[name]={"function":func,"description":description,"parameters":params_schema,}returnfuncreturndecorator@tool(name="get_weather",description="获取指定城市的当前天气",params_schema={"type":"object","properties":{"city":{"type":"string","description":"城市名"},},"required":["city"]})defget_weather(city:str)->str:"""模拟天气 API(实际替换为真实 API)"""weathers=["晴","多云","阴","小雨"]temp_low=random.randint(-5,20)temp_high=random.randint(temp_low+5,temp_low+18)returnjson.dumps({"city":city,"weather":random.choice(weathers),"temp_low":temp_low,"temp_high":temp_high,"updated_at":datetime.now().isoformat()},ensure_ascii=False)@tool(name="calculate",description="执行数学计算表达式",params_schema={"type":"object","properties":{"expression":{"type":"string","description":"数学表达式,如 '23*47'"},},"required":["expression"]})defcalculate(expression:str)->str:try:# 安全起见只允许数字和基本运算符allowed=set("0123456789+-*/().% ")ifnotall(cinallowedforcinexpression):returnjson.dumps({"error":"不允许的表达式字符"})result=eval(expression)# 生产环境用 ast.literal_eval 更安全returnjson.dumps({"expression":expression,"result":result})exceptExceptionase:returnjson.dumps({"error":str(e)})@tool(name="search_news",description="搜索最新新闻(按关键词)",params_schema={"type":"object","properties":{"keyword":{"type":"string","description":"搜索关键词"},"limit":{"type":"integer","description":"返回条数(默认5)"},},"required":["keyword"]})defsearch_news(keyword:str,limit:int=5)->str:"""模拟搜索(实际接入搜索 API 或 Tavily)"""fake_news=[f"{keyword}相关重大进展报道",f"专家解读{keyword}领域新趋势",f"{month}{keyword}行业数据发布",]returnjson.dumps([{"title":n,"source":"模拟源"}forninfake_news[:limit]],ensure_ascii=False)print(f"已注册{len(TOOLS_REGISTRY)}个工具:{list(TOOLS_REGISTRY.keys())}")

核心循环 & 完整实现

# bot/main.pyfromopenaiimportOpenAIimportjsonfromtoolsimportTOOLS_REGISTRY client=OpenAI()defbuild_tools_definition():"""转换为 OpenAI Function Calling 格式"""return[{"type":"function","function":{"name":name,"description":info["description"],"parameters":info["parameters"]}}forname,infoinTOOLS_REGISTRY.items()]defexecute_tool(name:str,args:dict):"""安全执行工具并返回结果"""ifnamenotinTOOLS_REGISTRY:returnjson.dumps({"error":f"未知工具:{name}"})try:func=TOOLS_REGISTRY[name]["function"]result=func(**args)returnresultexceptExceptionase:returnjson.dumps({"error":f"工具执行错误:{e}"})defchat_with_tools(user_message:str,max_turns=5):"""带 Function Calling 的多轮对话循环"""messages=[{"role":"system","content":"你是一个有帮助的助手。使用可用工具来获取实时信息和执行操作。"}]messages.append({"role":"user","content":user_message})tools_def=build_tools_definition()forturninrange(max_turns):response=client.chat.completions.create(model="gpt-4o-mini",messages=messages,tools=tools_def,temperature=0.2,)msg=response.choices[0].message# 情况A:直接回答ifnotmsg.tool_calls:returnmsg.content# 情况B:调用工具messages.append(msg)# 记录 LLM 的决策fortcinmsg.tool_calls:func_name=tc.function.name func_args=json.loads(tc.function.arguments)print(f" 🔧 调用工具:{func_name}({func_args})")tool_result=execute_tool(func_name,func_args)print(f" 📋 结果:{tool_result[:100]}...")# 结果喂回 LLMmessages.append({"role":"tool","tool_call_id":tc.id,"content":tool_result})return"达到最大轮次限制"# CLI 交互if__name__=="__main__":print("🤖 函数调用机器人已启动!(输入 quit 退出)\n")whileTrue:query=input("你: ")ifquery.lower()=="quit":breakanswer=chat_with_tools(query)print(f"🤖:{answer}\n")
# 运行python-mbot.main

❌ 常见误区

  • ❌ 工具描述写得越详细越好 — 太长的描述反而干扰 LLM 决策,简洁精准最好
  • ❌ 所有工具一次性注册 — 按场景分组加载,减少选择困难
  • ❌ 忽略工具的错误处理 — 工具可能失败,必须有 fallback 和异常捕获
http://www.gsyq.cn/news/1582540.html

相关文章:

  • 【从0到1构建一个ClaudeAgent】规划与协调-技能
  • 三位24岁博士团队创办映界科技,补齐具身智能感知短板,2026年订单有望超千万!
  • Kimi LeetCode 3348. 最小可整除数位乘积 II Rust实现
  • 开源版Figma:Penpot,设计协同+代码生成,全栈设计平台
  • 杰理之固定通话音量【篇】
  • Xbox成就解锁终极指南:3分钟掌握免费开源工具的完整教程 [特殊字符]
  • 计算机毕业设计之高校社团招新管理系统
  • 轻智能时代开启,谁在夯实智慧家庭的“地基”?
  • NoSleep防休眠助手:5分钟掌握Windows屏幕永不停歇的智能解决方案
  • 如何快速掌握微信小程序逆向分析:wxappUnpacker完整指南与5个实用技巧
  • ripgrep:比 grep 快几十倍的命令行搜索工具
  • 深圳华智信创|华为IdeaHub会议协作平板金牌代理商
  • 数字刊物系统用户操作手册
  • 【基础电子元件】电感
  • QPR(准比例谐振控制器)详解
  • 钢结构---柱基础二次浇筑的预留空间
  • 第一讲,c语言基础
  • 高效抢票实战指南:5分钟掌握大麦自动化购票技巧
  • 王牌操盘手怎么样?一文看懂其运营方法论与行业价值
  • 数字员工--前番
  • 磐创科技PCTG-1014型工业协议转换网关接线与组态配置指南
  • 存量RPA智能化改造指南:分阶段升级的技术落地顺序与企业架构重构实战
  • larksuite-cliskill
  • InDraw怎么调整键长、键角、键间距?
  • 2026英语重启阶段,很多人卡住的不是记不住单词,而是根本读不进去
  • 【Linux】章4 归档和传输文件(RH134知识点问答题)
  • 机械键盘连击克星:精准配置与智能过滤技术指南
  • GTA5线上小助手:5分钟掌握终极游戏增强方案,解锁洛圣都无限可能
  • 终极指南:如何免费掌控你的Alienware灯光、风扇与电源设置
  • 免费终极指南:5步使用League Director打造专业级英雄联盟视频