ARTICLE DETAIL

资讯详情

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

AI Agent实战:从对话到交付,掌握ReAct与Function Calling

AI Agent实战:从对话到交付,掌握ReAct与Function Calling 很多朋友学完第一课和第二课之后会有一种“AI也不过如此”的错觉——聊聊天、写写文案、生成几张图好像已经摸到天花板了。但真正进入AI Agent智能体和AI编程实战的人很快就发现事情没那么简单模型经常不按套路出牌任务一复杂就翻车工具调用失败了你还不知道为什么。这恰恰是第三课要解决的核心问题从“会聊天”到“会交付”。这一课我不打算给你贴大段的概念定义而是把AI大模型基础理论里最影响实战的几块掰开讲清楚然后带着你从零搭一个能查资料、能算数据、能干活的小Agent再聊多AI协作和并发场景下的工程化思路。适合的人有两类一类是刚学完AI入门课、想往AI编程走但不知道从哪下手的同学另一类是已经在业务里用AI提效但总觉得自己在用“人工智障”想搞明白背后原理的开发者。1. 从对话到交付第三课先想明白Agent和你谁说了算很多人对AI Agent的第一反应是“这玩意儿能自动干活”。这个说法没错但它掩盖了一个关键问题Agent到底是什么我的定义很朴素——Agent是一个“能自己做决定、自己动手、自己根据结果调整下一步”的AI系统。它和大模型对话的本质区别不是功能变多了而是控制权发生了转移。你和大模型聊天每一轮都是你在主导你问它答你继续问它继续答。Agent不一样你只需要给它一个目标剩下的过程它来规划、它来尝试、它来修正。听起来很爽对吧但代价是你要学会“把话说清楚”并且懂得设边界。我见过太多人搭Agent失败不是模型不行而是他在System Prompt里根本没说清楚这个Agent的职责范围是什么、有哪些工具可以用、什么情况下必须停下来问人。这里有个很重要的认知大模型的强项是“生成”不是“记忆”更不是“执行”。它本质上是一个极度擅长预测下一句话的系统你给它合理的上下文它就能输出合理的内容。但它不记你的会话历史除非你手动塞给它、不会主动去查数据库除非你给它工具、也不能保证每一步都严谨它经常跳步和瞎编。Agent存在的意义就是把这些弱点全部用工程手段补上——用外部存储补记忆用工具调用补执行用任务规划补严谨。那为什么第三课才讲这个因为第一课你学了模型是什么第二课你学了怎么写提示词但这些都是“对话范式”。到了Agent你需要换一套思维提示词不再是“把话问好”而是“把任务定义清楚”。这是两种完全不同的写作方式。对话范式里你写的是问题Agent范式里你写的是章程、边界、工具清单和纠错策略。我见过最快的入门路径是这样的先别急着用复杂的框架自己用API写一个最小的Agent循环——给模型配两个工具让它反复“思考-调用-观察-再思考”跑通了再去学LangGraph、Dify这些工具。为什么因为框架会把很多细节藏起来藏起来的东西一旦出问题你根本不知道去哪排查。自己写一遍循环你对“模型输出和工具调用之间到底怎么连接”会有肌肉记忆式的理解。2. 又一次大模型基础理论token、上下文与幻觉的真相既然要搞Agent大模型基础理论里有些东西就得重新复习一遍——但不是为了考试是为了让你在选参数、排故障的时候有据可依。2.1 token不是“字数”是成本也是能力边界所有模型都按token计费但很多人对token的理解停留在“大概等于英文字母或半个汉字”。这在对话场景无所谓Agent场景就麻烦了Agent会多轮循环、每轮都要把工具返回结果拼进上下文token消耗是指数级上升的。我做过一个真实的文本分析Agent让它处理一篇3000字的文章并输出摘要中间它调用了4次工具最后一算总token是文章本身字数的6倍。所以你在搭Agent之前一定先搞清楚三件事模型的上下文窗口到底有多大、你的业务单次会话大概需要多少token、成本上限是多少。上下文窗口不是“越大越好”的窗口越大模型的注意力越容易被稀释。实测下来很多任务在长上下文下反而不如短上下文稳定因为无关信息太多模型容易“迷失重点”。能通过RAG检索增强生成缩小范围的就不要把整份文档塞进去。2.2 temperature到底该怎么设temperature这个参数通俗讲是“回答的随机程度”。0到1之间越大越有创造性越小越确定。很多人从头到尾用默认值这是不对的。在Agent场景里大部分环节你希望模型“稳”而不是“飘”——调工具、解析参数、做数据提取这些任务一旦发散就会出错。我会把工具调用和数据处理节点设成0到0.2只有需要在最后生成文案、写总结、做头脑风暴的节点才调到0.7以上。这个经验属于谁用谁知道的那种不调你后面会被各种莫名其妙的输出逼疯。2.3 幻觉是bug吗不是特性大模型会产生幻觉也就是一本正经地胡说八道。很多人把这当模型缺陷实际上这是“预测下一个词”机制的必然结果。模型不知道“事实”它只知道“哪个词接在这儿更像人话”。所以它回答一个问题不是去“查证”而是去“生成一个看起来合理的答案”。当这个答案恰好在训练数据里匹配到了真实信息它就显得聪明匹配不到它就编一个。理解了这一点你就能理解为什么Agent必须配备工具和知识库模型的角色是“推理”不是“记忆”。凡是涉及实时信息、私有数据、精确计算的一律通过工具调用去拿结果而不是让模型凭记忆生成。RAG、API查询、数据库读取都是为了把“记忆”外包出去只留“推理”给模型。我在实操中还有个教训低temperature也不能完全消除幻觉尤其是模型被要求回答超出它知识范畴的问题时。所以Agent的System Prompt里要明确写一句“当你不确定时明确回答不确定并使用工具查询如果工具仍未返回可靠结果如实告知用户。”这行字不值钱但能省下大量后期救火的时间。3. Agent的工作哲学ReAct循环里的想、做、看现在进入本期最核心的话题Agent是怎么“想事情”的。几乎所有主流Agent架构底层都是ReAct范式——Reasoning推理加Acting行动交替进行。理解这一个模式你就理解了Agent设计的半壁江山。3.1 ReAct到底是怎么转起来的我给你画个简单的循环不用看论文也能懂用户给一个目标。Agent先生成一段“思考”——分析当前目标、判断下一步该做什么。Agent调用一个工具——可能是搜索、算数、查数据库。系统把工具返回的结果拼接到上下文里。Agent再生成一段“思考”——评估工具结果决定下一步是继续调用工具还是给用户产出最终答案。循环直到结束。用生活类比的话这就像一个实习生做调研他先想“我需要哪些资料”然后去翻资料看到资料后想“这些够不够”不够就继续找够了就写报告。ReAct就是把这个过程程序化。这就是Agent和“单次对话”的差别。你让普通大模型“帮我写一篇市场分析”它直接生成——全程没有查证内容全靠训练记忆。但Agent版本的“帮我写市场分析”会先去搜索行业报告、查几个数据源、交叉验证一下再动笔。谁更靠谱不用我多说了吧。3.2 Function Calling让模型学会使唤工具模型本身不能执行代码、不能发请求它只能输出文字。所以Agent里有一层非常关键的机制叫Function Calling——模型在需要外部能力时不是直接给答案而是输出一段结构化的调用请求比如{ name: web_search, arguments: { query: 2026年新能源汽车市场销量数据 } }我以OpenAI风格API为例整个Agent循环的代码骨架长这样import json from openai import OpenAI client OpenAI() def web_search(query): # 这里接入搜索服务 return f搜索到与{query}相关的结果若干最重要的是…… def get_current_time(): import datetime return datetime.datetime.now().isoformat() tools [ { type: function, function: { name: web_search, description: 搜索最新的网络信息, parameters: { type: object, properties: { query: {type: string, description: 搜索关键词} }, required: [query] } } }, { type: function, function: { name: get_current_time, description: 获取当前时间, parameters: {type: object, properties: {}} } } ] messages [{role: user, content: 帮我查一下今天天气怎么样顺便告诉我现在几点了}] finished False while not finished: response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, ) message response.choices[0].message messages.append(message) if message.tool_calls: for tool_call in message.tool_calls: fn_name tool_call.function.name args json.loads(tool_call.function.arguments) if fn_name web_search: result web_search(args[query]) elif fn_name get_current_time: result get_current_time() else: result 未支持的函数 messages.append({ role: tool, tool_call_id: tool_call.id, content: result }) else: finished True print(message.content)这个循环就是Agent的心脏。你仔细看会发现模型本身不会去执行工具它只是“提议”调用工具和参数真正执行的是你的Python代码。这就是Agent的工程本质你写的程序负责执行模型负责决策。在实际做AI编程的时候我会用像Fitten Code这样的AI插件去辅助写这类胶水代码——你只要把上面的循环描述清楚IDE里的AI能直接生成差不多能用的版本你自己再根据业务微调。这不丢人反而是AI Native研发范式下的正确习惯把重复代码交给AI把判断留给人类。3.3 System PromptAgent的螺丝钉式约束很多人在Agent翻车之后才发现问题出在System Prompt上。System Prompt不是普通提示词它是给Agent设定的“职业规范”。写System Prompt有四个必须覆盖的内容角色与边界你的Agent是谁什么能做、什么绝对不能做。工具使用规则什么情况下必须调用工具什么情况下禁止调用。输出格式最终答案要什么结构比如必须是JSON或MD格式。兜底策略遇到不确定情况怎么处理是继续尝试还是回退给用户。我自己的System Prompt模板大概是这样的你是一个智能助理负责帮用户查询资料、分析数据并给出建议。 规则 - 凡涉及实时信息、精确计算、数据查询必须先调用工具禁止凭记忆回答。 - 每次工具调用后先分析工具结果再决定下一步动作。 - 如果工具返回为空或结果不可靠明确告知用户暂未查到可靠信息不要尝试编造。 - 最终输出使用Markdown格式包含结论和依据两个小节。 - 当用户要求明显超出你的能力范围时礼貌说明并提供替代建议。别小看这段文字。我在调试Agent时有超过一半的诡异行为都是“规则没写全”导致的。模型是个“遵纪守法的好员工”你给了什么规则它就按什么规则走但你没写的规则它就自由发挥——自由发挥通常是翻车的前奏。4. 动手做一个能查资料、算数据、发消息的小Agent纯粹讲原理容易飘接下来我带你动手搭一个能跑的最小Agent。别急我们不用那些重型框架就用一个Python脚本主线逻辑就是第三节那个ReAct循环。等到你把这个循环跑通了再决定要不要换框架。4.1 需求定义我以“会议室预订助手”为例这个场景很短小但足够覆盖Agent的大多数核心动作输入用户说“帮我查一下明天下午三点的会议室是否空闲如果空闲就订一个两小时的同时把这个消息发给项目群。”能力一个查空闲时间的方法、一个预订会议室的方法、一个发消息的方法。输出用户能感知到“查询-预订-通知”三个动作依次完成并收到确认信息。4.2 prompt与工具定义工具部分直接复用第三节的函数格式在这里我补一下System Prompt的设计你是会议室预订助手职责是帮助用户查询和预订会议室。 规则 - 查空闲必须调用check_room工具预订必须调用book_room工具发通知必须调用send_message工具。 - 在预订之前必须已经完成空闲查询并且结果是空闲。 - 如果查询结果为空或不满足用户需求直接如实告知不要擅自更改条件。 - 每完成一个动作用一句话向用户确认。你看每一条都在约束“决策顺序”。因为Agent最大的风险不是不会干活而是乱干活——比如用户还没确认它就直接订了。这一类“自作主张”的问题是Agent落地时最常遇到的靠模型自我反省是靠不住的必须在规则里写死。4.3 完整Demo代码这里给出一个精简版核心只是循环里的工具分派逻辑完整代码已经够你照着敲了import json from openai import OpenAI client OpenAI() # 模拟会议室数据 rooms {A202: [(09:00, 12:00), (14:00, 16:00)], B305: [(10:00, 18:00)]} def check_room(room_id, date): if room_id in rooms: return f{room_id}在{date}的名额{rooms[room_id]} return 未找到该会议室 def book_room(room_id, date, start, end): return f{room_id}在{date}的{start}-{end}已预订成功 def send_message(channel, content): return f已发送消息到{channel}{content} tools [...省略具体定义结构同上...] def agent_run(user_input): messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_input} ] for _ in range(10): resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools ) msg resp.choices[0].message messages.append(msg) if not msg.tool_calls: return msg.content for tc in msg.tool_calls: args json.loads(tc.function.arguments) if tc.function.name check_room: result check_room(**args) elif tc.function.name book_room: result book_room(**args) elif tc.function.name send_message: result send_message(**args) messages.append({role: tool, tool_call_id: tc.id, content: result}, ) return 已达最大执行轮数停止。 print(agent_run(帮我查一下B305明天下午的会议室如果空闲就订两点到四点的))我把这一步单独拎出来讲是因为Agent的第一个版本文档里不写原理只写“沿着这个骨架改业务函数就行”。很多人学AI编程最大的障碍不是不会写代码而是不知道第一行应该放哪。上面这段就是你的第一行。跑完这个Demo你至少会直接遇到三个问题模型有时候不按约定调用工具而是直接回答跳步、工具参数格式偶尔不匹配幻觉参数、循环次数设置太短导致任务中途停止。这三个问题太典型了我会在第六节逐个踩一遍给排查思路。4.4 低代码平台值不值得学搭建Agent完全不写代码可行吗可行。Dify、Coze这类低代码平台把节点拖一拖就能构建一个Agent。我的建议是可以用来做MVP验证业务价值但生产环境最终要落到代码。原因是平台有边界一旦需求超出平台的预设节点你要么被迫加非标准方式要么换框架重写。而做AI编程的核心竞争力不只是把Agent跑通而是知道它为什么能跑通以及出了问题去哪修。For初学者我的路径是先用低代码平台跑通整个业务的逻辑流程然后用代码平台比如LangGraph或原生API重写核心的、需要定制的部分。两边一对比你对“Agent到底是什么”的理解会生根。5. 从单兵到小队多AI协作怎么编排、怎么扛并发当你的Agent越来越复杂你就会遇到两个新问题一个Agent搞不定需要多个角色协作同时用的人多了性能扛不住。这两个问题往往是同时出现的所以我放在一起讲。5.1 多Agent协作的三种经典编排模式多AI协作不是“多开几个Agent聊天”而是有目的性地分工。我实践下来最常用的有三种模式直接给结论第一种流水线模式Pipeline。任务天然有先后顺序比如“先分析文档再写摘要最后翻译成英文”。每个Agent只负责一步前一个的输出是后一个的输入。这种模式最简单、最稳定就是链路长的时候延迟高。第二种扇出聚合模式Fan-out / Fan-in。一个任务可以横向切成多块比如“分析全国各省的销售数据”拆成几十个子任务每个子任务一个Agent并行处理最后再汇总。这种模式下并发多效率高但是要注意子任务的输出格式必须严格对齐否则聚合的时候会五花八门。第三种路由器模式Router。一手用户请求进来由一个“调度Agent”判断该交给哪个下游Agent——是客服Agent、技术Agent还是数据分析Agent。这种模式最接近真实业务但调度Agent本身成了新的瓶颈它的判断准确率直接决定整个系统体验。模式的选择没有标准答案取决于你的任务可不可以被切分以及切分后是否容易合并。5.2 Agent怎么扛并发从请求到任务队列热词里有一个问题特别实在AI Agent怎么扛并发。单机把Agent循环跑一百次本质上就是一百次串行超过一定量级就要上工程手段。我的核心结论Agent的循环本身是CPU密集加IO密集的混合体你不可能靠加线程解决所有问题真正的解法是把任务加入队列用一批Worker消费。整体架构我一般这么设计用户请求进来先入库或进消息队列Redis或RabbitMQ。一批Worker进程从队列里拉任务每个Worker内部跑Agent循环。循环中的每次模型调用都要做超时控制——模型接口卡住了不能等它一辈子。任务状态要持久化running、success、failed都要记录在案。失败任务要有重试机制但是重试次数要设上限且重试要在退避Backoff之后进行否则接口被打满更难恢复。这里面最容易忽略的是速率限制。各家模型API都有每分钟请求数限制你的并发一上来最先爆的就是这个。所以代码里必须加限流器——我用的是令牌桶思路一个Worker在调用模型前先取令牌取不到就等一下。这一个小改动能让你的Agent在高并发下的稳定性提高好几个档次。下面是我常用的并发改造思路表阶段问题解法大量任务涌入请求打到模型API触发限流引入消息队列削峰填谷单任务执行太久Agent一个循环卡在模型调用上每次调用设置合理的超时时间Worker崩溃进行到一半的任务丢失任务状态落库启动时扫描未完成重复执行重试导致重复预订等副作用给任务和工具调用加幂等键上下文过大多轮循环后token超限对工具结果做截断和摘要压缩5.3 多Agent与真实硬件扩展一个不起眼但值得知道的点热词里有个“openclawros为你的ai代理”看起来像是Agent和真实硬件设备交互的方向。其实思路是一样的如果Agent要操作的不是软件工具而是ROS机器人那工具调用的目标就从“函数”变成了“接口指令”本质上还是“模型决策-函数执行-结果回传”的循环。一旦Agent开始操作实体设备可靠性要求会急剧上升——软件服务出错了可以重试机器人动作出错了是会出事故的。所以这类场景一定要加“人工确认”节点凡是高风险动作Agent只能发起请求真正执行必须有人拍板。这是我在多AI协作上踩过的最大的坑光顾着让Agent干活忘了在关键节点上留人类干预的闸门。等你想起来的时候往往已经造成了不可逆的副作用。6. 实测中踩过的Agent坑从上下文膨胀到模型跳步最后这部分我把自己在真实项目里踩过的坑挨个说一遍。每一个说出来都是“这也能错”但每一个我都实际花钱买过教训。6.1 模型跳步明明有工具它偏要自己猜现象System Prompt里写明了“查数据必须调用查询工具”但模型在部分轮次直接绕过工具凭训练记忆输出数据。排查后发现模型在“觉得差不多能答”的时候就会偷懒——这是它的本能。修复方式有两个第一把System Prompt改成“除非工具返回了结果否则不要相信你的记忆”第二在代码循环里强制校验如果某类关键动作没有对应的tool_call记录直接让模型重来一轮。6.2 上下文膨胀Agent跑着跑着就“失忆”了Agent每轮循环都把工具返回塞进上下文等跑到七八轮时上下文里全是历史结果最早的指令被淹没了。你明明让它做三步任务它做完第二步就停了。这个问题最适合用“截断摘要”解决每一轮结束后把之前的消息列表压缩成一个“过程摘要”只保留关键事实和已完成的动作下一轮重新拼接。一句话别让Agent背着全部历史跑要让它背着“要点”跑。6.3 工具返回格式不和模型读不懂自己的调用结果有时候工具返回了结构化的JSON但模型会执着地把它当纯文本解读导致后续解析全部乱掉。解决方案有两种一种是让工具返回“模型友好格式”比如拼接好的自然语言摘要另一种是在system prompt里强制指定“工具返回内容必须按JSON解析”。我更推荐第一种因为模型对自然语言的容错度远高于强制JSON解析。6.4 死循环与无限调用成本失控的开端最要命的一个坑Agent在某个问题上反复调用同一个工具返回结果都一样但它就是不死心一直循环。如果你不设最大循环次数这个循环能直到token耗尽为止。我的血泪经验是循环上限不是保护任务成功率是保护你的钱包。10轮是默认值20轮是极限再高说明Agent的规划逻辑有缺陷你调的是System Prompt而不是把上限调高。6.5 遗忘测试Agent重构了旧功能坏了多Agent协作搞起来以后团队经常只测新路径老路径慢慢失效了也不知道。我现在维护Agent项目一定会建一个评估集把过去用户反馈过的最典型的20个任务写进去每次改Prompt、换模型、加工具全量跑一遍评估集看有没有退化。这个习惯和做软件的回归测试是一个道理但Agent项目里更容易被忽略因为“对话式交互”给人感觉好像不容易回归——实际恰恰相反模型或提示词一换行为完全可能大变样。6.6 真实项目里的一个完整排查链路给你还原一次真实的排错过程。当时用户反馈“查会议室的时候有时候不会发送确认消息”。我排查的时候没有急着改Prompt而是翻日志发现同一个任务有两个分支路径路径A先查会议室返回空闲继续预订发送消息。正常。路径B先查会议室返回空闲模型在下一步居然没有发起预订调用而是直接返回了一句“会议室空闲请问需要预订吗”问题定位这其实不是功能坏了而是模型“决策保守化”了。系统上下文里某个历史样本可能让它觉得“擅自预订会惹用户不满”所以它在可做可不做时选择了不做。修复方式也直白——在System Prompt里加一条硬性规则“对于用户明确要求的完整任务不得在中间步骤停下来询问确认除非遇到异常。”跑完评估集重启恢复正常。类似这样的问题是Agent项目里最耗时间的部分。排查思路就一条先复现再看日志再看模型到底在哪个环节改变了决策最后针对性地修改Prompt或工具的定义。不要一上来就“加一句更严格的提示词”来解决问题那样很容易按下葫芦浮起瓢。最后分享一个我自己调整Agent的小习惯每加一个工具或改一次Prompt我都会把模型的完整运行日志保存下来简单统计一下每轮的目的。跑得久了你会形成一种直觉——看到Agent的输出路径你基本能猜出它在哪一步会翻车。这种直觉不是来自算法理论而是来自反复试验和数据积累。AI这个领域变化快但Agent的底层逻辑——决策、执行、观察、纠错——在可预见的未来不会过时掌握好这套思路你换什么模型、用什么框架都不慌。
返回列表