十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

AI Agent开发全解析:从ReAct循环到企业级落地

AI Agent开发全解析:从ReAct循环到企业级落地 AI Agent开发是2026年最值得花时间吃透的方向但很多人学了很久仍然停留在调API、跑Demo的阶段。真正从零基础走向企业级项目实战卡点通常不在模型知识而在你能否把一个循环、一次工具调用、一套带日志的批量任务在真实环境里稳定跑起来。这篇教程不追求堆概念而是按我实际跑项目的顺序把AI Agent开发的环境、最小实现、工具接入、知识库、测试、部署排查和面试题全流程拆一遍。如果你想做的是课程作业或个人玩具可以直接跳到最小实现部分如果你想在团队里落地建议从第5节开始重点看。1. 先建立正确认知AI Agent到底在解决什么问题1.1 能聊天的模型不等于能办事的Agent很多人第一次接触AI Agent时觉得它就是“能聊天的模型加了一点自动化”。这个理解不完整。普通大模型能生成文本但是它不能主动去查数据库、不能调用你们公司内部系统、不能感知当前业务状态更不能在任务中途发现信息不足后自己补一次查询。我见过不少项目把大模型接口封装成API然后对外就叫“Agent”。实际上那只是聊天机器人。真正意义上的Agent至少要具备四个能力理解用户目标并把目标拆成可执行步骤。在需要外部信息时调用工具获取数据。根据工具返回结果继续推理并决定下一步动作。保留短期或长期记忆保证多轮对话不丢失上下文。这四个能力不是一上来就要完全实现但要先有一个全局认知。否则你很容易在用LangChain、LlamaIndex、Spring AI这类框架时只会照着文档写代码出了问题完全不知道原因。在2026年这个时间点Agent相关的称呼和框架仍然在快速变化。今天看这个框架明天可能被另一个新框架覆盖。真正不变的是运行逻辑。先把运行逻辑吃透换框架只是换写法。1.2 Agent的最小运行逻辑其实就四步循环不管是开源项目还是企业级系统Agent的内部运行逻辑都可以简化成一个循环接收用户输入。大模型判断是直接回答还是需要调用某个工具。如果调用工具程序执行工具并拿到结果。把结果重新交给大模型让它继续判断或产出最终答案。这就是常说的ReAct循环Reasoning加Acting。模型先思考再行动行动后根据观察继续思考。这个循环看起来简单但很多项目的问题恰恰出在这里。比如模型判断需要调用工具但工具返回的是异常程序直接把异常抛给用户又比如模型连续调用同一个工具多次形成了死循环再比如工具返回结果太长撑爆了上下文导致后续生成质量断崖式下降。所以我会建议不管最终使用什么框架第一步都先手动写一个最小循环。自己写一遍你才知道哪些报错是模型问题哪些是工具问题哪些是参数问题。这也是后面所有企业级做法的地基。2. 开发环境和前置条件先能跑再谈复杂2.1 Python环境与依赖选择高效学习AI Agent环境搭得太重反而会拖慢节奏。先准备一个干净的Python环境然后只装必要的依赖。我建议使用Python 3.10以上版本。太低版本很容易在安装新依赖时遇到兼容问题。建议创建一个虚拟环境不要直接装在全局环境里python -m venv agent_env source agent_env/bin/activate pip install openai pip install python-dotenv这只是一个最简依赖。你不需要在一开始就安装LangChain、CrewAI这些大框架。先用最朴素的HTTP调用或SDK手动完成一个Agent循环。等你理解了每个环节再决定是否引入框架来减少重复代码。选择框架时也要留意版本锁定。Agent领域迭代非常快框架升级后接口经常变。第一天能跑通的代码周末再跑可能就因为依赖版本升级而报错。我一般会在项目里维护一份requirements.txt并且锁定主要依赖版本范围。这样至少能保证代码在团队成员之间复现。2.2 模型从哪来本地部署还是API调用做Agent开发第一步要选模型来源。你的选择会直接影响开发速度和资源配置。如果你只是学习优先使用模型API。它的优势是部署成本低、推理速度快、不用关心显存和显卡驱动。开发时你把更多精力放在Agent逻辑上而不是模型推理环境。如果你的企业有数据隐私要求或者需要极低延迟就需要考虑本地部署模型。常见做法是用支持隐私部署的推理服务或本地推理框架。本地部署对GPU资源有要求。显存会直接影响可支持的上下文长度和并发数越大的模型推理越慢。这里给一个通用参考先从你手头能稳定运行的模型开始不要追求参数最大。Agent开发对模型的“指令遵循能力”很敏感。有些模型能聊天但让它严格按JSON返回工具参数就很吃力。与其纠结参数大小不如先验证模型对function calling的支持程度。2.3 用统一接口屏蔽不同模型差异不同模型服务商提供的接口格式可能不同。为了不把Agent代码绑死在某个模型上我建议在开发初期就留出一层抽象。大多数支持工具调用的模型都提供OpenAI兼容格式。你可以在环境变量里配置export LLM_API_KEYyour-key export LLM_BASE_URLhttps://your-api-endpoint.example.com export LLM_MODELyour-model-name代码里统一从这个环境变量读取。这样换模型时不需要改动Agent核心逻辑只需要换环境变量。需要注意密钥不要硬编码在代码里。尤其在企业项目里密钥应该放在配置中心或环境变量管理。这个问题看似基础但我确实见过有人把密钥提交到Git仓库最后不得不整个项目回滚。3. 从零手写一个最小Agent用代码理解Agent运行逻辑3.1 最小ReAct循环代码先用最简单的方式实现一个Agent。下面这段代码是示意实际接入时以你使用的SDK为准。import os import json from openai import OpenAI client OpenAI( api_keyos.environ.get(LLM_API_KEY), base_urlos.environ.get(LLM_BASE_URL), ) MODEL os.environ.get(LLM_MODEL, your-model-name) TOOLS [ { type: function, function: { name: get_weather, description: 查询指定城市的实时天气, parameters: { type: object, properties: { city: { type: string, description: 城市名比如北京 } }, required: [city] } } } ] def execute_tool(name: str, arguments: str): args json.loads(arguments) if name get_weather: # 这里应该替换成真实天气服务 return {city: args[city], weather: 晴, temperature: 25} return {error: unknown tool} def run_agent(user_input: str, max_steps: int 5): messages [ {role: system, content: 你是一个智能助手可以使用工具获取信息最后用中文回答用户。}, {role: user, content: user_input} ] for _ in range(max_steps): resp client.chat.completions.create( modelMODEL, messagesmessages, toolsTOOLS, ) msg resp.choices[0].message if not msg.tool_calls: print(msg.content) return # 把模型的工具调用意图记录到对话中 messages.append({ role: assistant, content: msg.content, tool_calls: msg.tool_calls }) # 逐个执行工具并把结果以 tool 消息返回 for tc in msg.tool_calls: result execute_tool(tc.function.name, tc.function.arguments) messages.append({ role: tool, tool_call_id: tc.id, content: json.dumps(result, ensure_asciiFalse) }) print(达到最大步骤未完成。) if __name__ __main__: run_agent(北京今天适合跑步吗)这段代码完成了一个最小Agent迭代。它的流程是把用户问题放入messages模型判断是否需要调用工具需要调用就执行工具执行结果再放回messages直到模型不再请求调用工具直接输出最终答案。建议你先把这个最小流程跑通。跑通的意思是你能看到日志里出现模型返回的tool_calls能看到execute_tool被触发能看到最终模型基于工具结果给出回答。3.2 让Agent具备“调用工具”的能力工具调用能不能稳定工作很大程度取决于你对工具的描述和参数约束。首先工具的name要见名知义。不要写一大堆拼音缩写AI Agent基本靠描述理解意图。description要写清楚这个工具是干什么的、什么时候用、有哪些限制。其次parameters必须用JSON Schema定义清楚。所有必填参数都要放进required数组。字段类型要准确。比如城市名在JSON Schema里是string在真实代码里就不要期望它是数组。一个比较容易踩的坑是工具返回结果格式必须稳定。模型会拿你的返回结果继续推理。如果这次返回字符串下次返回JSON模型很难稳定决策。我一般会让所有工具统一返回JSON字符串并且包含status字段{ status: success, data: { city: 北京, weather: 晴, temperature: 25 } }如果工具执行失败不要把异常堆栈直接返回给模型。模型未必能理解程序异常。更好的做法是捕获异常后返回结构化错误信息{ status: error, message: 天气服务超时请稍后重试 }这样模型至少有机会决定是换个参数重试还是告诉用户服务暂时不可用。3.3 验证一个Agent好不好看这四件事跑通一个Demo后你要用质疑的眼光来看它。不要因为一次回答正确就说Agent做好了。我一般会用一个固定样例集来反复验证。一份Agent测试至少要看这四件事目标拆解用户说“帮我计划一次北京一日游”Agent是否知道要分步骤完成。工具触发当问题需要天气、时间、数据库等外部信息时是否正确触发了对应工具。结果使用工具返回后Agent是否把关键信息用上了而不是无视工具结果自己编答案。错误恢复工具失败后Agent是直接放弃还是尝试换一种方式继续。如果四个维度都稳定才说明这个Agent有基本可用性。这里也要提醒不要用一条“看起来聪明”的回答来评估Agent一定要多准备几十个输入样例覆盖正常、模糊、边界、异常四类情况。4. 从Demo到项目工具接入、知识库和外部系统4.1 工具函数的设计与参数约束Agent的价值在于能操作真实系统。因此工具函数设计越合理Agent能完成的任务越复杂。我在真实项目里的工具设计原则是“一个工具只完成一件事”。不要写一个万能工具让模型自己传参数决定行为。模型能处理简单的选择但无法承受复杂的业务分支。常用做法是把业务能力封装成原子接口。工具名类似create_order、cancel_order、get_order_status。每个工具的输入输出都要有明确边界。另外要考虑外部服务的特性。如果工具调用的是一个第三方接口必须处理超时、限流、接口变更等问题。超时时间不要太短大模型本身有推理耗时工具也可能慢。但也要设置上限避免模型等待一个永远不返回的请求。4.2 知识库接入Obsidian、本地文档和向量检索很多Agent项目落地时不希望模型凭空编造公司制度、产品文档或者个人笔记。这时候就需要给它接入知识库。知识库的基本流程不复杂把文档切片向量化存入向量库用户提问时先从知识库检索相关内容再把检索结果附带给模型。这一步常被叫做RAG检索增强生成。我在本地常用Obsidian管理笔记。Obsidian里的Markdown文件本身就是很好的知识库素材。你不需要把所有内容复制到代码里而是让Agent程序读取指定目录下的Markdown文件按标题或段落切分然后向量化。切片参数会影响检索效果。chunk_size太大会把多个主题混在一起增加噪音太小则会切断语义导致检索不到完整上下文。我习惯先用默认参数跑通再根据检索结果调整。判断标准是用户问题里的关键字能否在检索结果中找到对应片段。有一个误区需要说明接入向量检索不等于万事大吉。向量检索只能帮你找到可能相关的内容是否真的正确还需要你持续评估。比如用户问“请假流程”结果检索到一段“请假审批表填写说明”虽然相关但可能缺少了流程中的关键环节。这里最需要的是建立一套评测问答对不断迭代切分方式和检索策略。4.3 Java服务里的Agent客户端Spring Boot AI基础用法很多后端团队是Java技术栈但Agent教程大多是Python写的。这会导致一个尴尬算法工程师用Python验证了效果Java后端却不知道怎么接入。如果你的团队是Java后端建议关注Spring AI这类把模型调用封装成统一客户端的方案。Spring AI的思路和Python生态类似也在支持工具调用、结构化输出、记忆管理等能力。先引入依赖。不同版本依赖坐标有差异建议以你使用的文档为准。基础配置通常是spring: ai: openai: api-key: ${LLM_API_KEY} base-url: ${LLM_BASE_URL} chat: options: model: ${LLM_MODEL}然后在业务代码中注入客户端RestController public class AgentController { private final ChatClient chatClient; public AgentController(ChatClient.Builder builder) { this.chatClient builder.build(); } PostMapping(/chat) public String chat(RequestBody String question) { return chatClient.prompt(question).call().content(); } }代码只是一个示意。不同版本里ChatClient的构建细节会变化但核心思想不变你只需要配置模型地址、密钥和模型名然后把业务代码注入进去。Java场景下最需要注意的是异步和线程池。模型接口调用是IO密集操作不要用同步阻塞的方式打满所有线程。要结合项目本身的并发模型设计合理的线程池大小和超时时间。如果有人问某个图表库能不能和Agent对接我的经验是先看它有没有HTTP接口或结构化导出能力。只要有稳定的输入输出接口就可以封装成Agent工具。真正的问题不是“能不能对接”而是“对接后返回的数据模型是否稳定”。5. 企业级落地测试、评估、队列、可观测性5.1 Agent测试和传统接口测试的差异传统接口测试断言一个返回值Agent测试要难得多。因为大模型有随机性同一个问题可能每次回答都不一样。你不能简单断言输出字段等于某个固定值。Agent测试要更关注行为。比如用户提了一个需要工具的问题模型是否触发了工具。触发工具后传给工具的参数是否合理。工具返回结果后模型是否基于结果回答。模型生成的内容是否包含不该出现的信息。我一般会做两件事第一记录每轮对话的完整轨迹包括用户输入、模型思考、工具调用、工具返回、最终输出。这些轨迹可以用于离线回放。第二建立一个小型标注评测集。准备30到50个问题先手动记录认为正确的行为再让Agent跑一遍对比差异。如果你完全靠人工测试成本会很高。如果条件允许可以把评测集做成自动化脚本。判断标准可以放宽比如工具名是否正确、返回中是否包含关键字段、是否触发了危险动作。5.2 批量任务与并发控制Agent从Demo走向生产最明显的变化就是处理量增大。个人项目跑单条没问题企业场景往往是一次提交几百上千条任务。不要一上来就把并发调到最大。我踩过几次坑之后已经形成习惯先用单条跑通再用5并发试观察错误率和耗时再逐步往上涨。Agent批量任务比传统接口批量更复杂。模型推理慢工具调用也有延迟一条任务可能要几十秒甚至几分钟。这时需要引入任务队列。先把任务写入队列再由worker按配置的并行度消费。还要考虑失败重试。不是所有重试都有效。如果是模型接口临时限流重试有意义如果是输入文本本身有问题重试再多次也是白费。我建议设置重试次数上限并记录失败原因。连续失败的任务要进入一个单独队列人工查看。5.3 日志、追踪和结构化输出Agent系统排查问题的难度比普通应用高。因为一次回答可能包含很多步模型推理、工具调用、中间结果、最终生成。任何一个环节出错最终表现都可能类似。所以日志一定要带上request_id。从请求进来开始一路透传到模型调用、工具调用、异常捕获和最终输出。没有request_id生产环境出问题后你很难把一次任务的完整链路串起来。日志至少记录这些信息用户原始输入。模型收到的完整messages。每次工具调用的名称、参数、返回结果。每次大模型调用的耗时和token消耗。最终输出内容。错误堆栈或失败原因。同时尽量让Agent输出结构化结果。如果你需要Agent返回JSON可以使用受支持的JSON输出模式并在代码侧做一次Schema校验。校验失败时不要直接当成成功要进入重试或异常流程。5.4 性能与稳定性手段当一个Agent要支撑真实业务时稳定比功能多更重要。除了日志和队列下面几个手段值得优先做。第一是超时控制。模型调用要设超时工具调用也要设超时。没有超时一条慢请求可能拖垮整个worker。第二是熔断降级。当模型服务连续报错或响应时间过长时要能自动暂停调用避免雪崩。最简单的做法是连续失败N次后开启熔断过一段时间再尝试。第三是信息缓存。完全相同的用户提问可以缓存结果。更细一点的语义缓存也能命中意思相近的问题。缓存能显著降低成本和延迟但要注意业务数据的时效性不是所有问题都适合走缓存。第四是敏感操作的人机确认。如果Agent能调用删除、下单、转账这类高风险工具不建议完全放开自动执行。可以设计成Agent生成操作意图人工确认后再执行。这既是安全设计也是对合规要求更稳妥的响应。6. 排错链路那些看起来像Bug实际是配置或输入问题6.1 先看现象再动代码的排查顺序Agent出了问题不要急着改代码。我先按这个链路排查看现象是请求失败、超时、无输出、答非所问还是工具循环不结束。看输入用户输入是否完整messages格式是否正确上下文有没有异常增长。看环境依赖版本、环境变量、密钥、网络连通性、磁盘空间。看参数max_tokens是否太小temperature是否过高并发是否过大工具参数Schema是否合法。看模型模型是否支持工具调用是否在长上下文下表现恶化。很多问题表面上是代码Bug实际上与代码无关。比如401错误大概率是密钥不对404大概率是模型名或接口地址不对有一些超时问题是因为企业网络限制导致请求出不去这属于环境问题不是模型问题。排查时不要钻在某个方向里出不来。6.2 高频报错和对应原因下面是我在Agent开发中遇到的高频问题整理成一个表格方便你对照检查。现象常见原因处理建议401 / 403 报错密钥不对、没有权限检查环境变量和密钥是否失效404 报错模型名或接口地址不对核对模型名和base_url429 报错限流或并发过高降低并发增加重试退避请求超时网络问题、模型推理慢、上下文过长分别从网络、模型负载、messages长度排查工具不被调用工具描述不清晰、参数Schema不合法丰富description检查JSON Schema工具调用后模型继续乱答工具返回结果格式不稳定统一返回结构化JSON输出被截断max_tokens设置太小增大max_tokens或压缩上下文上下文长度超限messages累积太长做历史裁剪、摘要压缩或向量缓存任务卡住不动工具调用未设置超时或陷入死循环为工具调用设超时设置最大迭代步数6.3 面试官最爱问的Agent问题结合“AI Agent面试题”这个高频搜索词我列几个面试里经常出现的问题并给出回答时需要突出的点。第一个Agent和RAG有什么区别。RAG是给模型补充知识Agent是让模型主动行动。两者可以结合不是互斥关系。第二个什么是function calling。这是模型输出结构化调用指令的能力模型决定调用哪个函数程序来真正执行不是模型直接执行函数。第三个Agent陷入死循环怎么办。要设置最大迭代步数增加工具调用超时检测重复工具调用并准备人工中断通道。第四个多Agent如何通信。可以用共享消息队列、事件总线或黑板模式。通信内容要结构化不能依赖纯文本。第五个如何评估Agent质量。从目标完成率、工具调用准确率、错误恢复率、上下文引用正确率几个维度评估。第六个生产环境怎么保证安全。敏感操作需要人工确认权限最小化所有动作留痕并做输入输出审计。回答这些问题不用背概念要有自己跑过的项目体会。哪怕是一个很小的天气查询Agent只要你能说清楚循环逻辑和踩过的坑面试官也会认为你具备真实实践能力。7. 2026年AI Agent的学习节奏和趋势判断7.1 技术栈该往哪个方向积累到了2026年AI Agent相关框架和产品会继续增加但底层技术栈的积累方向相对清晰。第一提示词和上下文管理能力仍然重要。不管模型能力怎么升级你能不能把有效信息放到合适的位置决定了生成质量。第二工具调用和结构化输出越来越关键。Agent能控制的工具越多出问题的可能性也越大。如何设计稳定的工具Schema如何校验输出这些经验比框架知识更值钱。第三工程化能力是区分专业和业余的分水岭。日志、追踪、限流、熔断、失败重试、测试评估这些传统后端技能放在Agent场景下同样适用。你没有这些能力Agent只能在Demo里转。第四多模态输入、长文本和自动化工作流是值得重点观察的方向。未来Agent可能不只是读文字还要读图、读表格、操作业务系统。每增加一种能力都要同步补上对应的评测和排错手段。7.2 推荐的最小学习路线最后给一条我认为最稳妥的学习路线按阶段执行每个阶段都设置一个明确结果。阶段一手动实现一个ReAct循环。不需要任何Agent框架能通过API完成用户输入、工具调用、结果回传即可。完成标准是你能在日志里清晰看到每一步。阶段二给Agent加入3到5个工具。覆盖查询类、计算类、业务操作类。完成标准是Agent能根据用户意图选择正确工具且工具失败时能恢复。阶段三接入一个知识库。用本地Markdown或Obsidian笔记做资料源完成文档切片、向量化、检索和回答。完成标准是评测集上的相关检索命中率有明显提升。阶段四做一个批量任务版Agent。加入任务队列、并发控制、失败重试和日志追踪。完成标准是连续跑100条任务能自动跳过单条失败并保留完整日志。阶段五用Java或Go等语言封装成服务。可以沿用Spring AI也可以自研接口。完成标准是业务方通过HTTP接口触发Agent任务并能在管理后台看到结果和失败原因。把这几个阶段走完你就不再是“会调API的人”而是真正能从零搭建Agent系统的开发者。环境可以更新框架可能会换但这一套方法在2026年依然能用。
返回列表