拓冰建站拓冰建站
首页 / 资讯中心 / 正文

深入浅出Function Calling②-零基础保姆级教程

第 3 章多工具、并行调用与工具注册表3.1 三件武器上架def calculator(expression: str) - str: 安全计算器01教程18章白名单方案转正 allowed set(0123456789-*/().% ) if not expression or not set(expression) allowed: return 错误表达式含非法字符只支持数字与-*/()% try: return str(eval(expression)) except Exception as e: return f计算失败: {e} def get_exchange_rate(currency: str CNY) - str: 美元兑指定货币汇率01教程的老朋友 try: r requests.get(https://api.exchangerate-api.com/v4/latest/USD, timeout10) r.raise_for_status() rate r.json()[rates].get(currency.upper()) return f1 USD {rate} {currency.upper()} if rate else f不支持的货币代码: {currency} except requests.RequestException as e: return f汇率查询失败: {e}3.2 注册表模式清单与执行器分离生产项目从不写if name get_weather长梯子用字典注册表TOOLS_SCHEMA [ { type: function, function: { name: get_weather, description: 查询指定城市的当前实时天气。用户询问天气/气温/穿衣建议时使用。, parameters: {type: object, properties: {city: {type: string, description: 城市中文名如北京}}, required: [city]}}}, { type: function, function: { name: calculator, description: 计算数学表达式。任何算术问题都必须用本工具禁止心算。, parameters: {type: object, properties: {expression: {type: string, description: 标准数学表达式如 (35)*2/7不含变量与函数}}, required: [expression]}}}, { type: function, function: { name: get_exchange_rate, description: 查询美元(USD)兑其它货币的实时汇率。, parameters: {type: object, properties: {currency: {type: string, description: 三位货币代码如 CNY/JPY/EUR默认 CNY}}, required: []}}}, ] TOOL_REGISTRY { # 名字 → 真函数 get_weather: get_weather, calculator: calculator, get_exchange_rate: get_exchange_rate, }3.3 统一执行器防错三连模型可能编造工具名、填坏参数、触发函数异常——执行器把三种事故全部转化为给模型看的错误说明让它自我修正def execute_tool(tc) - str: 接收一张申请单(tool_call)返回结果字符串永不抛异常 name tc.function.name func TOOL_REGISTRY.get(name) if func is None: # 事故1编造工具名 return f错误工具 {name} 不存在。可用工具: {list(TOOL_REGISTRY)} try: args json.loads(tc.function.arguments or {}) except json.JSONDecodeError as e: # 事故2参数不是合法JSON return f错误参数解析失败({e})。请以合法JSON重新提供参数。 try: return str(func(**args)) except TypeError as e: # 事故3a参数名/缺参错误 return f错误参数不匹配({e})。请核对参数名后重试。 except Exception as e: # 事故3b函数内部异常 return f工具执行出错: {type(e).__name__}: {e}3.4 并行调用一次申请 N 张单问北京上海的天气再算下 36524模型可能一次返回*多张申请单parallel tool calls。处理规则逐张执行每张回一条 tool 消息id 一一对应if msg.tool_calls: messages.append(msg) for tc in msg.tool_calls: # 可能有 1~N 张 messages.append({role: tool, tool_call_id: tc.id, content: execute_tool(tc)})3.5 tool_choice给模型的自由度上锁取值含义场景auto默认模型自己决定调不调、调哪个常规 Agentnone禁止调用工具只许说话纯闲聊分支、强制总结required必须调至少一个工具表单抽取等确定要工具的流程{type:function,function:{name:x}}强制调用指定工具固定流水线步骤第 4 章Agent 循环 —— 20 行 while 里的智能4.1 从一来一回到自主多步真实问题常需要连环工具美元汇率是多少100 美元换成人民币再乘 3 是多少钱——模型得先查汇率、再拿结果算乘法、最后作答。解法就是Agent 的本质是一个 while 循环def run_agent(messages: list, max_iterations: int 8) - str: 通用 Agent 循环模型不再申请工具时即为最终答案 for i in range(max_iterations): # 铁丝网防死循环 resp client.chat.completions.create( modelMODEL, messagesmessages, toolsTOOLS_SCHEMA, temperature0.3) # 工具决策要稳低温 msg resp.choices[0].message if not msg.tool_calls: # 出口这轮是人话 messages.append({role: assistant, content: msg.content}) return msg.content print(f [第{i1}轮] 模型申请: f{[(t.function.name, t.function.arguments) for t in msg.tool_calls]}) messages.append(msg) # 申请单入史 for tc in msg.tool_calls: result execute_tool(tc) print(f [第{i1}轮] 工具返回: {result[:80]}) messages.append({role: tool, tool_call_id: tc.id, content: result}) # 不 return —— 回到循环顶部带着工具结果再问模型 return 抱歉任务过于复杂已达最大工具调用轮数请拆分后再试。跑一把连环任务messages [ {role: system, content: 你是全能助理。实时信息与一切计算都必须用工具完成禁止凭记忆或心算。}, {role: user, content: 现在1美元换多少人民币100美元换成人民币再乘3是多少}, ] print(最终:, run_agent(messages)) # 观察打印第1轮申请汇率 → 第2轮拿着汇率申请计算器 → 第3轮输出答案4.2 请郑重认识你写下的东西这 20 行循环 一个真正的 Agent感知读对话→ 决策选工具→ 行动执行→ 观察结果入史→ 再决策……直到目标达成。第 5 批的 LangGraph、各大 Agent 框架内核都是这个循环的工程化加强版状态管理、持久化、可视化、人工介入。先徒手写过它你用任何框架都不会被唬住——这正是大厂面试要手撕它的原因。两个循环安全阀面试必答max_iterations 上限兜底死循环模型反复调同一工具拿到同样结果时会转圈temperature 调低让工具决策稳定。更多防线在下一章。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门