资讯动态

零基础搭建AI Agent:深入ReAct循环与工具调用实战

发布时间:2026/8/30 9:15:31 来源:尧图企业网站定制
AI Agent 是当前 AI 应用开发中最值得关注的方向之一。很多人第一次接触 Agent 开发时会以为它只是把大模型 API 包装一层实际上真正的 Agent 是一个“感知、决策、行动、观察”的循环。本文面向零基础开发者不需要提前掌握 LangChain也不需要在第一天研究复杂框架只要有 Python 基础就能从零搭建一个会调用工具的 Agent并理解背后的 ReAct 机制。读完这篇文章后你可以独立完成一个小型智能客服 Agent 的搭建、验证和排查也知道真实项目中应该往哪个方向扩展。整篇文章会围绕一条主线展开先理解 Agent 的工作原理再准备环境然后写最小代码实现工具调用闭环接着用 Mock 模式和真实模型分别验证最后补充常见故障排查和项目化建议。1. AI Agent 到底是什么从一次 API 调用到循环决策初学者最容易犯的错误是把“大模型对话”和“Agent”混为一谈。对话只是 Agent 的表面形态真正决定 Agent 能力的是它能不能自主完成多步决策。1.1 一个通俗比喻Agent 是“会查资料的实习生”想象你找了一位实习生处理问题。实习生首先听清楚你的诉求如果发现自己不知道答案他会去查文档、查系统、算数据拿到结果后再向你汇报。Agent 的工作方式与此非常接近大模型相当于实习生的大脑工具相当于他能使用的电脑、表格和资料库而“循环”则保证他不会在第一步失败后就停下来。这个比喻可以帮助你建立直觉Agent 并不神秘它就是一个被赋予“调用外部能力”的大模型程序。它是否可以执行有用的任务取决于你给了它多少真实可用的工具。1.2 Agent 与普通 Chat API 调用的核心差异传统 Chat API 的调用方式是“一问一答”用户输入一句话模型返回一段文本。这种模式适合闲聊、翻译、文本总结但无法完成“查一下订单再计算退款金额”这种需要多步操作的任务。Agent 的关键差异在于模型不再只输出文本而是可以输出“工具调用指令”。你的程序需要负责执行这些指令。执行结果会作为新消息重新交给模型驱动它继续推理。所以 Agent 的最小单元不是“一次对话”而是“一个循环”。也正因为如此Agent 开发的重点从“怎么把 prompt 写得更漂亮”转移到了“怎么把工具设计得更可靠、把上下文管理得更清楚、把循环控制得更稳定”。1.3 ReAct 循环思考、行动、观察、再思考当前大多数 Agent 采用的模式叫 ReAct即 Reason and Act。一个完整的 ReAct 循环包含四步思考Reason模型阅读用户问题结合已有信息决定下一步。行动Act模型输出一个工具调用请求比如get_current_time。观察Observe程序执行工具并把结果返回给模型。再思考模型根据观察结果决定是否继续调用工具还是生成最终答案。如果把这个循环画成代码逻辑就是for循环 if判断。下面这个伪代码虽然简单但它揭示了所有 Agent 框架的共同内核while True: response llm.chat(messages, toolstools) if response.has_tool_calls(): for call in response.tool_calls: result execute_tool(call) messages.append(tool_message(call.id, result)) else: return response.content理解了这段伪代码你就理解了 80% 的 Agent 开发。1.4 Agent 常用术语速查表在学习代码之前先把下面这些术语和它们的关系搞清楚术语一句话解释在本项目中的位置LLM大语言模型Agent 的推理核心POST /chat/completions请求的模型Tool模型可以调用的外部能力get_current_time、calculatorTool Calling模型输出结构化工具调用指令的能力响应中的tool_calls字段System Prompt给模型设定的角色和规则主循环里的 system 消息Context Window模型一次能看到的 token 数量由模型服务决定使用时要节省ReAct思考、行动、观察交替进行的推理模式本文主循环的实现思想MemoryAgent 保存历史信息的能力短期靠 messages长期靠向量库不要急着把所有术语都背下来。你先记住Agent 是循环工具是能力模型是大脑上下文是记忆。后续代码会逐个验证这些概念。2. 准备最小开发环境Python 虚拟环境与 OpenAI 兼容接口零基础开发 Agent 的常见误区是“先把几十个框架都装一遍”。实际上最轻量、最透明的做法是直接用 Python 脚本调用 OpenAI 兼容接口自己写一个只有几十行代码的循环。2.1 环境要求与依赖清单本文的示例代码依赖很少适合作为学习起点。项目要求说明Python3.9 及以上建议 3.10 或 3.11低版本会缺少部分类型语法requests2.31 及以上用于调用模型 HTTP 接口模型服务OpenAI 兼容 Chat Completions 接口可以是本地服务也可以是团队的内部网关这里选择“OpenAI 兼容接口”而不是绑定某个厂商 SDK原因有两个OpenAI 兼容接口已经成为事实上的行业标准很多本地部署框架和云服务都支持这种调用方式。零基础开发者可以直接看到 HTTP 请求和响应理解 Agent 循环的每一步而不是被 SDK 封装隐藏细节。2.2 创建虚拟环境并安装依赖打开终端创建一个项目目录mkdir agent_workshop cd agent_workshop python3 -m venv .venv source .venv/bin/activateWindows 环境下激活命令不同python -m venv .venv .venv\Scripts\activate然后创建依赖文件requirements.txtrequests2.31.0安装依赖pip install -r requirements.txt安装完成后确认环境没有问题python -c import requests; print(requests.__version__)能输出版本号说明环境已经可用了。2.3 项目目录结构一个可维护的 Agent 项目至少要把“配置”“工具”“循环”“入口”分开。初学者建议按下面这个结构组织agent_workshop/ ├── .venv/ ├── requirements.txt ├── config.py # 读取环境变量和配置 ├── tools.py # 工具定义和工具实现 ├── agent.py # Agent 主循环 └── main.py # 命令行入口这样做的好处是工具越来越多时不需要改动主循环更换模型服务时只需要修改配置排查问题时也能快速定位是哪一层出了问题。2.4 配置文件把 API 地址、模型名、密钥与代码分离很多初学者把模型地址和密钥直接写在代码里这是不推荐的做法。密钥一旦提交到代码仓库就可能造成泄露模型地址写死之后切换环境也会非常痛苦。推荐建立一个config.py从环境变量读取配置import os def get_config(): config { # 如果使用本地兼容服务可以填写本地地址 api_key: os.getenv(OPENAI_API_KEY, sk-local-demo), base_url: os.getenv(OPENAI_BASE_URL, http://127.0.0.1:8000/v1), model: os.getenv(OPENAI_MODEL, qwen2.5-7b-instruct), # 学习阶段先打开 mock跑通链路后再关闭 use_mock: os.getenv(USE_MOCK, true).lower() true, max_iterations: int(os.getenv(MAX_ITERATIONS, 5)), temperature: float(os.getenv(TEMPERATURE, 0.2)), max_tokens: int(os.getenv(MAX_TOKENS, 512)), timeout: int(os.getenv(TIMEOUT, 60)), } return config这里有几个设计意图use_mock是学习模式开关没有模型服务时也可以体验完整循环。base_url使用127.0.0.1:8000作为默认值适合连接本地部署的可兼容服务真实项目应改成团队网关地址。所有敏感信息和环境差异都通过环境变量注入代码本身保持纯净。在终端可以这样设置环境变量export OPENAI_API_KEY你的密钥 export OPENAI_BASE_URLhttp://127.0.0.1:8000/v1 export OPENAI_MODELqwen2.5-7b-instruct export USE_MOCKtrueWindows PowerShell 用$env:OPENAI_API_KEY...的形式。2.5 为什么推荐先使用 Mock 模式真实模型服务不是任何时候都可用初学者也不一定马上有接口权限。如果第一步就卡在“连接服务器失败”很容易打乱学习节奏。Mock 模式的意思是程序不真正调用模型而是按照预设好的步骤依次返回“调用时间工具”“调用计算工具”“生成最终答案”三条响应。这样我可以先验证主循环代码是否正确再接入真实模型。Mock 模式不是假验证它验证的是 Agent 循环的骨架工具调用能否被解析、工具结果能否回填、最终答案能否生成。语义能力要靠真实模型来验证但循环逻辑用 Mock 就能跑通。3. 实现一个会调用工具的最小 Agent工具、循环与代码这一部分会写四个文件工具定义、工具实现、Agent 主循环、命令行入口。代码不追求复杂但会把关键链路完整走通。3.1 第一步定义工具元信息让模型知道有哪些能力模型不会自动知道你写了哪些 Python 函数。要让模型调用工具必须先把工具的“说明书”传给模型这就是工具元信息。在tools.py中定义TOOLS列表TOOLS [ { type: function, function: { name: get_current_time, description: 获取当前日期和时间适合回答时间相关问题, parameters: { type: object, properties: {}, required: [] } } }, { type: function, function: { name: calculator, description: 执行四则运算和乘方适合数学计算, parameters: { type: object, properties: { expression: { type: string, description: 要计算的数学表达式例如 (12 8) * 3 } }, required: [expression] } } }, { type: function, function: { name: lookup_doc, description: 查询内部文档知识库适合产品规则、常见配置问题, parameters: { type: object, properties: { keyword: { type: string, description: 搜索关键词 } }, required: [keyword] } } } ]这里的重点是name和description。name必须与后面的 Python 函数名一致description写得越清楚模型越能在正确的场景下调用它。3.2 第二步实现真正的工具函数工具元信息告诉模型“可以调用什么”工具函数才是真正执行逻辑的地方。继续在tools.py中实现import ast import datetime import operator _OPERATORS { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.Pow: operator.pow, } def _safe_eval(node): if isinstance(node, ast.Expression): return _safe_eval(node.body) if isinstance(node, ast.Constant): if isinstance(node.value, (int, float)): return node.value raise ValueError(不是数值) if isinstance(node, ast.BinOp): left _safe_eval(node.left) right _safe_eval(node.right) op _OPERATORS[type(node.op)] return op(left, right) if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub): return -_safe_eval(node.operand) raise ValueError(不支持的表达式) def get_current_time(): return datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S) def calculator(expression): if len(expression) 200: return error: 表达式过长 try: tree ast.parse(expression, modeeval) return str(_safe_eval(tree)) except Exception as exc: return ferror: {exc} def lookup_doc(keyword): doc { 退款: 用户下单后 30 分钟内可申请无理由退款, 发票: 电子发票会在订单完成后 24 小时内发送到用户邮箱, API: 查询接口使用 GET /api/v1/orders请求头需要携带 X-Token } for key, value in doc.items(): if key in keyword: return value return 没有找到相关文档这里特别说明calculator的实现。有些教程会直接使用 Python 的eval但实际生产中这是非常危险的做法用户输入一旦包含恶意代码就可能造成安全问题。本文使用ast模块做白名单解析只允许数值、四则运算、乘方和一元负号不认识的节点直接抛异常。常用工具函数映射表写在agent.py中运行时根据模型返回的工具名称调用TOOL_MAP { get_current_time: get_current_time, calculator: calculator, lookup_doc: lookup_doc, }3.3 第三步实现 Agent 主循环agent.py是整个项目的核心。它要完成四件事把用户问题转成 messages 结构。调用模型接口。判断返回结果中有没有tool_calls。执行工具并把结果回填进入下一轮。先实现一个负责“调用模型接口”的函数同时兼容 Mock 和真实模式。Mock 响应如下def mock_chat(messages): tool_result_count sum(1 for m in messages if m.get(role) tool) if tool_result_count 0: return { choices: [{ message: { role: assistant, content: None, tool_calls: [{ id: call_time, type: function, function: { name: get_current_time, arguments: {} } }] } }] } if tool_result_count 1: return { choices: [{ message: { role: assistant, content: None, tool_calls: [{ id: call_calc, type: function, function: { name: calculator, arguments: {\expression\: \(12 8) * 3\} } }] } }] } return { choices: [{ message: { role: assistant, content: 当前时间已获取计算结果为 60。Mock 模式验证的是工具调用闭环实际语义由真实模型决定。 } }] }这个 Mock 模式的逻辑是前两轮分别返回两个工具调用第三轮返回最终答案从而完整走一遍 Agent 循环。真实调用部分的实现import json import requests from tools import TOOLS def chat_once(messages, config): if config.get(use_mock): return mock_chat(messages) url config[base_url].rstrip(/) /chat/completions payload { model: config[model], messages: messages, tools: TOOLS, tool_choice: auto, temperature: config.get(temperature, 0.2), max_tokens: config.get(max_tokens, 512), } try: resp requests.post( url, headers{Authorization: fBearer {config[api_key]}}, jsonpayload, timeoutconfig.get(timeout, 60), ) resp.raise_for_status() return resp.json() except requests.exceptions.Timeout: raise RuntimeError(f模型服务请求超时{url}) except requests.exceptions.ConnectionError: raise RuntimeError(f无法连接模型服务{url}) except requests.exceptions.HTTPError as exc: status exc.response.status_code if exc.response is not None else unknown body exc.response.text[:500] if exc.response is not None else raise RuntimeError(f模型服务返回 HTTP {status}{body})然后是完整的 Agent 循环def run_agent(user_question, config): messages [ { role: system, content: 你是智能客服助手。如果需要实时信息先调用工具根据工具结果组织最终回答。 }, { role: user, content: user_question } ] max_iterations config.get(max_iterations, 5) for step in range(1, max_iterations 1): print(f[step {step}] 调用模型 ...) data chat_once(messages, config) msg data[choices][0][message] messages.append(msg) tool_calls msg.get(tool_calls) if not tool_calls: answer msg.get(content) or 模型没有返回可用的回答。 print(f[done] {answer}) return answer for call in tool_calls: fn call.get(function, {}) name fn.get(name, ) arguments fn.get(arguments, {}) try: args json.loads(arguments) if arguments else {} except json.JSONDecodeError: args {} print(f[warn] 工具参数解析失败{arguments}) if name in TOOL_MAP: try: result TOOL_MAP[name](**args) except Exception as exc: result ferror: 工具执行失败 {exc} else: result ferror: 未知工具 {name} print(f[tool] {name}({args}) - {result}) messages.append({ role: tool, tool_call_id: call.get(id), content: str(result), }) print([warn] 达到最大迭代次数停止。) return 抱歉问题比较复杂请稍后再试或补充更多信息。这个循环的关键点有三个每次调用模型后都要把 assistant 的消息追加到messages否则模型不知道自己之前做过什么。工具执行结果作为roletool的消息回填并且tool_call_id必须对应 assistant 返回的调用 ID这是协议要求。用max_iterations限制循环次数避免模型陷入无限调用工具的死循环。3.4 完整项目代码入口文件最后创建main.pyfrom agent import run_agent from config import get_config def main(): config get_config() mode MOCK if config.get(use_mock) else REAL print(fAgent 启动当前模式{mode}) while True: try: question input(user ).strip() except (EOFError, KeyboardInterrupt): break if not question: continue if question.lower() in {exit, quit}: break answer run_agent(question, config) print(fassistant {answer}) if __name__ __main__: main()3.5 关键设计说明为什么用 tool_call_id 回填在工具调用的消息协议中模型返回的工具调用都有一个唯一 ID比如call_time。当程序执行完工具后回填消息必须带tool_call_id用来告诉模型“这次工具结果对应刚才哪一个调用请求”。如果忽略这个 ID很多模型服务会报错或者模型会分不清结果属于哪一步。这是 Agent 开发中非常隐蔽的一个坑。4. 运行验证与结果分析Mock 模式先跑通真实模型再确认代码写完之后先不要急着接入真实模型。建议按照“Mock 模式先跑通真实模型再确认”的顺序进行验证。4.1 Mock 模式运行效果在项目根目录执行export USE_MOCKtrue python main.py输入任意问题比如“现在几点了”预期输出类似Agent 启动当前模式MOCK user 现在几点了 [step 1] 调用模型 ... [tool] get_current_time() - 2026-01-20 10:24:15 [step 2] 调用模型 ... [tool] calculator({expression: (12 8) * 3}) - 60 [step 3] 调用模型 ... [done] 当前时间已获取计算结果为 60。Mock 模式验证的是工具调用闭环实际语义由真实模型决定。 assistant 当前时间已获取计算结果为 60。Mock 模式验证的是工具调用闭环实际语义由真实模型决定。请仔细观察输出中的三行[step 1]模型要求调用时间工具。[step 2]模型要求调用计算工具。[step 3]模型生成了最终回答。这说明循环已经被完整走通工具调用被解析工具结果被回填模型拿到了回填数据输出了最终答案。如果这三步没有出现说明代码有逻辑问题请先检查agent.py中的消息追加顺序。4.2 接入真实 OpenAI 兼容服务的步骤Mock 跑通后关闭 Mock并设置真实的模型服务信息export USE_MOCKfalse export OPENAI_API_KEY你的密钥 export OPENAI_BASE_URLhttp://127.0.0.1:8000/v1 export OPENAI_MODEL你使用的模型名 python main.py这里再次强调OPENAI_BASE_URL可以是本地部署模型服务暴露的地址也可以是团队内部的统一网关地址关键是这个地址必须提供 OpenAI 兼容的 Chat Completions 接口。输入一个需要时间工具的问题user 帮我查一下当前时间 [step 1] 调用模型 ... [tool] get_current_time() - 2026-01-20 10:30:05 [step 2] 调用模型 ... [done] 当前时间是 2026-01-20 10:30:05。 assistant 当前时间是 2026-01-20 10:30:05。如果模型认为不需要调用工具它也会直接回答这是正常行为。真实模型的判断取决于系统提示词、工具描述和问题本身。4.3 三步验证法触发、回填、收尾接入真实模型后建议不要再“凭感觉”测试而是用固定步骤验证触发输入一个明确需要工具能力的问题检查是否触发对应工具。回填检查工具执行结果是否作为roletool消息返回给模型。收尾检查模型是否基于工具结果生成了最终回答而不是复述工具输出。把这三个步骤写成一张简单的验证表验证点输入示例预期表现时间工具“现在几点”出现get_current_time调用计算工具“12 加 8 乘以 3 等于多少”出现calculator调用文档工具“退款政策是什么”出现lookup_doc调用综合流程“查一下时间并计算今天日期加 10 天”出现多个工具调用并最终回答错误输入输入空字符串程序不崩溃提示重新输入4.4 在真实项目中观察中间过程当前代码用print打印了每一步的工具调用日志。真实项目中不建议直接使用print而应该使用结构化日志把每一步的模型响应、工具调用、耗时、token 消耗都记录下来方便事后排查。推荐记录的最小字段包括{ session_id: xxx, step: 2, model: qwen2.5-7b-instruct, tool_name: calculator, tool_args: {expression: (12 8) * 3}, tool_result: 60, latency_ms: 450, input_tokens: 320, output_tokens: 45 }有了这份日志出现问题时才能回答出三个关键问题模型当时看到了什么、它决定做什么、工具返回了什么。5. 常见失败场景与排查路径从报错到稳定运行Agent 开发最大的挑战不是“跑出一次成功结果”而是“在失败时能快速定位问题”。这一部分列出最常见的故障和排查方法。5.1 常见问题对照表问题现象常见原因检查方式处理建议请求返回 401API Key 未配置或错误查看环境变量是否设置确认密钥正确并重新设置环境变量请求返回 404接口路径不对在浏览器访问base_url /chat/completions确认地址是否包含/v1请求超时模型服务负载高或网络慢查看服务端日志和耗时调大 timeout或者换更快模型模型不调用工具工具描述不清晰或模型不支持查看模型返回内容优化描述或换支持工具调用的模型工具参数解析失败模型输出非法 JSON打印原始 arguments增加异常处理使用更强模型工具结果太长返回内容超过上下文窗口查看 token 统计截断工具结果只保留关键字段Agent 一直循环模型反复调用同一个工具打印每步工具调用日志调低max_iterations或在提示词中限制Mock 与真实结果不一致只是混淆了两种模式查看USE_MOCK值学习阶段用 Mock逻辑验证用真实模型5.2 按优先级排查输入、配置、网络、模型、解析、循环出现问题时建议从低到高逐层排查不要一开始就怀疑模型能力。第一步检查输入。用户问题是否为空期望触发的工具是否与问题匹配。如果用户问“现在几点”模型调用计算器那不是循环的问题而是工具描述或者模型理解的问题。第二步检查配置。OPENAI_BASE_URL是否拼写正确OPENAI_MODEL是否和实际部署模型一致USE_MOCK是否意外打开。第三步检查网络与接口。使用 curl 命令直接测试接口curl http://127.0.0.1:8000/v1/chat/completions \ -H Authorization: Bearer sk-local-demo \ -H Content-Type: application/json \ -d {model:qwen2.5-7b-instruct,messages:[{role:user,content:hello}]}如果 curl 返回异常说明问题在模型服务本身而不是 Agent 代码。第四步检查模型能力。不是所有模型都支持工具调用。如果你的模型不支持tool_calls就要考虑更换模型或者退回到“用文本协议解析工具调用”的旧方案。第五步检查解析与循环。把tool_calls和arguments打印出来确认模型返回的结构是否合法。如果arguments是非法 JSON程序要能容错而不是直接崩溃。第六步检查成本与上下文。如果每轮都把完整历史回传上下文会越来越大最终触发长度限制。此时需要做消息截断或摘要压缩。5.3 temperature、max_tokens、max_iterations 该怎么设置这几个参数直接影响 Agent 的稳定性建议按场景调整。参数建议值调大的影响调小的影响temperature0.2回答更有创造力但工具选择更容易出错更稳定适合工具调用和结构化输出max_tokens512能输出更长回答但成本更高输出更快但可能被截断max_iterations5能处理更复杂任务但成本和耗时更高响应更快但复杂任务容易失败timeout60容忍慢模型快速失败便于告警对于需要频繁调用工具的 Agenttemperature建议保持在 0 到 0.3 之间。工具调用本质上是“准确性”任务不需要太多随机性。5.4 上下文膨胀与成本控制Agent 循环每执行一步messages都会增加新的 assistant 消息和 tool 消息。一次复杂任务可能产生几千 token 的历史记录。如果不加控制很快就会把上下文窗口撑满。常见的控制手段有以下几种只保留最近 N 轮消息。对工具结果进行截断比如只返回前 500 个字符。对历史对话做摘要用摘要消息替代原始历史。对每轮 token 消耗做预算超过阈值强制停止。在本文的最小项目中messages在每次调用run_agent时都会重建所以不存在跨会话记忆膨胀问题。但一旦你开始做多轮对话就必须考虑上下文管理。6. 从示例项目到真实应用框架选型、记忆、评估与学习路线示例项目证明了核心原理但真实业务中的 Agent 还需要考虑记忆、评估、安全、监控等问题。6.1 什么时候可以不写循环直接上成熟框架你已经实现了最小循环这非常好。但真实项目中不建议所有团队都从零开始写 Agent 循环。成熟框架能解决一些通用问题LangChain提供大量模型封装、工具集成和链式调用能力。LangGraph把 Agent 的状态流转用图结构管理适合复杂多步骤任务。Dify、Coze 等平台适合快速搭建业务 Agent不需要写太多代码。选择框架的原则是业务复杂度低时直接用脚本或轻量框架业务复杂度高需要分支、并行、人工审核时再引入图编排框架。不要为了用框架而用框架尤其是当你还理解不了框架背后的循环逻辑时自己写最小循环反而更可控。6.2 记忆从 messages 到向量检索本文示例中每次提问都是一个独立会话。真实客服场景中用户可能连续问多轮问题Agent 必须记住上文。短期记忆可以直接维护messages列表把历史对话传给模型。这里的问题是上下文会膨胀需要做截断或摘要。长期记忆通常借助向量数据库把用户历史偏好、文档内容编码成向量在需要时检索出相关片段放回上下文。流程是清洗文本切分成合适的片段。用 Embedding 模型生成向量写入向量库。用户提问时先做相似度检索。把检索到的片段拼进 system 或 user 消息。这种方式适合内部知识库问答、智能客服、文档分析等场景。6.3 评估用测试集代替“肉眼感觉”很多开发者在本地测试 Agent 时觉得“效果不错”但上线后就被各种真实输入击败。原因是本地只验证了少数手工用例。推荐用“测试集 指标”的方式来评估 Agent。测试集至少包含三部分单轮工具调用如“查询当前时间”。多轮工具调用如“查一下订单金额然后计算退款比例”。异常输入如工具参数非法、模型重复调用工具、上下文超长。评估指标可以包括工具调用准确率该调的时候有没有调不该调的时候有没有乱调。参数正确率工具参数是否符合预期。最终回答正确率最终回答是否基于工具结果。耗时与成本平均每轮消耗时间和 token。把测试集固化到项目里每次修改 prompt 或工具描述后都跑一遍避免“修好一个问题带崩另一个场景”。6.4 生产环境必须补齐的能力清单从示例项目到生产上线还有很长的路要走。下面这份清单可以当作发布前的检查项能力项说明配置外置化密钥、模型地址、参数不能写死在代码里日志与追踪记录完整调用链、耗时、token、工具结果限流与预算防止单个用户或单个任务消耗过多资源工具权限控制不是所有工具对所有用户开放工具输入校验防止恶意参数、路径穿越、危险表达式敏感信息过滤日志和响应中不能出现密钥、手机号等敏感数据人工审核兜底高风险场景需要人审评估回归每次变更后跑测试集监控告警模型服务错误率、耗时、成本异常要能触发告警灰度发布与回滚新 prompt 或新工具上线要能快速回退6.5 给零基础读者的 5 天练习路线“5 天从入门到精通”是不现实的但“5 天跑通基础链路并做出一个可用的小项目”是可以做到的。下面这个路线比较适合零基础读者天数练习目标建议任务第 1 天理解 ReAct跑通 Mock

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价