ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从零开始构建AI智能体:函数调用实现与工具使用指南(收藏必学)|TaoToken 统一 Key 接入实战

从零开始构建AI智能体:函数调用实现与工具使用指南(收藏必学)|TaoToken 统一 Key 接入实战 1. 为什么你的 Agent 只会聊天不会干活从天气查询说起很多人第一次做 AI 智能体都会卡在同一个地方模型能说会道但你让它“查一下北京今天天气”它要么编一个温度要么告诉你“我无法获取实时信息”。这不是模型笨而是你只给了它一张嘴没给它一双手。函数调用Function Calling就是这双手它让 LLM 从“文本生成器”变成“能操作外部世界的执行体”。我先把结论放前面一个能落地的 AI 智能体核心就三件事——定义工具 schema、跑通调用循环、处理错误重试。天气查询、计算器、搜索这三类工具刚好覆盖了“取实时数据”“做确定性计算”“查开放信息”三种最典型的场景。你把这三个跑通剩下的业务工具只是换 schema 和换执行函数而已。这篇文章面向的是想动手写 Agent 但被各种概念绕晕的开发者。你不需要先精通 LangChain也不需要买一堆课只要会写 Python 函数、能发 HTTP 请求就能跟着把端到端流程跑起来。我会用 TaoToken 的统一 Key 和 API 通道来承接模型请求这样你不用在多个厂商的 Key 之间来回切换一个 Key 就能验证不同模型的函数调用能力。先讲清楚一个容易混淆的点函数调用不是模型去执行函数。模型做的事情是“识别意图 抽取参数 输出结构化 JSON”真正执行get_weather(北京)的是你的代码。这个分工很重要因为它决定了安全边界——模型永远不碰你的数据库和密钥它只负责告诉你“该调哪个函数、传什么参数”。我试过用纯 prompt 让模型输出 JSON结果十次里有两次格式跑偏多一个逗号就解析失败。而用原生 tools 参数模型返回的tool_calls是结构化对象参数在function.arguments里是标准 JSON 字符串解析稳定性完全不是一个量级。这就是为什么做 Agent 一定要用函数调用而不是靠“求模型输出 JSON”。下面这张表先帮你建立整体认知后面每一节都会展开工具类型典型函数参数特点执行方失败重试策略天气查询get_weather城市名、日期你的后端调气象 API城市名纠错后重试计算器calculate表达式字符串本地安全求值表达式语法修正搜索web_search查询词、条数你的后端调搜索 API换关键词重试2. TaoToken 统一 Key 接入一个 Key 打通函数调用链路做 Agent 最烦的事情之一是每换一个模型就要改一遍 base_url、换一套 Key、重写一遍鉴权逻辑。尤其是函数调用这种对模型能力有要求的场景你可能想对比几个模型谁的工具调用更稳结果光配置就耗掉半天。TaoToken 解决的就是这个问题它提供统一的 API 通道和统一 Key你只改model字段就能切换模型tools参数和调用循环的代码一行都不用动。TaoToken 是什么、能做什么、适合谁简单说它是一个大模型 API 的统一接入层把不同模型的调用协议收敛成 OpenAI 兼容格式。适合三类人一是想快速验证函数调用效果的独立开发者二是需要在多个模型间做 A/B 对比的团队三是不想在 Key 管理上花精力的 Agent 项目。你拿到的就是一个 Base URL 加一个 Key剩下的按 OpenAI SDK 的写法来就行。接入前你需要准备两样东西一个 TaoToken 的 API Key以及确认你要用的模型 ID。Key 在控制台的 API Keys 页面创建模型 ID 在文档里能查到当前支持的列表。这里有个细节函数调用对模型有要求不是所有模型都支持tools参数选模型时优先挑标注了支持 function calling 的。关于地址记住两个就够官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 。注意 API 基址后面不加任何多余路径OpenAI SDK 会自动拼/v1/chat/completions。如果你用的是原生 requests就要自己拼完整路径。我踩过的坑是一开始把 base_url 写成了带/v1的结果 SDK 又拼了一次变成/v1/v1/chat/completions直接 404。所以用 SDK 时 base_url 就写https://taotoken.net/api别自作聪明加后缀。这个细节在文档里其实写了但我当时没细看白白折腾了二十分钟。环境变量建议这样管理避免 Key 硬编码进代码export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你用 Claude Code 这类工具做辅助开发它的配置逻辑类似也是填 Base URL、Key、Model ID 三件套。但注意工具是工具Agent 的运行时代码还是要你自己控制调用循环别指望编辑器帮你把工具编排也做了。3. 可复制配置tools schema、system prompt 与 settings 片段这一节是全文最核心的部分我给你可以直接复制粘贴的配置。先定义三个工具的 schema这是模型理解“有哪些工具可用”的唯一依据。schema 写得好不好直接决定模型能不能正确抽参数。[ { type: function, function: { name: get_weather, description: 查询指定城市指定日期的天气情况当用户询问天气、气温、是否下雨时使用, parameters: { type: object, properties: { city: { type: string, description: 城市名称例如 北京、上海、深圳 }, date: { type: string, description: 日期格式 YYYY-MM-DD默认今天 } }, required: [city] } } }, { type: function, function: { name: calculate, description: 执行数学计算当用户需要做加减乘除、幂运算等确定性计算时使用, parameters: { type: object, properties: { expression: { type: string, description: 数学表达式例如 (128)*3 或 2**10 } }, required: [expression] } } }, { type: function, function: { name: web_search, description: 搜索互联网获取最新信息当用户询问实时新闻、未知事实时使用, parameters: { type: object, properties: { query: { type: string, description: 搜索关键词 }, top_k: { type: integer, description: 返回结果条数默认 3 } }, required: [query] } } } ]schema 里description字段千万别偷懒。模型判断“该不该调这个工具”全靠它。比如get_weather的描述里我特意加了“当用户询问天气、气温、是否下雨时使用”这样用户说“明天出门要带伞吗”模型也能联想到调天气工具。接下来是 system prompt 模板。它的作用是给模型定角色、定规则、定输出约束你是一个可以调用工具的智能助手。你的工作流程是 1. 理解用户意图判断是否需要调用工具。 2. 如果需要选择合适的工具并抽取参数。 3. 拿到工具返回结果后用自然语言总结给用户。 4. 如果工具报错根据错误信息决定是否重试或换参数。 规则 - 不要编造工具返回的数据一切以工具结果为准。 - 参数缺失时先向用户追问不要瞎猜。 - 一次可以调用多个工具但不要重复调用同一个工具。 - 计算类问题必须用 calculate 工具不要自己心算。这个 prompt 的关键在“不要编造工具返回的数据”和“计算类问题必须用工具”。前者防止模型幻觉后者强制它走函数调用而不是自己算。你可以根据业务再加约束比如“涉及金额的操作必须先确认”。如果你用 Python 的 OpenAI SDK客户端初始化配置这样写import os from openai import OpenAI client OpenAI( api_keyos.getenv(TAOTOKEN_API_KEY), base_urlos.getenv(TAOTOKEN_BASE_URL, https://taotoken.net/api) ) MODEL_ID gpt-4o-mini # 换成你确认支持 function calling 的模型 ID如果你更习惯用配置文件管理可以写一个settings.toml[taotoken] base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model_id gpt-4o-mini timeout 60 max_retries 3注意model_id这里要填你实际能用的模型。不同模型对函数调用的支持程度不一样有的模型返回的arguments偶尔会带多余转义解析时要加容错。这个后面排障章节会讲。4. 验证请求curl 与 Python 端到端跑通调用循环配置写好了先别急着写完整 Agent用 curl 发一个最小请求验证链路通不通。这一步能帮你快速定位是网络问题、鉴权问题还是参数问题。curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: gpt-4o-mini, messages: [ {role: user, content: 北京今天天气怎么样} ], tools: [ { type: function, function: { name: get_weather, description: 查询城市天气, parameters: { type: object, properties: { city: {type: string, description: 城市名} }, required: [city] } } } ], tool_choice: auto }如果返回的choices[0].message.tool_calls里有内容说明模型正确识别了意图并生成了工具调用。你会看到类似这样的结构{ id: call_abc123, type: function, function: { name: get_weather, arguments: {\city\: \北京\} } }注意arguments是字符串不是对象用之前要json.loads一下。这是新手最容易踩的坑之一直接当字典用会报TypeError。现在写完整的 Python 调用循环。核心逻辑是发请求 → 检查有没有 tool_calls → 有就执行工具 → 把结果作为role: tool的消息追加回去 → 再发一次请求 → 直到模型不再调工具输出最终回答。import json import os from openai import OpenAI client OpenAI( api_keyos.getenv(TAOTOKEN_API_KEY), base_urlhttps://taotoken.net/api ) TOOLS [...] # 上面定义的三个 schema def get_weather(city: str, date: str None) - str: # 这里替换成你真实的气象 API 调用 return f{city}今天晴气温 18-26 摄氏度适合出行。 def calculate(expression: str) - str: # 生产环境请用安全求值不要直接 eval allowed set(0123456789-*/(). ) if not set(expression) allowed: return 表达式包含非法字符 try: return str(eval(expression)) except Exception as e: return f计算失败: {e} def web_search(query: str, top_k: int 3) - str: # 替换成你的搜索 API return f关于「{query}」的前 {top_k} 条结果... TOOL_MAP { get_weather: get_weather, calculate: calculate, web_search: web_search, } def run_agent(user_input: str, max_turns: int 5): messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_input}, ] for turn in range(max_turns): resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolsTOOLS, tool_choiceauto, ) msg resp.choices[0].message messages.append(msg) if not msg.tool_calls: return msg.content for tc in msg.tool_calls: fn_name tc.function.name try: args json.loads(tc.function.arguments) except json.JSONDecodeError: args {} fn TOOL_MAP.get(fn_name) result fn(**args) if fn else f未知工具: {fn_name} messages.append({ role: tool, tool_call_id: tc.id, content: str(result), }) return 达到最大轮次任务未完成跑一下run_agent(北京今天天气怎么样再帮我算一下 (128)*3)你会看到模型先调天气工具再调计算器最后把两个结果合并成一段自然语言回答。这就是一个最小可用的 Agent 调用循环。max_turns这个参数很重要它是防止死循环的保险丝。模型偶尔会陷入“调工具→不满意→再调”的循环设个上限能避免请求无限发下去烧钱。5. 常见报错排查401、local proxy failed 与 reading choices这一节按真实报错来你遇到哪个直接对号入座。401 Unauthorized九成是 Key 的问题。先确认环境变量有没有生效echo $TAOTOKEN_API_KEY看输出对不对。如果 Key 是对的检查请求头格式必须是Authorization: Bearer sk-xxxBearer 后面有个空格少了空格也会 401。还有一种情况是 Key 被复制时带了换行或空格用strip()处理一下。local proxy failed / connection error这类报错通常是网络层的问题。先确认 base_url 写对了是https://taotoken.net/api而不是别的。如果你在公司内网检查是不是有网络策略拦截了外部请求。另外超时时间设长一点函数调用因为要等模型推理响应比普通对话慢默认 10 秒可能不够设 60 秒比较稳。reading choices of undefined这个报错说明resp.choices是 undefined也就是响应结构和你预期的不一样。最常见的原因是请求根本没成功返回的是一个错误对象但你直接去取choices了。加一层判断if not resp.choices: print(响应异常:, resp) return 请求失败还有一种可能是模型 ID 写错了服务端返回了错误信息但没抛异常。打印完整响应体就能看到真实原因。tool_calls 为空但模型回答了说明模型没走函数调用直接自己编了答案。检查两点一是tool_choice是不是设成了none二是 system prompt 里有没有明确要求“必须用工具”。有时候模型觉得问题太简单就懒得调工具了这时候在 prompt 里加一句“任何涉及实时数据的问题都必须调用工具”能改善。arguments 解析失败模型返回的 JSON 字符串偶尔会有格式问题比如多一个逗号、少一个引号。加 try/except 兜底解析失败时把原始字符串传回去让模型重新生成或者直接返回错误让用户重试。OAuth / 鉴权相关报错如果你用的是 Claude Code 或类似工具报 OAuth 错误通常是工具的登录态过期了。这类工具和 API Key 是两套鉴权体系别混在一起。工具里配置 Base URL、Key、Model ID 三件套时确认 Key 是 API Key 而不是 OAuth token。报错关键词最可能原因快速修复401Key 错误或格式不对检查 Bearer 空格、Key 有无换行local proxy failed网络不通或 base_url 错确认地址、加长超时reading choices响应是错误对象打印完整 resp 再取字段tool_calls 为空模型没走工具改 tool_choice、强化 promptarguments 解析失败JSON 格式瑕疵try/except 重试6. 从能跑到好用把 Agent 接到你的真实业务里跑通 demo 只是起点真正难的是让它稳定处理真实用户的乱七八糟输入。我给你几个实战建议。第一工具执行一定要加超时和重试。天气 API 挂了、搜索接口限流了这些都会让 Agent 卡住。给每个工具函数包一层重试逻辑失败三次就返回一个友好的错误信息让模型决定是换个方式问还是告诉用户稍后再试。第二参数校验不能省。模型抽出来的参数不一定合法比如城市名写成“北京市朝阳区”、日期写成“明天”。在工具函数入口做一层归一化把“明天”转成具体日期把“北京市”转成“北京”。这层处理能大幅降低工具调用失败率。第三控制工具数量。我见过有人一口气定义二十个工具结果模型选择困难经常调错。建议单次对话暴露的工具不超过 8 个多了就做分组或动态加载。MCP 那种动态发现工具的架构适合大型系统小项目硬编码几个工具反而更稳。第四日志要打全。每次工具调用的入参、出参、耗时都记下来出问题时能快速定位是模型抽错参数还是工具执行失败。我一般会在run_agent里加一个trace列表把每一轮的tool_calls和结果都存进去调试时一目了然。第五安全边界要清晰。计算器工具千万别直接eval用户输入我上面给的字符白名单是最低要求。涉及写操作的工具下单、发邮件、改数据一定要加人工确认环节别让模型自主执行。函数调用的能力越强越要管住它的手。如果你想把 Agent 能力接到长期运行的编码或自动化任务里可以考虑用 Coding Plan 这类方案来管理调用配额和模型切换。验证模型函数调用能力时模型对话页面能快速试不同模型的表现。接入文档里有完整的参数说明和示例遇到协议细节问题查文档比搜博客靠谱。最后说个心态问题Agent 不是一次写完就完美的它是调出来的。先让它在天气、计算、搜索这三个场景跑顺再逐步加你的业务工具。每加一个工具就用十几条真实用户问法测一遍看模型抽参数准不准、该不该调它。这个过程没有捷径但跑通之后你就有了一个真正能干活而不只是聊天的 AI 智能体。
返回列表