新生成练成记-《AI Agent开发项目实践》做AI Agent开发有一段时间了从最开始只会给聊天机器人接个API到现在能用LangGraph FastAPI搭出一套可独立部署的Agent服务中间踩过的坑、推倒重来的设计比我在前公司写业务代码三年加起来还多。这篇《AI Agent开发项目实践》算是一个阶段性的复盘把从选型到落地、从单机跑到扛并发的全过程记录下来。这个项目说白了就一件事让一个AI Agent真的“下地干活”。不是那种陪人聊天的Demo而是接到真实业务流程里去能够解析用户模糊指令、调外部API、查数据、写结果把状态管理、错误恢复、性能优化全部搞定。如果你正准备从Demo走向可生产部署或者手里已经有一个Agent项目但总觉得哪里不稳这篇文章应该能帮你少走不少弯路。1. 项目缘起市面上的Agent不少能接得住脏需求的却不多1.1 我的起点一个把自己绕晕的聊天机器人我最早接触AI Agent相关开发是在一个内部工具项目里公司想把客服聊天记录自动整理成工单再根据工单内容给售后组分配任务。第一版我用了最简单的思路——把聊天记录直接丢给大模型让它输出一个JSON包含工单标题、紧急程度、责任部门、处理建议。第一次测试效果惊艳基本准确。但真上线跑了三天问题全冒出来了。首先是用户的原始输入“脏”。聊天记录里有表情包、错别字、中英文夹杂、发布时间戳、客服自己打的备注模型经常被这些无关信息带偏。其次同一个用户追着问三句话模型就把前面的上下文忘了导致工单内容不连贯。最让我头疼的是工具调用——我想让Agent自动去查订单系统拿用户买了什么但第一版的模型并没有“查订单”这个动作的能力它只能靠聊天记录里的只言片语瞎猜。这时候我才意识到我做的不是聊天机器人而是一个有“行为能力”的Agent。聊天机器人是“你说我听我回你”Agent是“你说目标我自己想办法达成”。目标拆解、状态管理、工具调用、错误恢复每一项都是单独的工程问题。1.2 需求梳理把一件事拆成四层重新开工之前我把需求拆成了四层这个拆法后来帮了我大忙接入层用户从微信、企微、网页对话框等多个入口进来所有消息统一转成内部消息协议。决策层Agent收到消息后先判断用户想干什么——是简单问答、是查数据、是多步操作还是需要追问澄清。这个决策由大模型 规则共同完成。执行层一旦确定要“做”就进入多步执行流程。每一步可能调一个工具、查一次数据库、或者再问模型一次“下一步该干什么”。沉淀层每次执行完毕把关键结论、上下文摘要、执行结果存下来下次同一用户再来就能直接继续对话或跳过重复流程。这四层在第一个版本里没有分清楚我把所有逻辑都塞在了一个for循环里结果模型每说一句话程序就跟着它跑一步完全不受控。后来真正理解了“Agent必须有状态机”这件事才把这个项目从玩具变成了能上生产的系统。2. 技术选型复盘LangGraph搭骨架、FastAPI做门面、模型留接口2.1 先回答热搜词Agent的主流架构到底长什么样在选型前我查了不少资料热搜词里“AI Agent主流架构”几乎被搜烂了。我的理解是市面上所有Agent框架本质上都是在解决“循环 工具 状态”这三件事。循环Agent不是一次的输入输出而是“用户说目标 → 模型思考 → 决定动作 → 执行动作 → 观察结果 → 再次思考”的循环过程。工具模型本身不能查库、不能调接口、不能操作文件必须通过注册好的工具函数与外部世界交互。状态循环过程中的中间产物——已经查到的信息、已完成的子任务、用户的长期偏好——需要有一个地方存起来供每一轮循环读写。主流架构基本就是围绕这三点展开的有的用ReAct模式Reason Act先推理再行动有的用Plan-and-Execute先规划再逐条执行有的用多Agent协作一个主控、多个子Agent各司其职。没有绝对的好坏只有适不适合。我在项目里最终选择了LangGraph原因是它在处理“循环 状态”的时候是显式建模的——你画一个图标明节点和边把状态放在一个共享的字典里图的执行逻辑完全由你自己控制。这比LangChain早期的AgentExecutor那种隐式循环要可控得多。2.2 为什么是LangGraph而不是其他方案我一度犹豫过要不要用LangGraph因为它比直接调OpenAI API多了学习成本。但实际工程上有三个理由让我留了下来状态持久化是内置能力。LangGraph的State是一个可序列化的结构每条执行轨迹可以存进数据库中断后能恢复。这对生产环境太重要了——如果你跑一个多步Agent第3步时模型输出超时整个任务重来的成本是灾难性的。图结构让逻辑可视化。我把客服工单处理流程画成图开始 → 信息抽取 → 订单查询 → 部门分类 → 工单生成 → 结束。每个节点一个函数节点之间用边连接哪里出错一目了然。后来新同事接手这个项目看着图就能懂整套逻辑不用读满屏流程代码。流式输出支持得不错。Agent执行过程中用户界面上需要实时显示“正在查询订单…”“正在分析对话…”这是一条硬需求。LangGraph的节点可以做成流式返回配合FastAPI的SSEServer-Sent Events体验很顺。当然我也不是没踩LangGraph的坑后边会专门讲。Framework是工具不是银弹。如果你只是做一个“单轮问答 调两三个工具”的小项目用手写状态机或者直接调LangChain都完全够用。LangGraph的价值在上规模之后才能真正体现。2.3 模型接入与token意识token不只是计费单位热搜词里有一个是“ai agent token是什么意思”这个问题我一开始也没完全想清楚。Token的朴素理解是“计费单位”——你给模型发的每个字、模型回你的每个字都折成token收费。但做Agent项目之后我把token意识彻底变了token就是Agent的思考预算。每一轮循环里模型收到的不是用户的一句话而是“系统提示词 历史消息 当前状态 工具描述 工具返回结果”。工具返回结果可能是一张几百行的数据表模型要消化这些数据还要输出决策这中间的token消耗比单纯聊天高一个数量级。我做了一个简单的成本估算表按当时GPT-4o的定价场景单次请求输入token单次响应token说明纯闲聊一轮约500约200上下文短成本低查订单 分析约3000约800工具返回数据占大头多步计划 两次工具调用约8000约2000中间推理过程全算token长对话 5次工具交互约30000约6000历史积累是主要开销Token不是“能省则省”的问题而是“该花的地方花、不该花的地方一分不花”。比如把原始聊天记录全塞进提示词就是典型的不该花。后来我改成先让模型做一次“信息压缩”只保留与工单相关的字段再进入下一步输入token直接降了近一半。3. 四个绕不开的核心块记忆、工具、规划与并发3.1 记忆管理让Agent记住“刚才说过的话”我前两版Agent最可笑的一个毛病用户问“刚才那个订单怎么样了”Agent完全不知道用户在说什么。因为它每次调用模型都是独立的上下文只包含当前这一次输入。后期我加了两种记忆短期记忆把当前任务循环里的关键状态放进LangGraph的State。比如查询到的订单号和订单状态在下一次模型调用时注入提示词。这样Agent能记得“自己刚刚查到过什么”。长期记忆把每个用户的历史会话摘要存储到数据库按用户ID索引。每次对话开始时加载上一轮的摘要作为“记忆片段”而不是把全部聊天记录塞进去。长期记忆我用的方案比较朴素每次会话结束时单独调一次模型把关键信息压缩成200字以内的摘要存到一个带expired时间的表里。下次用户再来时先取摘要再取最近几条原文。这个方案成本很低效果却很好——用户隔天回来问“昨天你说那个事怎么样了”Agent是真能接住的。3.2 工具调用让Agent“下地干活”的关键一步工具调用是Agent和聊天机器人的分水岭。我在项目里接的工具五花八门查询订单接口、用户画像接口、客服知识库检索、工单系统创建接口甚至还有内部汇率换算工具。工具注册的时候有几个细节容易被忽略工具描述必须“反着写”。就是告诉模型什么情况下不该用这个工具。比如查订单接口描述里要写“仅当用户提供订单号或手机号时使用如果用户只问物流政策不要调用”。不写清楚边界模型可能碰到任何问题都去调这个工具然后返回一堆无用数据把自己绕晕。我实测过加了“不该用”的描述之后工具调用准确率提升了至少20%。工具返回要结构化。返回的不是一段自由文本而是标准JSON{success: true, data: {...}, message: ...}。模型读JSON比读散文准确得多。另外要给返回加长度上限超长的数据先截断或摘要防止token爆炸。工具错误要可恢复。接口超时、参数不合法、没有权限这些错误信息要原样返回给模型模型才能基于错误决定下一步——“告诉用户订单不存在”而不是当成成功然后瞎编。这里有一个真实的教训我一版工具调用是“模型说调就调”结果有一次用户问“你们退货政策是什么”模型调了订单查询接口拿到空结果后自己编了一个退货政策。这个问题的根子不在模型而在工具边界没写清楚。从那以后我的每条工具描述都会写清楚“适用条件”和“绝对不要使用的情况”并且要求模型在调用工具前先输出“调用原因”。3.3 路由与规划把大任务拆成小步骤的工程化做法Agent能不能处理复杂任务关键看它会不会“规划”。我做过两种规划方式。第一种是在提示词里直接告诉模型“你可以一步一步来”然后让它在一次响应里输出多步计划。这种方式的优点是实现简单缺点是模型偶尔会在第二步就放弃或者自己编一个没验证的结论。第二种是在代码层做硬路由模型只负责“判断意图”不负责“安排步骤”。我写了一个意图分类函数把用户请求分为“查物流”“问政策”“提投诉”“转人工”等几个类目每个类目对应一个LangGraph子图。模型做的事情是单选题而不是开放式发挥准确率高了很多也方便加规则兜底。我的经验是能用代码写死的逻辑不要用模型自由发挥。模型擅长的是理解和生成不是精确控制和流程编排。特别是业务流程固定的时候用“意图路由 固化子流程”比“让模型全程自由规划”可靠得多。3.4 并发问题一个Agent不稀奇十个并发才算考验热搜词里“ai agent怎么扛并发”是不少人在搜的。Agent并发和普通API并发的难点不太一样普通接口是“请求进来 → 处理 → 返回”Agent是多轮循环可能一个任务跑两分钟中间还要调外部接口如果不做控制几十个任务就能把模型API配额打满、把下游系统拖垮。我的做法分三层应用层限制用信号量控制同时执行的任务数比如最多10个Agent任务并发其余排队等待。这一层很简单但避免了资源瞬间打满。队列削峰把任务先写入消息队列Worker按固定速率消费。每个任务有独立的执行ID用户在界面上看到“排队中→执行中→完成”的状态变化即可不需要实时响应。模型API错峰不同优先级任务走不同的模型或不同的速率限制。比如工单自动分类这种低成本任务用便宜模型复杂多步对话用强模型两类请求分开计数防止互相挤占。实测下来加了这三层之后同样10个用户同时发任务系统的P95延迟从原来的“有一个任务卡住整串都卡住”变成“单个任务最慢5秒其余全部正常完成”。并发问题的核心思路不是“无限扩大资源”而是“让资源被有序地使用”。4. 从能跑到扛得住并发瓶颈与token成本的实际排查4.1 第一个瓶颈模型超时引发连锁抖动系统第一次做压测的现场我记忆犹新总共也就20个模拟用户同时操作结果最多有6个任务同时卡在“等待模型响应”的状态其中3个最终超时失败。查日志发现失败原因不是模型不可用而是我的代码在发起模型请求时没有设置合理的超时和重试策略。一个请求默认等了60秒期间占着一个执行槽位后面的任务全堵住。后来把所有外部调用的超时统一设置为模型调用30秒、普通工具调用10秒、数据库查询5秒。重试采用指数退避 最大重试次数3次的策略。单项超时失败只影响当前任务不会拖垮全局。这里我特别想强调一个容易被忽略的坑重试时要区分“幂等”和“非幂等”。查询订单是幂等的重试没问题但创建工单不是幂等的如果第一次请求其实成功了、只是响应超时你重试就会创建出两个工单。我的解法是给每次创建操作生成一个request_id下游接口如果检测到同一个request_id就返回已有结果而不是重复创建。4.2 第二个瓶颈工具返回数据太大token直接失控有一次压测时我注意到一个异常现象某个查询订单的Agent任务单次消耗了将近10万token费用是正常任务的20倍。排查下来发现是这个Agent循环了5轮每一轮都把完整订单列表塞进上下文越攒越多最后模型光读历史就花掉一大半token。解决思路有两个方向。第一个是上下文压缩每轮循环结束时用模型把当前状态压缩为“我需要记住的事实清单”下一轮只带这个清单不带原始数据。第二个是裁剪工具返回订单列表超过20条就只展示汇总统计需要看明细再单独调用二次查询工具。两个方案结合之后同类任务的token消耗降了约70%而且模型决策质量没有下降反而因为输入更集中更准确了。这件事给我的启发是Agent的上下文窗口不是越大越好没用的信息越多模型越容易抓不住重点。上下文管理是一门独立的工程手艺值得花时间打磨。4.3 第三个瓶颈状态存储和并发冲突LangGraph默认的状态存储是在内存里的两个任务同时写同一个状态键会出现覆盖问题。我们遇到的实际场景同一个用户的“查订单”和“查物流”两个请求并发进来因为共享同一个user_id状态互相覆盖导致Agent一会儿以为自己在查订单、一会儿又以为是查物流输出完全错乱。修复方案是把状态存储切到数据库按“用户ID 会话ID”做隔离。最开始用的Redis缓存后来为了保证任务可恢复换成带持久化的PostgreSQL。每个会话有自己的状态记录任务恢复时按会话ID重新加载不会串数据。这个问题的排查花了很长时间因为错误是间歇性出现的它不是每次都复现只在并发量高的时候偶尔蹦出来。后来加了日志追踪单次会话的状态变化才发现是并发覆盖。排查这种问题最有用的手段不是猜而是给每个任务加上trace_id把整个生命周期里的所有日志串起来看。5. 项目之外的横向观察Rust、Spring AI与垂直场景的真实边界5.1 Rust写Agent高性能场景的另一种可能我在项目稳定运行之后顺手把一个简单的意图路由模块用Rust重写了一遍目的就是看看热搜词里“基于rust语言ai agent”到底有没有工程价值。先说结论有价值但和大多数人想的不一样。Rust的优势不是“写Agent更快”而是“运行得更省”。同样一个意图分类服务Python版本单进程能扛80 QPSRust版本能扛300 QPS内存占用还更低。如果你是把Agent拆成微服务架构把“高吞吐的入口网关”“工具调度中枢”这类模块用Rust写确实能省不少服务器成本。但难点也很明显AI生态的SDK基本以Python为核心Rust的LangChainlangchain-rust和大模型客户端还在追赶很多高级功能要么没实现、要么API不稳定。我的建议是不要把整个Agent都用Rust写而是挑出最需要性能的模块——比如工具网关、路由服务——用Rust做把它在整个系统里的职责定义清楚发挥长短处结合的优势。5.2 Spring AIJava生态的Agent入场券另外一个让我留意的方向是Spring AI。热搜词里“spring ai agent”说明很多Java背景的团队也在跟进。Spring AI的定位类似Spring Boot风格的封装把大模型调用、Prompt模板、结构化输出、向量数据库这些能力统一成了Spring风格的接口。Java技术栈的团队选择Spring AI有一个很现实的原因公司基础设施全是JavaJava团队没法轻易引入一套Python服务。Spring AI至少让“在Java里跑Agent”这件事有了标准化的路。但老实说Agent的核心复杂度——状态管理、循环编排、工具调用的容错——并不是Spring AI框架能解决的它提供的是“与大模型交互的规范化层”真正复杂的业务编排还是要自己设计。我给Java团队的建议是可以先用Spring AI做简单的RAG问答和工具调用验证流程不要一上来就上多Agent协作的架构。Spring AI本身迭代很快但目前生态的成熟度还需要时间去沉淀。5.3 垂直场景落地小红书自动发消息、期货交易这些热词背后热搜词里有些很具体的场景比如“让小红书自动发消息”“个人使用ai agent可以做期货交易吗”这类问题我平时被问得最多。先说小红书自动发消息这类自动化场景。技术上是完全可行的——本质就是Agent解析用户指令 → 生成内容 → 调API发布 → 定时跟踪互动数据。但真正的门槛不在代码而在账号风控和内容合规。平台对自动化行为有严格的检测机制违规操作可能导致账号被封。这类项目的正确打开方式是企业官方认证的接口渠道而不是个人脚本批量操作。我在做这类需求时都会反复提醒需求方Agent解决的是内容生产效率和运营链路协同的问题而不是让你用机器去刷平台。再说期货交易。让Agent辅助交易和让Agent全权交易是两回事。我能做的、也建议做的是让Agent做“信息汇总和风险评估”——比如把新闻、行情、交易报告整理成结构化简报提示“当前波动率异常”。但你让它自动下单、自动管理仓位这里涉及到监管合规和资金安全的问题绝不是技术能力能覆盖的。我对所有问这类问题的个人开发者都建议把Agent定位成决策辅助工具而不是全自动交易员风险边界一定要划清楚。6. 如果重新开始我会怎么做复盘与路线建议6.1 一份按周推进的学习路线很多人在热搜里搜“ai agent学习路线”我也复盘了自己的路径给准备入坑的人一份按周推进的参考第1周搞懂概念。弄明白ReAct、Plan-and-Execute、多Agent协作的区别。重点看LangChain和LangGraph的官方文档和示例不用写复杂代码跑通一个“读文件 → 总结 → 发邮件”的最小Demo即可。第2-3周把“工具调用”吃透。做一个带3个工具的小项目比如“天气查询 日历提醒 便签记录”重点体会工具描述怎么写、返回怎么结构化、错误怎么恢复。第4周引入状态管理。把之前的项目改成多轮对话 工具组合加上记忆功能实测“上下文压缩”对token消耗的影响。第5-6周做并发和生产化。把自己做的Agent包成FastAPI服务加上信号量、队列、超时重试做一次压测。目标不是追求高并发而是体验“从能跑到扛得住”的过程。第7-8周找一个真实场景。比如公司内部的工单助手、个人知识库问答机器人。真实场景会逼你处理脏数据、边界情况、用户不按套路出牌的问题这才是Agent工程能力的真正分水岭。6.2 我最后悔没有早知道的三个原则复盘整个项目有三件事如果一开始就明白能省下至少一个月的返工时间第一Agent的边界不是模型的能力而是你对状态的掌控力。模型可以很强但你的系统如果不知道“它现在到哪一步了”再强的模型也会乱跑。先把状态机画清楚再写一行业务代码。第二能写死的逻辑不要让模型自由发挥。模型是决策器不是状态机。所有可枚举的分支、需要精确计算的步骤、有统一规则的部分全部用代码实现。模型只处理那些真正需要“理解”的部分。第三上线之前先做成本预算。Agent的token消耗与用户交互次数、工具数据大小强相关没有预估就开始做很可能上线一个月才发现成本是预期的十倍。给每次对话设置费用上限超出自动转人工或降级这一条能救你的账单。6.3 个人真实的下一步打算目前这个项目已经稳定跑了小半年主要服务的还是内部业务。接下来我准备做三件事第一把长期记忆从简单的摘要升级成向量数据库方案让它能支持“模糊回忆”用户说“上次那个特别贵的订单”也能匹配上第二给Agent加一个“人工审计面板”所有AI执行的关键步骤都留痕必要时候人工介入这一步对信任建设非常重要第三尝试把Rust重写的路由服务正式部署到生产测一测真实场景下的性能和稳定性收益。做Agent开发这件事最上头的地方在于它没有标准答案。每一次踩坑都意味着这种“边界”又多摸清了一点而每摸清一点系统就能多扛住一种混乱。从项目最初那个被聊天记录绕晕的机器人到现在能稳定执行多步任务、扛住并发压测的工具回看整个《AI Agent开发项目实践》的过程最值钱的不是那些代码而是对“可控性”这三个字越来越具体的理解。如果你也在搞Agent项目别急着一上来就堆功能。找一个真实的需求场景把状态、工具、记忆、成本这四件事想明白就已经赢过大多数Demo了。这也是我在这个项目里最深的一条体会。
阅读完成 · 觉得有帮助?