
想弄清楚 AI Agent 开发的人多半已经经历过这样一个阶段Prompt 写了厚厚一叠模型也换了好几个但在真实业务场景里Agent 仍然会“一本正经地胡说八道”或者在执行到第三步时直接把上下文丢掉甚至把不该调用的工具给调了。如果你正卡在这个位置这篇教程就是为你准备的。很多人对 AI Agent 有一个误解以为它只是“多轮 Prompt 大模型调用”。但从实际工程来看Agent 开发真正考验的是另一套能力——任务拆解、工具编排、状态管理、权限隔离和可观测性。这套能力决定了你写的 Agent 是只能在演示里跑通的 Demo还是能放进企业业务里长期运行的“智能体”。这篇文章我会从一个最小可运行的 Agent 出发逐步拆解 Agent 开发的核心环节最后落到企业级部署必须考虑的架构问题。读完你会有四条收获理解 AI Agent 的运行逻辑而不是停留在“调 API”层面。能手写一个带工具调用能力的最小 Agent不依赖任何重框架。知道企业级 Agent 与教学 Demo 的差异在哪里。拿到一套可以直接复用的工程实践和排错思路。1. AI Agent 开发到底难在哪里先给一个明确的判断Agent 开发的核心瓶颈不是模型而是工程化。单纯让大模型“聊天”并不难难的是让大模型“负责完成一件事”。聊天只要生成文字而 Agent 需要生成行动。什么算行动调用 API 查订单、写入数据库、给用户推送消息、拉起另一个系统的工作流。一旦涉及行动就会出现几个传统软件开发里并不常见的问题模型下一步做什么是概率性的而不是确定性的。模型会编造工具参数比如把用户 ID 写成一个不存在的字符串。多轮工具调用之后上下文可能丢失或偏离原始目标。工具数量一旦超过 10 个模型选错工具的概率明显上升。生产环境里你无法完全控制模型的所有行为只能通过架构去约束。这些问题不是换一个大模型就能解决的它们需要在 Agent 的框架设计层面处理。这也是为什么“会写 Prompt”和“会做 Agent 开发”是两种完全不同的能力。前者是在跟模型对话后者是在围绕模型构建一套带约束的自动执行系统。2. AI Agent 核心概念与运行逻辑2.1 Agent 的本质是一个循环先放下那些复杂的术语。AI Agent 最核心的运行模式是一个“思考 → 调用工具 → 观察结果 → 再思考”的循环。完整过程可以描述为接收用户目标。大模型根据目标和已有信息决定下一步动作直接给出回答或者调用某个工具。如果调用工具则执行对应函数把返回值交给模型。模型把工具结果纳入上下文继续下一步决策。直到模型认为目标已经完成输出最终答案。理解这个循环是 Agent 开发的第一个分水岭。很多新手写的“Agent”其实只有第一步和最后一步中间没有工具执行和结果反馈自然也就没有“智能”可言。2.2 四大核心组件从工程抽象的角度看一个 Agent 系统由四类组件组成。组件作用类比LLM负责理解和决策员工的大脑Tools让 Agent 能影响外部系统员工的双手Memory保存对话历史和关键信息员工的笔记本Planner/Runner控制任务分解和循环执行项目经理的排期表这里的 Tools 是 Agent 开发里最值得琢磨的部分。所谓 Tool不只是普通的 API 封装函数而是要附带一段“使用说明”给模型看。大模型就是靠这个说明判断“什么场景该用哪个工具”。工具说明写得越准确模型的调用正确率越高。这也是 Agent 开发里“提示词工程”真正发挥作用的地方——它不是用在系统 Prompt 上而是用在工具描述上。2.3 Function Calling 是关键机制Function Calling函数调用是当前大多数 Agent 技术方案采用的标准机制。模型在生成普通文本的同时可以输出一个结构化 JSON里面包含工具名称和参数。之后由你的业务代码去真正执行这个函数再把结果拼回对话上下文。如果模型没有选择调用任何函数它输出的就是最终回复。所以判断一次 Agent 执行是否结束最直接的标志就是这一轮返回结果里是否包含 tool_calls 字段。2.4 Agent 与普通 API 调用的区别普通 API 调用是“输入 → 输出”的短链路一次请求得到一个结果。Agent 则是“输入 → 多轮内部调用 → 输出”的长链路中间可能穿插多次工具执行而且每轮决策都依赖上一轮的结果。这也是为什么 Agent 的调试比普通接口开发困难很多你不仅要看大模型的最终输出还要看它每一轮为什么选择这个工具、参数是否正确、返回结果是否被正确理解。3. 企业级 Agent 与 Demo Agent 的分水岭如果一个 Agent 只用于教学演示你可以容忍它偶尔出错甚至可以手动在对话里纠正它。但企业级 Agent 的要求完全不同它直接面对真实用户和真实系统错误是有成本的。企业级 Agent 与 Demo Agent 的核心差异可以用一张表看清楚维度Demo Agent企业级 Agent工具权限全量放开按角色最小授权错误容忍度允许重试需要兜底和降级可观测性打印日志全链路追踪 审计上下文管理全量塞给模型截断、摘要、长期记忆评估方式人工看结果测试集回归 指标对比安全边界几乎不考虑输入过滤、工具白名单、参数校验从实际项目经验看企业级 Agent 最容易被忽略的环节是“工具调用的参数校验”。大模型生成的参数看起来格式正确但值可能是乱来的。比如查订单接口模型传入了一个“2024-13-45”这样的日期。所以在 Agent 的工程实现里每个工具的入参都必须有独立的业务层校验不能假设模型返回的参数永远正确。4. 环境准备与前置条件工欲善其事必先利其器。本文的示例采用 Python 编写因为 Agent 开发相关的生态最成熟的语言仍然是 Python。4.1 运行环境操作系统Windows 10/11、macOS 或 Linux 均可。Python 版本建议 3.10 及以上具体以实际环境为准本文代码基于通用 Python 语法编写。包管理使用 venv 或 conda 创建独立虚拟环境。模型接口本文使用 OpenAI SDK 的通用调用方式可对接兼容该接口的模型服务。请根据你所在团队的技术选型配置合法的模型服务访问方式。环境准备的最小命令mkdir agent-demo cd agent-demo python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate pip install openai如果你希望完全本地化运行也可以选择 Ollama 等本地推理方案并暴露 OpenAI 兼容接口。需要注意的是本地小参数模型的工具调用成功率通常低于云端大模型做教学演示可以做生产级应用时建议根据需要评估模型能力。4.2 依赖说明本文两个核心依赖openai用于调用大模型接口并解析 tool_calls。标准库 json、datetime、logging用于工具参数解析、日期处理和日志记录。这里刻意不引入 LangChain、LlamaIndex 等重量级框架目的是让你先看清 Agent 运行的最底层原理。框架确实能提升开发效率但如果连最基础的循环都没理解就一头扎进框架出了问题会非常被动。5. 从零手写一个最小 Agent先跑通再谈架构这一章我们实现一个真正能运行的最小 Agent。目标只有一个让 Agent 具备调用工具的能力并且跑通“思考 → 调用 → 观察 → 再思考”的完整循环。5.1 项目结构agent-demo/ ├── venv/ ├── main.py └── requirements.txtrequirements.txt 内容openai1.0.05.2 最小 Agent 核心代码在 main.py 中写入以下代码import json from openai import OpenAI # 初始化客户端 # 如果你使用 OpenAI 官方服务按合规要求配置 API Key # 如果你使用兼容 OpenAI 接口的本地或云端网关填对应的 base_url client OpenAI( api_keyyour-api-key, base_urlyour-openai-compatible-endpoint, # 例如本机推理服务的 /v1 地址 ) # 1. 定义工具 tools [ { type: function, function: { name: calculate, description: 执行四则运算输入一个算式字符串例如 12*75, parameters: { type: object, properties: { expression: { type: string, description: 要计算的数学表达式 } }, required: [expression] } } } ] # 2. 定义工具的实际执行函数 def calculate(expression: str) - dict: # 生产环境不要用 eval这里仅做最小示例 # 生产环境建议用白名单解析器或 ast 模块做安全校验 try: result eval(expression) return {success: True, result: result} except Exception as e: return {success: False, error: str(e)} # 工具分发 def dispatch_tool(name: str, arguments: str): args json.loads(arguments) if name calculate: return calculate(args[expression]) return {success: False, error: f未知工具: {name}} # 3. 核心循环 def run_agent(user_input: str, max_steps: int 5): messages [{role: user, content: user_input}] for step in range(max_steps): response client.chat.completions.create( modelyour-model-name, messagesmessages, toolstools, ) message response.choices[0].message messages.append(message) # 没有工具调用表示 Agent 已输出最终答案 if not message.tool_calls: return message.content # 执行每个工具调用 for tool_call in message.tool_calls: print(f[step {step 1}] 调用工具: {tool_call.function.name}, 参数: {tool_call.function.arguments}) result dispatch_tool(tool_call.function.name, tool_call.function.arguments) messages.append({ role: tool, tool_call_id: tool_call.id, content: json.dumps(result, ensure_asciiFalse) }) return 已达到最大执行步数任务可能未完成。 # 4. 运行测试 if __name__ __main__: answer run_agent(请计算 12345 * 6789 等于多少) print(最终答案:, answer)5.3 关键逻辑解释这段代码里最核心的设计有四个第一tools 列表是给模型看的“使用说明书”。模型不会直接执行你的函数它只负责输出“我想调用 calculate参数是 xxx”。真正执行的人是你的 dispatch_tool。第二messages 列表一直在累积。每次工具调用的结果都以 roletool 的身份追加进去模型下一轮才能“看到”工具返回了什么。第三循环终止条件有两个模型不再生成 tool_calls说明它认为已经有足够信息回答另一是达到 max_steps防止 Agent 陷入无限循环。第四temperature、max_tokens 这类参数这里没有设置因为在 Agent 场景下工具调用往往比创造性回答更重要一般建议把 temperature 调低如 0.2 或 0以减少随机性。但这里保持最小示例的简洁暂不展开。5.4 运行与验证python main.py预期输出类似[step 1] 调用工具: calculate, 参数: {expression: 12345*6789} 最终答案: 83810205注意真正的输出取决于模型的行为模型可能在第一轮就调用工具也可能先输出一段说明再调用工具。只要最终能看到“调用工具”的日志以及“最终答案”就说明这个最小 Agent 已经跑通了。如果运行失败优先检查三处base_url 和 api_key 是否配置正确。模型名称是否与你的模型服务匹配。模型是否支持 tool_calls / function calling 能力。6. 给 Agent 接入真实业务工具订单查询示例上一章的 calculate 工具只是验证流程接下来模拟一个更接近企业业务的场景用户询问订单状态Agent 需要调用订单查询 API。这个示例会体现三个工程要点工具描述要写清楚参数约束、工具内部要做参数校验、返回值要结构化。6.1 模拟订单工具import json import datetime # 模拟订单数据源 FAKE_ORDERS { A1001: {status: 已发货, eta: 2025-03-18, goods: 机械键盘}, A1002: {status: 待支付, eta: None, goods: 显示器支架}, } def query_order(order_id: str) - dict: # 参数校验模型可能传空字符串、None 或非法格式 if not order_id or not isinstance(order_id, str): return {success: False, error: 订单号不能为空} # 校验订单号格式A 4 位数字 if len(order_id) ! 5 or not order_id.startswith(A) or not order_id[1:].isdigit(): return {success: False, error: 订单号格式不正确应为 A 加 4 位数字} order FAKE_ORDERS.get(order_id) if not order: return {success: False, error: f未找到订单 {order_id}} return {success: True, data: order}对应的工具描述order_tool { type: function, function: { name: query_order, description: 根据订单号查询订单状态。订单号格式为 A 开头加 4 位数字例如 A1001。, parameters: { type: object, properties: { order_id: { type: string, description: 用户提供的订单号形如 A1001 } }, required: [order_id] } } }注意工具描述里特意写清了订单号格式。这不是多余的说明而是降低模型乱传参数概率的关键手段。模型不是数据库它对“订单号应该长什么样”没有概念只有你在描述里显式写清楚它才能生成符合格式的参数。6.2 组装新的工具列表tools [order_tool] def dispatch_tool(name: str, arguments: str): args json.loads(arguments) if name query_order: return query_order(order_idargs.get(order_id)) return {success: False, error: f未知工具: {name}}6.3 验证效果执行if __name__ __main__: answer run_agent(我想查一下订单 A1001 到哪了) print(最终答案:, answer)如果 Agent 正常执行它应该调用 query_order 工具然后根据返回结果告诉用户“订单 A1001 已发货预计 2025-03-18 送达商品是机械键盘”。这里真正容易踩坑的是用户消息里可能携带“订单号是A1001、帮我查一下”这种非标准表达。模型需要从自然语言里抽取订单号并填进工具参数。如果抽错了需要靠工具内部的校验逻辑兜底。所以 Agent 开发并不是“写一个函数让模型调用”那么简单工具自身的健壮性会直接决定 Agent 的可用性。7. 企业级 Agent 落地架构建议跑通最小示例之后距离企业级应用还有一段很长的路。这一章我给出一个相对完整的 Agent 架构分层方案每一项都是生产环境迟早要面对的问题。7.1 路由与编排层企业内通常不止一个 Agent可能有客服 Agent、数据分析 Agent、运维 Agent。用户请求进来之后第一层需要一个 Router 来决定把请求交给哪个 Agent或者哪个模型。这不是一个简单的 if-else实践中常用两种方式基于分类模型的路由用一个小模型判断用户意图。基于关键词与规则的路由适合意图边界清晰的场景。路由层的好处是隔离故障。假设数据分析 Agent 依赖的数据库抖动至少客服 Agent 还能正常工作。7.2 会话状态与记忆层生产环境的 Agent 不能每次请求都从零开始。你需要维护短期记忆当前会话最近 N 轮消息。长期记忆用户偏好、历史订单、历史决策通常存在向量数据库或 Redis 中。工作记忆当前任务上下文比如已经查到的订单信息。记忆管理的难点是上下文窗口有限。当对话超过模型窗口长度时不能简单截断而要考虑对历史消息做摘要或者把关键信息抽取成结构化字段。从实践看用摘要压缩历史消息的效果通常优于逐字截断因为它保留了语义重点。7.3 权限与安全层这是企业级 Agent 和 Demo 最本质的区别。Agent 一旦接入企业内部系统工具的调用权限必须分级。我建议的最小权限体系如下用户角色可调用工具是否需要审批普通用户查询类工具否运营人员查询 部分写入类工具否管理员全部工具高风险操作需要审批流高风险工具如退款、删除数据、修改配置在执行前必须经过二次确认。具体实现上可以在工具分发层加一个 permission 装饰器没有权限直接返回错误而不是把请求发给模型处理。7.4 可观测性与审计Demo 阶段一句 print 日志足够了。生产环境不行。你需要记录每一次 Agent 执行的用户输入。模型每一轮输出。调用了哪些工具参数是什么。工具返回结果是什么。最终响应是什么。每步耗时、Token 消耗。这些数据至少有三个用途排查线上问题、评估模型表现、满足企业内部审计要求。实际项目中团队会把 Agent 执行过程输出为结构化日志写入集中式日志平台再配一套 Dashboard 查看工具调用成功率、模型回答耗时等指标。7.5 评估与回归企业级 Agent 上线前一定要有一组测试用例。比如 50 个典型问题以及每个问题期望的工具调用序列和最终答案。模型升级或 Prompt 修改后先跑回归测试。AI Agent 是概率系统没有回归测试兜底一次 Prompt 调整可能让线上表现全面退化而你未必能及时察觉。7.6 配置示例下面给出一份参考配置用 YAML 描述一个企业级 Agent 的核心参数agent: name: order-service-agent version: 1.0.0 model: provider: openai-compatible base_url: your-gateway-address model_name: your-model-name temperature: 0.1 max_tokens: 2048 timeout_seconds: 30 loop: max_steps: 8 enable_early_stop: true memory: type: redis ttl_seconds: 3600 max_history_rounds: 10 tools: query_order: permission: user timeout_seconds: 3 cancel_order: permission: admin need_approval: true logging: level: INFO include_tool_args: true sink: elasticsearch这份配置相对抽象地体现了模型参数、执行步数、记忆策略、工具权限和日志输出。实际接入时还需要根据企业技术栈做细化比如 Redis 连接信息、日志平台地址、审批流回调地址等。8. Agent 开发常见问题与排查方法Agent 开发调试成本高一个重要原因是“错误链”很长。问题可能出在 Prompt、工具描述、参数解析、模型能力或外部系统任何一个环节出错都会导致最终结果异常。以下是实践中频率最高的问题问题现象可能原因排查方式解决方案模型不调用工具工具描述不清晰或者模型版本不支持 Function Calling查看模型原始返回确认是否支持 tool_calls重写工具描述换成支持函数调用的模型工具参数总是传错工具 description 里没有写清字段格式约束打印模型生成的 arguments 原文在描述中补充格式示例如“订单号为 A 加 4 位数字”Agent 反复调用同一个工具工具返回结果模型没理解或返回结构太复杂查看工具返回值是否被正确拼进上下文简化返回值格式增加 success/error 字段上下文超出窗口报错长期对话或工具返回内容过长查看 token 消耗日志加入历史截断、关键信息压缩、减少每轮工具返回内容最终答案明显偏离目标多轮循环后任务漂移检查每一轮 messages 内容观察系统 Prompt 是否被覆盖引入任务阶段追踪必要时重新约束目标工具执行报错但 Agent 不自知工具异常返回格式不规范确认工具异常分支是否返回结构化字典所有工具必须返回统一结构success / data / error模型速度太慢单轮生成 token 太多或循环次数过多查看每轮生成耗时降低 max_tokens、限制工具返回长度、控制 max_steps排查 Agent 问题有一条基本思路从头回放每一轮模型输出。不要只看最终答案而是把 messages 列表完整打印出来。每一步模型用了什么工具、带了什么参数、工具返回了什么看完基本能定位问题。9. Agent 开发最佳实践与学习路线9.1 五条工程建议第一工具描述要像写接口文档一样认真。对 Agent 来说工具描述就是它操作世界的说明书。描述里要有参数格式、边界条件、错误示例。描述质量直接决定工具调用成功率。第二所有工具返回值统一结构。推荐使用 {success: boolean, data: ..., error: ...} 三段式结构。这样模型解析起来简单日志和监控也好做。第三默认调低 temperature。Agent 执行内部工具调用时我们希望它稳定、可预测而不是充满创造力。temperature 建议 0 到 0.3 之间。如果模型总是犯错先降低 temperature再优化 Prompt。第四一定要有最大步数保护。一个 Agent 循环如果没有步数上限遇到模型反复思考的极端情况会浪费大量 Token 和时间。建议默认 5 到 10 步根据业务复杂度调整。第五生产环境禁止放开所有工具。逐个上线、逐个验证。可以把工具按“查询类”和“写入类”分开查询类先上线写入类经过审批流后再放开。9.2 学习路线建议如果你是想系统学习 Agent 开发的新手我建议按这套顺序先不依赖框架用原生模型接口手写一个带工具调用的最小 Agent。理解 ReAct 模式、Function Calling、记忆压缩等核心概念。再用 LangChain 或 LlamaIndex 提升开发效率但始终保持能看懂底层实现。动手做一个真实业务场景的 Agent比如客服问答、订单查询、数据分析助手。最后补上可观测性、评估、权限这三个企业级模块。很多人的误区是一开始就上 LangChain结果被各种抽象概念绕晕出了问题不知道是框架问题还是模型问题。先手写循环再上框架你在排查问题时就会清晰得多。9.3 关于“一周吃透”的客观提醒“一周吃透 AI Agent”这个说法我建议用更务实的眼光来看。一周时间足够你理解核心概念、跑通最小示例、写出第一个带工具调用的 Agent。但要达到企业级水平还需要在实际业务里积累经验。真正拉开差距的不是你想了多少概念而是你在真实项目中处理过多少异常、调过多少工具、踩过多少坑。如果你能把本文的最小 Agent 扩展成一个能处理用户真实消息、调用多个企业工具、并且导出执行日志的系统你已经具备了 Agent 开发的核心能力。剩下的就是在项目里持续打磨。建议先按顺序跑通第五章和第六章的代码再尝试把系统 Prompt、工具描述、日志输出调整成适合你自己业务的形式。遇到问题回到第八章的排查表逐个对照。这一套走完你对 AI Agent 开发的理解会超过大多数停留在概念阶段的人。