尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Agentic编程是Flop吗?从原理到工程实践的冷静分析

Agentic编程是Flop吗?从原理到工程实践的冷静分析 最近在 Hacker News 上刷到一个带着点“审判”意味的讨论Is “Agentic” Programming a Flop评论区两边吵得很凶。有人在自己项目里跑 Agent 工作流预算烧得快结果却不如一句 if-else也有人坚持说 Agent 只是被用错了地方不是这个方向不行。我把这个争论拿到实际代码里验证了一遍也动手搭了一个最小可运行的 Agent 工作流。这篇文章不打算站队而是把 Agentic 编程是什么、为什么有人觉得它“翻车”、到底哪些场景适合用、哪些场景应该绕开完整梳理一遍。文章里会给出可直接复制的 Python 示例、常见报错和排查思路以及我在工程落地时的取舍建议。无论你是刚接触大模型开发的新手还是已经在生产环境里折腾过 Agent 的后端开发者这篇文章都能给你一个相对冷静的参考坐标。1. 背景Agentic 编程为什么会被质疑是 Flop1.1 从“大模型能聊天”到“大模型能干活”过去两年大家的注意力从“大模型能不能生成一段话”快速转移到了“大模型能不能独立完成一件任务”。于是出现了 Agentic AI、Agentic RAG、Agent 工作流这些热词。Agentic 编程通俗地说就是让大模型不只是一个问答接口而是一个能自己调用工具、根据工具返回结果调整下一步行动、最终完成任务的“执行者”。它的核心循环可以简化成接收任务。思考需要调用什么工具。调用工具并拿到结果。根据结果决定继续调用还是给出最终答案。这套模式在学术界和工业界最著名的范式之一是 ReAct也就是 Reason Act让模型交替进行推理和行动。1.2 为什么很多人感觉“翻车”了回到标题里的问题为什么有人会觉得 Agentic Programming 是 Flop我翻了大量讨论负面的声音基本集中在几个真实痛点上成本不可控一个简单的查询Agent 可能反复调用模型好几轮每一轮都在消耗 token。行为不稳定同样的任务这次成功下次可能在一个小细节上跑偏。调试困难传统的程序执行路径是确定的Agent 的执行路径是模型现场“想”出来的出了问题很难复现。收益不明显很多任务用几条规则、一个普通的 RAG 流程就能解决非要上 Agent 反而更慢更贵。这些批评不是没有道理。但“用错了地方”和“这个东西本身不行”是两码事。这篇文章的后半部分会专门讨论适用边界。2. 概念拆解Agent、Agentic RAG 与普通自动化有什么区别2.1 Agent 到底是个什么东西在工程语境里一个 Agent 至少包含三部分大模型负责理解任务、做决策。一组工具模型可以调用的函数比如查数据库、调 HTTP 接口、读文件。控制循环决定什么时候继续调用工具、什么时候停止并输出答案。缺少模型的代码只是普通函数调用缺少工具的模型只是聊天机器人缺少控制循环的调用方式则很难处理多步任务。2.2 Agentic RAG 不是简单的“向量检索 大模型”很多人听到 RAG第一反应是把文档切块做向量化用户提问时先检索再拼进 Prompt 让模型回答。这是标准的朴素 RAG。Agentic RAG 则是在这个基础上加入了“多次检索、多次推理”的能力。比如用户问“对比三份合同里付款条款的差异”朴素 RAG 可能只检索到其中一份文档的片段而 Agentic RAG 会先检索发现信息不足再改写查询继续检索最后汇总答案。关键区别在于Agentic 模式下检索的次数和查询词不是提前定死的而是模型根据上一轮检索结果动态决定的。2.3 Agentic 编程与低代码自动化的边界另外需要注意Agentic 编程不等于类似 Python 脚本的自动化。普通自动化是确定的每一步都提前写死。Agent 的每一步是模型在推理时决定的。这意味着你不可能用单元测试完全覆盖 Agent 的所有执行路径只能用评估集和边界约束来“限制”和“校验”它的行为。3. 环境准备与版本说明这一节我们先搭好运行环境后面的示例都基于这个环境。3.1 基础环境操作系统Windows / macOS / Linux 均可。Python建议 3.10 及以上。大模型 API下面的示例以 OpenAI 兼容接口为例你也可以替换为国内可用的兼容服务只要接口协议一致即可。3.2 安装依赖这里最主要的依赖是openaiPython SDK。注意这个 SDK 的版本差异比较大1.x 版本和 0.x 版本的调用方式完全不同本文使用的是 1.x 的写法。python --version pip install openai如果你的网络环境需要走代理需要确保 HTTP_PROXY 或 HTTPS_PROXY 环境变量配置正确这里不再展开。3.3 准备 API Key下面示例会从环境变量读取OPENAI_API_KEY不要把 Key 硬编码在代码里。为了安全我还建议你使用一个专门为测试创建的 Key并设置调用额度上限。export OPENAI_API_KEY你的_key4. 核心原理从一次函数调用到一个完整 Agent 循环4.1 Function CallingAgent 的“手”想让大模型具备调用工具的能力第一步是告诉模型有哪些工具可用。OpenAI 等平台提供了 Function Calling 机制你只需要把工具描述按指定格式传给模型。下面是一个最小工具定义功能是查询天气。请注意工具描述越清晰模型越不容易调用错。# tools.py def get_weather(city: str) - str: 模拟天气查询 return f{city}: 晴25°C TOOL_SCHEMA [ { type: function, function: { name: get_weather, description: 查询指定城市的当前天气, parameters: { type: object, properties: { city: { type: string, description: 城市名称如 上海 } }, required: [city] } } } ]这段代码里description字段很关键。如果工具描述模糊比如只写“天气查询”模型可能不会正确从用户输入中提取城市参数。4.2 Agent 主循环控制“继续还是停止”有了工具定义接下来就是最核心的部分Agent 控制循环。它的逻辑可以概括为调用模型传入历史消息和工具列表。如果模型返回tool_calls就执行对应工具把结果以tool角色消息追加回去然后继续下一轮。如果模型没有返回tool_calls说明它认为可以给出最终答案循环结束。必须设置最大轮数避免死循环。# agent.py import json from openai import OpenAI from tools import get_weather, TOOL_SCHEMA client OpenAI() def execute_tool(name: str, arguments: str) - str: 根据函数名执行工具 args json.loads(arguments) if name get_weather: return get_weather(args[city]) return f未知工具: {name} def run_agent(user_prompt: str, max_steps: int 5): messages [ {role: system, content: 你是一个乐于助人的助手必要时使用工具回答问题。}, {role: user, content: user_prompt} ] for step in range(max_steps): print(f--- Step {step 1} ---) response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolsTOOL_SCHEMA, ) msg response.choices[0].message if msg.tool_calls: messages.append(msg) for tc in msg.tool_calls: print(f调用工具: {tc.function.name} {tc.function.arguments}) tool_result execute_tool(tc.function.name, tc.function.arguments) messages.append({ role: tool, tool_call_id: tc.id, content: tool_result }) continue # 没有工具调用说明模型已给出最终答案 print(最终答案:, msg.content) return msg.content print(达到最大轮数强制停止) return None if __name__ __main__: run_agent(今天上海天气怎么样)运行python agent.py预期的执行过程大致如下--- Step 1 --- 调用工具: get_weather {city: 上海} --- Step 2 --- 最终答案: 上海今天晴25°C。请注意模型名称、返回格式可能因 API 版本不同而略有差异。如果你用的是其他兼容接口需要先确认它是否支持tools参数。4.3 为什么“固定流程”也是一种 Agent再强调一次Agent 不一定要多复杂。一个“先检索、再生成”的 Agentic RAG 流程其实也是在同一套循环里把“检索”当成一个工具。# agentic_rag.py def retrieve(query: str) - str: # 实际项目中这里是向量检索或关键词检索 return 检索到的文档片段合同付款条款约定在发货后30天内支付。 TOOL_SCHEMA_RAG [ { type: function, function: { name: retrieve, description: 从知识库中检索与问题相关的文档片段, parameters: { type: object, properties: { query: {type: string} }, required: [query] } } } ]把这个工具和前面的主循环拼在一起就是一个最简版本的 Agentic RAG。它比朴素 RAG 的优势在于模型可以在第一轮检索结果不够时自己决定换一个关键词再检索一次。5. 完整实战构建一个带“确认机制”的代理任务5.1 需求背景下面我们做一个更贴近业务的小例子一个“带前置确认”的定时任务 Agent。它的任务是用户告诉它“定期导出报表并发送到指定邮箱”Agent 需要先调用工具确认报表状态再决定是否执行发送。在实际生产环境中类似需求很常见尤其是涉及写入、发送、删除等操作时必须引入人工确认。5.2 项目结构agent_demo/ ├── tools.py # 工具定义与实现 ├── agent.py # Agent 主循环 └── run_demo.py # 演示入口5.3 带确认机制的实现我们先定义两个工具check_report和send_report。# tools.py def check_report(date: str) - str: 检查指定日期的报表是否生成完成 if date 2025-01-01: return 报表未生成 return 报表已生成 def send_report(email: str) - str: 发送报表到指定邮箱高敏感操作需要确认 return f报表已发送至 {email} TOOL_SCHEMA [ { type: function, function: { name: check_report, description: 检查报表是否生成参数为日期, parameters: { type: object, properties: { date: {type: string} }, required: [date] } } }, { type: function, function: { name: send_report, description: 发送报表到指定邮箱必须在确认用户已明确要求后才可调用, parameters: { type: object, properties: { email: {type: string} }, required: [email] } } } ]在 Agent 主循环中我们对send_report做一层人工确认# agent.py import json from openai import OpenAI from tools import check_report, send_report, TOOL_SCHEMA client OpenAI() def ask_user_confirmation(action_desc: str) - bool: 在新终端或控制台请求用户确认 answer input(f是否确认执行以下操作[{action_desc}] (y/n): ) return answer.strip().lower() y SENSITIVE_TOOLS {send_report} def execute_tool(name: str, arguments: str) - str: args json.loads(arguments) if name check_report: return check_report(args[date]) if name send_report: if not ask_user_confirmation(f发送报表到 {args[email]}): return 用户取消了本次操作请勿重试 return send_report(args[email]) return f未知工具: {name} def run_agent(user_prompt: str, max_steps: int 5): messages [ {role: system, content: 你是一个报表助手先检查报表状态再按用户要求执行发送。}, {role: user, content: user_prompt} ] for step in range(max_steps): response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolsTOOL_SCHEMA, ) msg response.choices[0].message if msg.tool_calls: messages.append(msg) 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: result }) continue print(最终答案:, msg.content) return msg.content print(达到最大轮数强制停止) return None运行演示入口# run_demo.py from agent import run_agent if __name__ __main__: run_agent(请检查 2025-01-01 的报表如果已经生成就发送到 bossexample.com)这样当模型决定调用send_report时程序会先让用户确认避免 Agent 在条件判断失误时直接执行高敏感操作。5.4 运行与验证python run_demo.py输出会类似--- Step 1 --- 调用工具: check_report {date: 2025-01-01} --- Step 2 --- 调用工具: send_report {email: bossexample.com} 是否确认执行以下操作[发送报表到 bossexample.com] (y/n): y 最终答案: 报表尚未生成但我已尝试发送结果为报表已发送至 bossexample.com。这里暴露了一个真实问题模型可能忽略“先检查再发送”的顺序约束。所以我在执行层加了确认机制即使模型乱来操作也不会未经确认就执行。这个思路在生产环境里非常重要别指望模型“理解”你的意图要在执行层用代码兜底。6. 常见问题与排查思路6.1 Agent 最常见的“翻车”现场下面我整理了自己和社区里反馈较多的问题按现象、原因、解决方案列出。问题现象常见原因解决思路Agent 不断调用工具不输出最终答案缺少最大轮数限制或工具返回结果不明确模型认为还需要继续设置 max_steps工具返回内容包含“已结束”“无更多信息”等明确措辞每次调用花费大量 token成本飙升每轮都把完整历史消息传给模型且工具返回结果过长做上下文裁剪工具结果只保留关键字段必要时用摘要替代原文模型调用了错误工具工具描述不够精确或工具之间功能重叠在 description 中写清楚使用条件和典型例子减少重叠工具数量同一任务多次执行结果不一致模型本身有随机性且没有固定评估标准设置 temperature0建立固定评估集多次采样观察通过率Agent 在业务系统里产生错误数据执行层缺少校验和确认机制高敏感操作必须加入人工确认写操作前先做参数校验和权限检查6.2 排查 Agent 问题的通用步骤如果 Agent 行为异常不要直接改 Prompt 瞎试按下面顺序排查打开日志确认每一轮模型的输出内容和工具调用参数。手动执行工具确认工具本身没有 bug。逐步减少工具数量看模型是否还会出错。用一个固定输入反复跑 5 到 10 次判断问题是否随机出现。如果错误来自模型理解再微调描述或给示例而不是增加更多约束词。6.3 关于评估集的一点提醒很多 Agent 项目失败不是代码写得不好而是根本不知道“好”的标准是什么。建议第一时间准备一份评估集包含 20 到 50 条典型输入和预期结果。这样模型或流程调整后你能快速判断是变好了还是变差了。7. 最佳实践与工程建议7.1 先做“确定的事”再让模型参与决策我在项目里的一条铁律是能用规则解决的绝不让模型决策。Agent 只负责“判断走哪条路”具体执行尽量走确定性代码。比如判断用户意图后实际的数据计算仍然用普通函数完成模型只做调度。7.2 为 Agent 加上预算和时间约束生产环境里每个 Agent 运行实例都应该有成本上限和时间上限。这些约束不是可选优化而是必须项。# config.py MAX_STEPS 5 # 最大调用轮数 MAX_COST_DOLLARS 0.5 # 单次任务最大花费 REQUEST_TIMEOUT 30 # 单次请求超时时间调用模型时传入超时参数并在每轮结束后统计 token 消耗一旦超过预算立即中止。7.3 日志记录比任何推理都重要Agent 的运行过程不可预知因此必须记录完整轨迹。至少要记录时间、模型名称、Prompt、模型回复、工具名称、工具参数、工具结果、token 消耗、本轮是否触发停止。这些日志不仅是排错依据也是后续评估、安全审计的原材料。7.4 安全边界最小化涉及发送邮件、修改数据库、执行命令、通知用户等操作时务必遵守最小权限原则。在测试环境验证通过后再考虑生产发布。每次变更前做好备份普通用户角色禁止调用高权限工具。7.5 用分层结构控制复杂度建议不要写一个“万能 Agent”。把系统拆成多个小 Agent每个只负责一个专业领域。比如一个负责检索一个负责起草一个负责审核。这样单个 Agent 的 Prompt 更简单也更容易单独评估和替换。8. 结论Agentic 编程到底是 Flop 吗回到开头的问题。我的判断是Agentic 编程并没有失败失败的是“无边界地使用 Agent”这件事。它不适合解决的问题主要有三类完全确定、可以用脚本完成的操作。需要极高准确率和可证明性的事务比如金融精确计算。你无法提供评估手段的开放场景。它真正有价值的场景是那些“需要阅读理解 多步决策 上下文变化”的任务。包括但不限于复杂文档对比分析、自动化测试用例生成与执行、多轮检索的资料整合、代码仓库分析与修改建议。如果你正在考虑落地 Agent建议从一个小范围、低风险、可以量化的任务开始。先写好评估集再逐步扩大 Agent 的权限。短期内Agent 更多是程序员手里的“智能助手”而不是完全无人值守的“智能员工”。作为一个参考方向Agentic RAG 是目前开源社区比较活跃的切入点你可以在 GitHub 上搜索相关项目关注它的检索循环设计、评估方式和对工具调用的容错处理这些都是比纠结“Agent 是不是风口”更实际的问题。
返回列表