从大脑到手脚:LLM如何通过Agent闭环落地真实业务

📅 发布时间:2026/10/20 3:18:04
从大脑到手脚:LLM如何通过Agent闭环落地真实业务
最近我在帮某团队搭一套自动化办公的 AI 工具体系会上有位同事说了句话至今让我印象深刻“我们现在的很多 AI 产品脑子非常好使但手脚全是废的。”这个比喻相当精准。过去两年LLM大语言模型的能力突飞猛进写周报、改代码、分析数据看起来无所不能。可真把它接到业务流程里你会很快发现它除了吐出一段漂亮的文字什么都改变不了。它不会点按钮不会发请求不会改数据库更不会自己决定下一步该做什么。这恰恰就是 Agent 存在的理由。Agent 把“思考”和“行动”接在了一起——LLM 负责想清楚要什么Agent 负责把想法变成真实世界里的操作。对于程序员来说这不仅是概念新潮而是实打实的架构转型以前我们写函数、调接口、拼流程现在我们要设计“目标”、给模型配工具、再让模型自己拆解步骤。所以这篇文章我想用工程视角把“灵魂与肉体”这件事讲透LLM 的能力边界在哪里Agent 的闭环是怎么运转的我手写的最小 Agent 长什么样以及跑通 demo 之后真正会踩的那些坑。适合正在做 AI 应用集成、想从“调用 API”升级到“调度 Agent”的开发者参考。1. 先澄清一个误区LLM 是“大脑”但从来没长“手”1.1 一次让人印象深刻的演示“完美回答”和“什么都没做”之间的距离前阵子在某交流会上有位开发者现场演示了一个场景他让大模型帮忙生成一份电商促销方案。模型输出的内容相当专业分阶段目标、人群策略、预算分配、风险提示写得清清楚楚现场不少人都在拍照。然后他又追加了一句“帮我把这份方案发到项目群里并同步给仓储部门调一下库存锁定。”空气安静了。模型沉默了几秒回复“我无法直接访问您的群聊或仓库系统但以下是可以手动执行的步骤……”它又把方案总结了一遍。这个场景不是偶然。很多人第一次用 LLM 时都有类似的错位感模型回答得越完美你越容易误以为它能“做事”。可实际上LLM 的输出只是一种信息载体——文本。如果没有任何外部代码把这段文本转成 API 调用、数据库写入、按钮点击那它就只是一份写得特别好的备忘录。模型负责的是决策和表达行动需要另一层系统来承接。1.2 从概率生成器到推理引擎LLM 真正擅长和不擅长的边界为了理解 Agent 的必要性得先认清 LLM 的本质。从工程角度看LLM 是一个经过海量文本训练的参数化模型它对输入的 token 序列做概率预测逐字生成下一个 token。这就是为什么它极其擅长文本生成、摘要、翻译、风格改写也能在提示词的引导下完成一定程度的逻辑推理。但它的“不擅长”也非常明确它没有内置执行器输出文本不等于改变世界它无法主动访问实时数据知识截止训练时间很多信息靠“猜”它做复杂算术仍然容易出错因为算术不是它的强项推理路径它的上下文窗口虽然越做越大但塞入太多历史之后成本和延迟都会显著上升注意力也会被稀释它偶尔会产生幻觉尤其是面对不知道的细节时会“信心满满地编一个合理答案”。这些边界并不是说 LLM 不行而是说明如果想让模型在真实业务流程里产生价值必须在外面加一层能执行、能校验、能纠错的“身体”。这层身体就是 Agent。1.3 思维链与幻觉为什么“灵魂”再聪明也需要一个可验证的身体有一个很流行的技巧叫思维链Chain of Thought简单说就是让模型“先推理、后回答”——比如先写下已知条件再逐步推导结论。实测下来这个技巧确实能显著提升复杂问题的正确率原因是它模拟了人类解题时“打草稿”的过程让每一步都留下可检查的中间结果。但思维链再强本质上还是在“用语言推理语言”。模型说“我计算了三年销售额总和为 1280 万元同比增长 23%”它并没有真的拿计算器逐行加总它是在生成一个符合语言规律的答案。答案也许对也许错但模型自己并不知道对错。这就是 Agent 存在的一个深层次意义用工具去对抗幻觉。在 Agent 架构里模型如果要算均值可以调用一个计算工具如果要查某地的实时天气可以调一个天气接口。返回的真实数据会作为新输入回到模型那里模型基于事实再继续推理。这样一来LLM 的“想象力”不再被当作事实来源它退回到一个更稳妥的位置——调度者和表达者。2. Agent 补上的不是单个接口而是整套“感知-决策-行动”闭环2.1 从“你问我答”到“目标驱动”Agent 范式到底新在哪很多人的第一个疑问是我们早就写过“调用 AI API - 解析返回结果 - 做下一步处理”的代码这和 Agent 有什么区别区别在控制权。传统程序里流程是程序员预先画好的先调 A 接口判断返回再调 B 接口分支固定每一步由 if-else 决定。Agent 不一样每走一步模型都会根据当前状态重新决定下一步做什么。它可能第一轮选择查文档第二轮选择读数据库第三轮突然发现需要再确认某个条件于是又去查一次。整个路径不是预先定义的而是根据实际执行情况动态长出来的。打个比方传统程序是轨道列车路线固定只能沿着铁轨走Agent 更像自动驾驶汽车知道目的地但红绿灯、路口、临时路障都得实时判断。这个差别带来一个核心变化——程序员的工作从“写死流程”变成了“定义目标和边界”。2.2 工具就是 Agent 的手Function Calling 的底层逻辑Agent 能“动手”的关键技术叫 Function Calling函数调用也叫工具调用。主流大模型 API 基本都支持这个能力你在请求里附带一个工具列表每个工具包含名字、描述、参数结构说明模型在推理时会判断“当前情况是否需要调用某个工具”如果需要它不直接输出最终回答而是返回一个结构化的调用指令比如{ name: query_weather, arguments: {\city\: \某北方城市\} }开发者这边的代码收到这个指令后执行真正的查询函数再把结果以“工具消息”的形式塞回对话历史。模型看到真实返回值之后才能给出有依据的最终回答。这里有个容易被忽略的点工具描述的质量直接影响模型选对工具的概率。工具描述写得像“函数名参数表”是不够的要像给一个没见过你代码库的实习生写说明。比如描述一个计算工具不要只写“calculate”要写清楚“用于执行精确四则运算适合加法、乘法、百分比等避免模型直接心算出错”。描述越清晰模型的调度准确率越高。2.3 让 Agent 干长活的隐形支柱记忆与任务规划只有工具还不够。一个合格的 Agent 要能处理多步骤目标这时候就需要两个看不见的支柱记忆和规划。记忆分几层短期记忆就是上下文窗口里的对话历史模型靠它记得“刚才我说了什么”工作记忆是当前任务的状态变量比如“已经处理了第 3 个文件还剩 5 个”长期记忆则通常外置比如把历史结论存进向量数据库或普通文件需要时再检索回来。没有记忆的 Agent 每轮都像失忆患者跑两步就忘记初衷。规划能力则体现在“拆解目标”上。比如用户说“把季度销售数据整理成报告发给我”Agent 可能要拆成读取表格 - 汇总各产品线指标 - 生成文字结论 - 渲染图表 - 写入报告文件。拆解可以由模型完成但工程上通常需要限制拆解的深度和分支数量避免任务发散失控。我见过最影响稳定性的问题之一就是 Agent 规划时“想太多”明明只有三步的任务模型把它拆成了十二步中间还穿插了一堆无关动作。所以生产环境下往往会用提示词或代码框架限制单任务的步骤上限并强制模型每走一步都简短说明“当前进度和目标”。这本质上是在给“灵魂”加缰绳。3. 三十行代码手写一个最小 Agent从“嘴替”变成“跑腿的”3.1 为什么我不建议你直接用现成 Agent 框架入门现在社区里有很多开箱即用的 Agent 框架抽象层一个比一个高。但以我带项目的经验来说新手直接上框架风险很大框架把工具注册、记忆管理、流程编排都封装好了看起来运行得很顺可一旦出错你根本不知道错在哪一层。是模型选错了工具还是工具返回的格式没被正确回填还是循环退出的条件没满足你只能对着封装好的黑盒干瞪眼。我的建议是先花半小时用几十行代码把最小闭环手写一遍。这个过程中你会真正理解 Agent 的循环、工具调用的数据流、上下文如何累积、退出条件怎么判定。等你彻底搞懂了再去看框架会发现它的设计一目了然用起来也踏实得多。注意我这里说的“手写”是指核心循环自己写调用大模型接口还是用官方 SDK没必要从底层 HTTP 开始造轮子。我们的目标是指挥模型不是重写模型。3.2 最小 Agent 的核心循环观察-推理-行动-再观察来看核心伪代码去掉异常处理和各种边界条件主干其实非常短def run_agent(goal: str, llm, tools: dict, max_steps: int 6) - str: # tools: {tool_name: {desc: str, func: callable}} messages [ {role: system, content: 你是一个乐于助人的智能体。完成任务时你会按需调用工具并逐步推进。}, {role: user, content: goal}, ] for step in range(max_steps): # 1. 把工具 schema 发给模型让它决定是调用工具还是输出结论 response llm.chat(messages, toolsschema_of(tools)) # 2. 如果模型没有要求调用工具说明任务完成返回最终答案 if not response.tool_calls: return response.content # 3. 否则执行模型选择的工具并把结果回填给模型 messages.append(response.to_assistant_message()) for call in response.tool_calls: tool_name call.name tool_func tools[tool_name][func] result tool_func(**json.loads(call.arguments)) messages.append({ role: tool, tool_call_id: call.id, content: json.dumps(result, ensure_asciiFalse), }) raise TimeoutError(超过最大步数仍未完成任务)这个循环就是 Agent 的灵魂它并不是一次性生成答案而是把“生成答案”这个过程拆成了一轮轮的观察-推理-行动。第 3 步尤其重要——工具执行结果必须重新回到对话里模型才能基于真实数据继续思考。如果这一步漏了Agent 就会变成“盲人骑瞎马”——它只能凭空猜工具返回了什么。工具的定义也不复杂每个工具就是“名称描述JSON 参数约束对应函数”的组合。比如{ name: calculate, description: 执行精确四则运算传入运算符和数字返回计算结果。用于百分比、求和、差值等避免模型估算出错。, parameters: { type: object, properties: { expression: {type: string, description: 例如 (1280 2360) * 0.15} }, required: [expression] } }3.3 一次完整实测让 Agent 对比两地天气并给出行动建议我搭过一个非常简单的 demo注册了三个工具一个模拟的天气查询、一个 CSV 表格查询、一个精确计算器。然后给模型布置了一个需要“思考行动”配合的任务请分别查询某北方城市和某南方沿海城市今天的天气对比哪个更适合户外跑步如果两地温差超过 5 度请特别说明选择依据。下面是一个典型的运行轨迹第 1 轮模型说“我需要查询两地天气”然后调用 weather 工具查询某北方城市拿到返回晴21℃湿度 45%。第 2 轮模型调用 weather 工具查询某南方沿海城市拿到返回小雨15℃湿度 90%。第 3 轮模型没有再调用工具而是给出结论某北方城市天气晴、气温 21℃、湿度适中适合户外跑步某南方沿海城市有雨、气温较低不建议户外跑。两地温差 6 度超过 5 度阈值因此优先推荐某北方城市。这个例子看起来平平无奇但它演示了一个关键变化模型没有“编造”天气而是通过工具拿到了模拟数据并据此决策。在真实生产场景里把模拟工具换成真实的天气 API、订单 API、知识库检索接口跑的就是一套正儿八经的 Agent 应用。4. 跑通 demo 只是开始四个翻车点与对应修补方案4.1 Token 黑洞Agent 越“聪明”账单越吓人如果你以为 Agent 只是多调几次模型接口那就错了。它的 token 消耗不是按“轮次”线性增长而是按“历史累积”近似平方级增长。原因很简单每一轮调用都要把之前所有对话历史重新发送一遍。假设一次任务跑了 10 轮每轮新增的工具结果和模型回复约 800 token那么第 1 轮输入大约是 1200 token第 2 轮输入大约是 2000 token第 3 轮输入大约是 2800 token……第 10 轮输入大约是 8400 token。光输入累积加起来就有约 4.8 万 token是单次问答的几十倍。如果工具返回的是超大 JSON、日志文本这个数字还会更夸张。我的修补经验有三条严格限制最大轮数。我一般把生产环境的 max_steps 设在 5~8 之间任务真需要更多步骤就拆成多个子任务。工具结果要截断。只保留关键字段不要一股脑把整张表塞回上下文。比如查询数据库返回 100 行数据只保留前 20 行和汇总统计。定期压缩历史。如果对话太长可以使用一个小模型把早期讨论总结成一段摘要替换掉原始消息减小后续的输入长度。4.2 重试地狱Agent 卡在死循环里的检测与熔断比贵更气人的是“卡死”。我第一次跑 Agent 时就遇到过模型反复调用同一个搜索工具参数一模一样返回结果也一模一样但它就是不停地重新调用然后在总结里说“让我再确认一次”。这个现象在业内被戏称为“重试地狱”。原因是模型在某个能力边界上产生了自我怀疑又缺乏跳出循环的机制。解决办法不复杂但必须提前埋好设置最大步数熔断。到达上限直接终止把已执行的动作和最新进度返回给用户而不是无限等下去。检测连续重复动作。如果模型连续两轮调用同一个工具且参数完全相同就打断并追加一条系统消息“你已经执行过该调用结果未发生变化请停止重复并基于现有结果作答。”调低温度。把 temperature 调到 0 或接近 0减少模型随机探索的概率对工具调度场景稳定性提升非常明显。4.3 幻觉行动编造工具、传错参数比幻觉文本更危险模型返回文本幻觉最多是内容不准确模型调用工具时产生幻觉就可能真的去改数据、发消息、扣库存。这类“幻觉行动”比想象中更常见。举几个真实发生的例子注册表里只有 query_weather模型却调用了 get_weather工具要求参数是数字模型传了字符串工具参数要求数组模型传了字符串拼接的 JSON。根源在于模型是基于概率生成的结构化输出它见过太多类似的工具名容易张冠李戴。我的防御策略是注册表强校验。执行任何工具前先检查工具名是否真的存在不存在就返回错误消息附上可用工具列表引导模型纠正。参数类型严格转换。不要把 JSON 里的字符串直接传给函数用 JSON Schema 校验器先验证失败就明确告诉模型“参数格式不正确”让它重写参数。敏感动作二次确认。对删除、发送、支付这类高影响操作返回一个“需要人工确认”的占位结果而不是直接执行。幻觉无法根除但可以在流程上加护栏让模型“想错也做不成”。4.4 越权风险给 Agent 一双“有分寸的手”有一次某团队给 Agent 接了一个能发邮件的工具提示词里写“用户要求时可以发送邮件”。结果测试阶段模型为了“演示功能”自作主张给列表里的一个客户邮箱发了一封草稿性质的测试邮件。虽然及时撤回但已经足够让人冷汗直流。这个教训说明给 Agent 配置的工具权限必须小于最小必要权限并且按环境隔离。测试环境里给一个 mock 邮件服务生产环境才接真实服务需要调用外部系统时先走人工审批节点也就是所谓的 Human-in-the-loop。真正上生产之前还要把工具调用日志完整记录下来——谁、在什么任务里、调了哪个工具、传了什么参数、返回了什么结果全部留痕。很多初学者会陷入一个误区觉得“工具越强大Agent 越厉害”。但工程经验恰恰相反Agent 的威力来自精准控制下的行动能力而不是无限权限。一个只能查天气、算数字、读 CSV 的 Agent虽然在 demo 里看起来平淡但它不会给你惹大麻烦。5. 程序员的新基本功从“写逻辑”变成“写目标”5.1 提示词不是咒语是给协作者的需求文档很多程序员第一次写提示词时非常痛苦觉得模型“不听话”。后来我发现问题往往出在我们自己身上习惯了精确的编程语言写提示词却变成了模糊的日常口语。模型本质上是一个需要明确验收标准的协作者。好的提示词应该包含五个要素角色、目标、输入源、约束、输出格式。我经常推荐的模板是——你是数据分析助手。请读取 CSV 文件 sales_data.csv 中最近 30 天记录统计各品类销售额增长率输出 Markdown 表格并在表格下方用两句话给出一条可执行建议。如果数据不足请直接说明缺失字段不要编造。这段提示词和“帮我总结一下数据”相比把几乎所有的决策空间都锁死了。这不是玄学而是把需求文档写清楚。程序员的核心能力——拆解问题、明确边界、描述流程——在这里依然有用只是从写代码换成了写提示词和设计工具。5.2 没有“评估集”的 Agent 项目改两版就会失控传统软件有单元测试做回归保护。Agent 是概率系统同一个任务跑三次可能给出三个不同答案这给 QA 带来了极大的挑战。如果团队没有建立评估集每一次修改提示词、工具描述或者模型版本都可能“修好一个问题带崩一片”。我在实际项目里至少会准备一个 20~50 条任务的评估集覆盖三种类型标准任务正常情况下应该完成的代表任务边界任务缺少关键信息、工具返回为空、模型请求超出限制等场景敏感动作任务涉及发送、删除、批准的操作必须验证不会乱来。每次改动后跑一遍评估集哪怕只是人工抽查前 10 条结果也能拦住大部分回归问题。提示词调优和模型选型都不该靠感觉要靠样本集说话。5.3 多 Agent 协作的诱惑与陷阱要不要拆分一个大脑聊到 Agent 的下一步很多人的直觉是“一个模型搞不定那就多个 Agent 分工合作”。于是规划 Agent、执行 Agent、审查 Agent、记忆 Agent 各司其职听起来像一支专业的团队。但我的观察是多 Agent 架构是一把双刃剑。每增加一个 Agent就意味着新增一路模型调用成本、延迟、错误率都会叠加——一个 Agent 出错会影响下游所有 Agent 的判断。而且单个 Agent 本身已经需要严格的上下文管理多个 Agent 之间的信息传递又是一个新的复杂性问题。所以我的建议非常保守先把单个 Agent 做到稳定再考虑拆分。如果任务瓶颈在于“工具的多样性”那就给同一个 Agent 增加工具如果瓶颈在于“单个上下文放不下多个模块”再考虑把这些模块拆成独立 Agent 并提供清晰的接口协议。多数项目里90% 的场景用一个 Agent 加一组好工具就够了剩下的先别急着搞“Agent 联邦”。调试 Agent 的经历和我以前做传统服务端开发的感觉完全不同。传统程序失败的方式是报错——异常堆栈、错误码、断言失败位置清晰明确。Agent 失败的方式更像人跑偏、嘴硬、重复犯错、偶尔还会“一本正经地胡说”。所以我现在搭这类系统最花时间的往往不是模型选型而是给模型配好一排靠谱的工具、写好边界清晰的约束、再备好一轮能自动回归的评估样例。这个思路转变过来之后你会发现“LLM 负责思考Agent 负责行动”并不是一句口号而是下一阶段工程实践的基本分工。脑子和手脚都不缺之后接下来比拼的就是看谁能把团队带得更稳、跑得更远。