news 2026/9/11 6:22:26

Agentic Programming是Flop吗?工程视角下的落地实践与反思

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agentic Programming是Flop吗?工程视角下的落地实践与反思

最近在国内外技术社区里,总能看到一个争议很大的问题:Agentic Programming 到底是不是一个“Flop(失败/泡沫)”?

有人觉得 Agentic AI 是下一代开发范式,是打破传统“输入—处理—输出”固化逻辑的新方向;也有人觉得它不过是“调大模型 API + 写了一堆 if-else”,Demo 看着热闹,真正上生产就崩,甚至不如普通 RAG 稳定。

本文不打算站队,而是从工程角度把这个问题拆开:先厘清 Agentic Programming 到底是什么,再看看当前被吐槽“Flop”的核心原因,然后结合一个 Agentic RAG 的落地案例,聊聊如何用工程手段把“不稳定”控制在可接受范围内,最后给出一套适合新手入门的路线和场景决策表。

目录:

1. 背景与核心概念

1.1 Agentic Programming 到底是什么

Agentic Programming 不是一门新语言,也不是一个新的开发框架,而是一种编程范式的转变。

传统编程中,开发者会把一个任务拆成明确的函数调用链:A() -> B() -> C(),每一步做什么、参数是什么、返回什么都是确定的。这种范式在业务逻辑清晰、输入输出可控的场景下非常高效。

但到了大模型时代,很多任务的输入是“模糊的自然语言”,输出没有固定结构,甚至“目标”本身都需要模型来理解。这时候,传统编程就不好使了。Agentic Programming 的核心思路是:你不再直接写死每一步怎么做,而是定义好目标、工具、约束和边界,让模型在运行过程中动态规划下一步做什么。

一个典型的 Agentic 系统通常包含:

  • 一个 LLM 作为“大脑”,负责理解和规划。
  • 一组工具(Tool),比如搜索、数据库查询、代码执行、HTTP 请求。
  • 一个执行循环,模型根据当前状态决定调用哪个工具,然后观察结果,再决定下一步。
  • 可选的内存模块,用于记录对话历史或任务状态。

所以 Agentic Programming 不是“凭空自动写代码”,而是“把决策权交给模型,开发者负责搭建可控的执行环境”。

1.2 为什么会有人问“Is Agentic a Flop”

先说结论:Agentic Programming 并没有真正失败,但当前确实处于“期望膨胀期到落地阵痛期”的过渡阶段。

之所以大家质疑它,主要有几个很现实的原因:

  • 大多数 Agent 项目停留在 Demo 阶段,跑通一个完整业务并长期稳定运行的项目非常少。
  • Agent 的行为具有不确定性,同样的输入,可能前一次成功、后一次失败,这在传统工程里是灾难级的缺陷。
  • 成本不可控,多轮规划、多次工具调用,每一轮都是 Token 消耗,线上账单容易失控。
  • 可观测性差,传统代码一行日志就能定位问题,而 Agent 的问题经常发生在多轮推理中,排查难度成倍增加。

说白了,大家反感的不是“Agentic 这个方向”,而是“只展示能力、不解决工程问题的玩法”。

1.3 Agentic 编程与传统编程的核心区别

维度传统编程Agentic 编程
控制方式开发者写死控制流模型动态规划控制流
容错能力异常可以精确捕获处理需要设计恢复机制,错误比较隐蔽
可测试性单测、集成测试成熟需要额外的评估集和轨迹评测
成本计算资源相对固定与 Token 消耗、工具调用次数强相关
适用场景逻辑明确、输入结构化任务开放、需要跨工具协调

需要强调的是,两者不是替代关系,而是互补关系。一个成熟系统往往是用传统代码搭建骨架,在需要灵活决策的地方引入 Agentic 能力。

2. 为什么当前 Agentic 项目容易“翻车”

2.1 不可重复性与“幻觉”被放大

传统程序是确定性的,同一个输入必然得到同一个输出。Agent 则不同,模型每次生成的概率不同,加上多轮规划,失败会被逐步放大。

比如一个 Agent 任务:查询用户订单状态,如果异常则发邮件通知。它可能在第一轮正确调用了订单查询工具,但在第二轮解读结果时出现“幻觉”,错误地判断为“订单不存在”,然后走完了后续流程。这种错误在传统代码里是不会出现的。

应对思路是把“关键判断点”抽出来,做显式校验。比如模型判断“订单不存在”时,如果原始工具返回的是“网络超时”,就不应该直接接受模型的结论,而应该让 Agent 进入重试分支。

2.2 评估缺失

很多人觉得 Agent 写好了就是好的,但“跑通了”和“跑得好”是两个概念。传统代码可以用单元测试覆盖,Agent 则需要一个评测集,里面包含不同难度的任务、预期路径、期望结果。

如果没有评测集,你根本无法回答“我的 Agent 这次改动是变好了还是变坏了”。这也是 Agentic 项目早期最容易踩的坑。

2.3 成本与延迟失控

一个复杂任务可能要调用 5~10 次 LLM,每次几千 Token,算下来一次请求的成本是传统 API 调用的几十倍。如果 Agent 还在错误路径上循环,成本就更高。

延迟也一样,多轮串行调用会让用户感觉“卡了很久”。实践中需要限制最大步数、配置超时,以及把简单的流程直接做成固定代码,而不是交给 Agent 去“思考”。

2.4 工具层不稳定

Agent 能力再强,也要依赖底层工具。工具本身的返回值格式变化、接口超时、权限不足,都会让 Agent 走入“死胡同”。

比如你给 Agent 接了一个数据库查询工具,结果这个工具有时候返回[{"id":1}],有时候直接抛异常,Agent 很难从这种不一致中恢复。所以工具层的规范同样重要,需要有一个稳定的“工具封装层”,对上游返回做归一化。

3. 从“能跑”到“可控”:一个 Agentic RAG 的工程化实战

下面我们用一个 Agentic RAG 作为案例,看看怎么在工程上让 Agentic 系统更可控。

3.1 先理解 Agentic RAG 和传统 RAG 的区别

传统 RAG 是“检索—生成”的固定两步走:

  • 用户提问
  • 向量检索 TopK 文档
  • 将文档拼进 Prompt,让 LLM 生成回答

这种方式实现简单,但问题也明显:它不会判断“当前问题是否需要检索”,也不会自动处理多跳问题。比如用户问“去年 A 项目负责人现在负责什么项目”,需要先查 A 项目的负责人,再查该负责人的当前项目,传统 RAG 做不了这种多步推理。

Agentic RAG 则在传统 RAG 外面套了一个“规划层”:

  • 模型先判断问题是否需要检索,还是直接回答。
  • 如果需要检索,再决定是查向量库、查结构化数据库,还是先执行一次工具调用。
  • 每一步的结果都会被观察,然后决定继续还是终止。

这样就可以根据问题动态切换检索策略,甚至把多个工具串联起来。

3.2 场景设计

我们设计一个最小可用的 Agentic RAG 场景:

  1. 用户输入一个问题。
  2. Agent 判断问题是否需要检索。
  3. 如果需要,Agent 调用“文档检索工具”。
  4. 如果文档检索结果不足,Agent 还可以调用“网络搜索工具”(这里用 mock 数据代替)。
  5. 最终根据所有证据生成回答。

为了不让示例过于复杂,我们用 Python 实现一个简化版 Agent 循环。

3.3 代码:一个极简 Agent 执行循环

下面的代码演示 Agent 的核心循环,不依赖任何特定 Agent 框架,只使用大模型的chat/completions接口(这里用 OpenAI 风格的接口示意,实际需要按你的模型服务调整)。

# agent_loop.py # 一个极简 Agent 执行循环,思路演示 import json from openai import OpenAI client = OpenAI() # 按你的环境设置 base_url 和 api_key TOOLS = [ { "type": "function", "function": { "name": "retrieve_docs", "description": "从内部文档库检索与问题相关的资料", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "检索关键词"} }, "required": ["query"] } } }, { "type": "function", "function": { "name": "web_search", "description": "搜索公开网络信息,作为补充证据", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "搜索关键词"} }, "required": ["query"] } } } ] def retrieve_docs(query: str) -> str: # 实际项目中这里会调用向量数据库 mock_docs = { "项目": "Agentic RAG 项目于 2025 年启动,目标是实现动态检索。", "负责人": "当前负责人是张三。", } result = [v for k, v in mock_docs.items() if k in query] return "\n".join(result) if result else "未找到内部文档。" def web_search(query: str) -> str: # 实际项目中这里会调用搜索 API,此处用 mock 数据 return "公开信息:Agentic RAG 是检索增强生成与 Agent 决策能力的结合。" def run_tool(tool_name: str, args: dict) -> str: if tool_name == "retrieve_docs": return retrieve_docs(args["query"]) if tool_name == "web_search": return web_search(args["query"]) return "未知工具" def agent_run(user_input: str, max_steps: int = 5) -> str: messages = [{"role": "user", "content": user_input}] step_count = 0 while step_count < max_steps: response = client.chat.completions.create( model="gpt-4o-mini", # 按实际模型调整 messages=messages, tools=TOOLS, tool_choice="auto", ) message = response.choices[0].message messages.append(message) # 如果模型没有要求调用工具,说明可以输出最终结果 if not message.tool_calls: return message.content # 执行工具调用 for tool_call in message.tool_calls: tool_name = tool_call.function.name args = json.loads(tool_call.function.arguments) print(f"[Step {step_count}] 调用工具: {tool_name}, 参数: {args}") observation = run_tool(tool_name, args) print(f"[Step {step_count}] 工具返回: {observation[:100]}") messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": observation, }) step_count += 1 return "已达到最大步数,停止执行。" if __name__ == "__main__": result = agent_run("请帮我查一下 Agentic RAG 项目的负责人是谁?") print("最终回答:", result)

这段代码里最关键的是while循环:

  1. 将用户输入和工具返回结果都追加到messages
  2. 每次让模型判断是调用工具还是直接结束。
  3. 如果调用工具,就执行run_tool并把结果返回给模型。
  4. 设置max_steps,防止模型无限循环。

在真实项目中,通常不建议自己手写循环,而是使用 LangChain、LangGraph、Dify 等项目,它们的核心价值是已经帮你处理了状态管理、工具调用和错误处理,但上面的思路是通用的。

3.4 代码:工具层的返回值归一化

工具返回不统一,是 Agent 踩坑的高频原因。下面这个示例展示如何用标准结构包装工具输出:

# tool_wrapper.py from dataclasses import dataclass from typing import Any @dataclass class ToolResult: success: bool data: Any error: str = "" def wrapped_retrieve_docs(query: str) -> ToolResult: try: docs = retrieve_docs(query) if not docs: return ToolResult(success=False, data=None, error="检索结果为空") return ToolResult(success=True, data=docs) except Exception as e: return ToolResult(success=False, data=None, error=str(e)) def run_tool_with_unified_result(tool_name: str, args: dict) -> ToolResult: if tool_name == "retrieve_docs": return wrapped_retrieve_docs(args["query"]) # 其他工具类似 return ToolResult(success=False, data=None, error="未知工具")

为什么这很重要?因为当工具返回结构统一之后,你可以把successerror拼进 Prompt,让模型知道“这次调用失败了,要不要换一个方式”,而不是让模型对着一段莫名其妙的报错信息瞎猜。

归一化之后,Agent 的系统提示词中可以增加一条约束:

如果工具调用失败,请阅读 error 字段,并尝试换一个关键词重试,最多重试一次;若仍然失败,则明确告知用户无法完成该请求。

3.5 代码:记录执行轨迹和基础评估

可观测性,是 Agentic 系统落地的基本功。下面用一个极简例子,记录每一步的输入输出:

# trace_and_eval.py import json import uuid import time from collections import defaultdict class AgentTracer: def __init__(self): self.records = [] def record_step(self, step_type: str, content: dict): self.records.append({ "time": time.time(), "step_type": step_type, "content": content, }) def save(self, path: str = "agent_trace.json"): with open(path, "w", encoding="utf-8") as f: json.dump(self.records, f, ensure_ascii=False, indent=2) # 使用示例 tracer = AgentTracer() tracer.record_step("llm", {"role": "assistant", "content": "需要检索"}) tracer.record_step("tool", {"tool": "retrieve_docs", "args": {"query": "项目"}}) tracer.record_step("result", {"content": "Agentic RAG 项目于 2025 年启动"}) tracer.save()

评估层面的核心思路是:准备 20~50 条典型问题,每条标注“期望的关键步骤”和“期望答案”,然后运行 Agent,检查关键步骤是否被覆盖。

下面是一个简化评估函数:

# simple_eval.py def evaluate_agent(agent_fn, test_cases: list[dict]) -> dict: correct = 0 for case in test_cases: result = agent_fn(case["input"]) # 这里用最朴素的判断:期望关键词是否出现在结果中 if all(keyword in result for keyword in case["expected_keywords"]): correct += 1 total = len(test_cases) return { "accuracy": correct / total if total else 0, "correct": correct, "total": total, } test_cases = [ {"input": "Agentic RAG 项目的负责人是谁?", "expected_keywords": ["张三"]}, {"input": "什么是 Agentic RAG?", "expected_keywords": ["检索增强生成"]}, ] print(evaluate_agent(agent_run, test_cases))

当然,真实项目里的评估会更复杂,需要评估工具调用是否合理、步骤是否冗余、最终结果是否忠实于证据。但核心思想是不变的:先定指标,再跑回归,再迭代。

4. Agentic 编程落地时的高频问题与排查思路

以下问题来自真实项目里常见的“Flop”现场。

问题现象常见原因解决思路
Agent 陷入无限循环,反复调用同一个工具没有设置最大步数或超时在循环中增加max_steps,并配置请求超时
工具调用参数格式错误模型生成的 JSON 参数不规范在工具 API 侧做 JSON 解析保护,失败时返回结构化错误
回答结果出现事实性错误模型过度依赖自身记忆,忽略检索结果在 Prompt 中强调“只能基于工具返回内容回答”
多个 Agent 任务间互相干扰全局共享上下文每个任务使用独立状态和消息列表
Token 成本飞涨多轮调用、每次注入大量历史消息设置上下文裁剪策略,只保留最近 N 轮和关键结果
线上行为与本地不一致随机采样参数设置不一致固定temperatureseed,并记录实际调用参数

排查建议按以下顺序:

  1. 先看 Trace,确认 Agent 每一步到底调了什么工具、模型输出了什么。
  2. 再复现 Prompt,用相同消息历史直接调 LLM,判断是模型决策问题还是工具问题。
  3. 如果是决策问题,修改 Prompt 或增加结构化约束。
  4. 如果是工具问题,先在工具层修复,而不是让 Agent 去“适应”错误。
  5. 最后跑一遍评测集,确认改动没有让其他场景退化。

5. 最佳实践:如何避免 Agentic 项目变成“Flop”

5.1 能确定的部分,不要交给 Agent

这是最重要的一条。

Agent 适合处理“步骤不固定、需要动态判断”的部分。如果是固定流程,比如“收到订单 -> 校验金额 -> 扣库存 -> 发通知”,直接用传统代码写死就好。Agent 的灵活性在这里反而是负担。

一个合理的系统设计是:

  • 传统代码负责稳定流程。
  • Agent 只负责“判断下一步走哪个分支”。
  • 分支内部仍然是确定性的函数调用。

5.2 让 Agent 学会说“做不到”

很多 Agent 项目失败,是因为模型在工具返回不充分时,仍然硬着头皮编答案。

在系统提示词中加入约束:

如果你没有找到足够的信息来回答用户,请直接回复“根据当前可用的信息,我无法回答该问题”,不要猜测或编造。

这句话看起来简单,但实际上能大幅减少幻觉。因为模型知道“承认不知道”是合法的输出,就不会为了完成任务而去虚构信息。

5.3 控制上下文长度和成本

每次工具调用后,把完整历史都塞给模型,很快就把 Token 打爆。建议在每轮调用前做上下文裁剪:

  • 移除已经过时的中间推理。
  • 只保留“用户问题、最新工具结果、最终结论”。
  • 长文档使用摘要或检索片段,而非原文传输。

5.4 安全与权限边界不能省

Agent 可能根据模型决策去调用危险工具。比如一个具备数据库写入能力的 Agent,一旦被提示词注入攻击,可能导致数据被修改。

安全建议:

  • Agent 执行敏感操作前,必须经过人工确认。
  • 工具层做好白名单,Agent 只能调用预先定义好的函数。
  • 所有权限遵循最小权限原则,不要给 Agent 一个“万能数据库管理账号”。
  • 对 Agent 的输入输出做敏感信息过滤。

5.5 建立评测集并持续回归

没有评测集的 Agent 项目,就像没有测试用例的 Web 项目,上线全靠感觉。

评测集至少包含:

  • 正常问题。
  • 需要多步工具调用的问题。
  • 工具返回空结果的问题。
  • 含有误导信息的问题。
  • 模型应该“拒答”的问题。

修改一次 Prompt 后,跑一遍评测集,效果不下降再发布。

6. 哪些场景适合 Agentic,哪些场景不适合

场景类型适合 Agentic?原因
文档问答(单跳)传统 RAG 就够了不需要动态规划,固定流程稳定性更高
多跳问答、跨系统任务适合需要动态判断下一步查什么数据
客户工单自动分类和初步回复适合类型多变,需要模型灵活决策
固定报表生成不适合流程固定,传统代码更可控
数据库智能运维高风险,需谨慎Agent 决策可能触发危险操作,必须有防护
代码自动修复适合辅助场景可以自动定位问题,但合入代码需人工审核
实时低延迟接口不适合多轮推理延迟不可控

这个表可以作为选型参考:如果任务包含多个工具、多个步骤,且步骤顺序不固定,Agent 才有价值;如果任务是一条直线走到底,别硬上 Agentic。

7. 下一步怎么学

如果你刚接触 Agentic 方向,建议按下面的顺序推进:

  1. 先理解大模型函数调用(Function Calling)的原理,这是 Agent 的基础能力。
  2. 手写一个最小 Agent 循环,跑通“模型选工具 -> 执行工具 -> 模型总结”的流程。
  3. 学习一个成熟编排框架,比如 LangGraph,理解状态图、节点、边、条件分支的概念。
  4. 做一个 Agentic RAG 项目,把检索、路由、多跳对话串起来。
  5. 加上 Trace 和 Eval,建立评测集,迭代两轮 Prompt。
  6. 再考虑生产化:超时、限流、缓存、权限、日志、监控。

Agentic Programming 不是一个马上能交付所有业务需求的技术,但它确实为“开放任务自动化”打开了一个新方向。与其争论它是不是 Flop,不如实际跑一个场景,用工程手段把不确定性控制住。真正被淘汰的,永远是只会写 Demo、不考虑稳定性、安全性和成本的人,而不是“Agent”这个方向本身。

如果这篇文章对你有帮助,建议先收藏,等你自己动手做 Agent 项目时,再回来对照排查表和实践建议。你目前在学 Agentic 的哪个阶段?遇到过什么翻车现场?欢迎在评论区交流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 6:55:57

从生成模型采样加速到计算与统计保证:c-Rectified Flow 理论解析

从计算保证到统计保证&#xff1a;c-Rectified Flow 的理论核心与实验验证指南 如果你接触过生成模型&#xff0c;这几年大概率会频繁听到 Rectified Flow 或者 Flow Matching。它们的共同目标是解决扩散模型采样的老大难问题&#xff1a;生成质量虽高&#xff0c;但推理阶段动…

作者头像 李华
网站建设 2026/9/1 22:06:45

从NumPy到Pandas再到量化项目:一条完整的数据分析学习路径

学数据分析时&#xff0c;Pandas 是绕不开的库&#xff0c;也是最容易让人半途而废的库。第一个原因很实际&#xff1a;不少教程把 NumPy、Pandas、Matplotlib 拆成独立章节&#xff0c;每个章节又单独讲 API&#xff0c;读者学完 NumPy 的 ndarray 后&#xff0c;并不知道它和…

作者头像 李华
网站建设 2026/9/4 1:02:09

Vue 3 + Vite:2026年主流前端技术栈完全指南

前言截至2026年&#xff0c;Vue 3市场占有率已超71%&#xff0c;搭配Vite构建工具的组合成为国内前端开发绝对主流方案&#xff0c;尤其适合与FastAPI等Python后端搭配使用。Vue 3自动生成的OpenAPI文档可直接导出TypeScript类型定义&#xff0c;与FastAPI的Pydantic模型形成完…

作者头像 李华
网站建设 2026/9/4 8:52:22

生日悖论与哈希碰撞:从概率原理到工程防碰撞实践

生日悖论听起来像一道概率脑筋急转弯&#xff0c;但它真正决定的是实际工程问题&#xff1a;随机 ID 什么时候会重复、验证码什么时候会撞车、自定义哈希什么时候会出现碰撞。别只盯着“单个值出现的概率很小”&#xff0c;更危险的是“两个值落在同一个集合里还恰好相同”。这…

作者头像 李华
网站建设 2026/9/10 3:04:10

雌激素的“雄性化”作用:从神经内分泌到性别二态性行为

最近在梳理神经内分泌相关研究资料时&#xff0c;遇到一个非常有意思且容易被初学者绕晕的问题&#xff1a;在大鼠和小鼠的大脑中&#xff0c;那些被认为带有“雄性特征”的性别二态脑区和行为&#xff0c;很多情况下是由雌激素塑造出来的&#xff0c;而不是大家直觉上以为的雄…

作者头像 李华
网站建设 2026/9/3 2:01:05

拼多多笔试真题-多多的GPU批处理调度(C++/Py/Java /Js/Go)

多多的GPU批处理调度 拼多多技术岗 7月19号笔试 第二题 拼多多真题目录点击查看: 拼多多 春招&秋招 笔试真题题库目录|笔试题库 + 算法考点详解 题目内容 多多是一个大模型架构师,在部署大语言模型时为了提高 G P U GPU GPU 的利用率,推理引擎通常会将多个用户的请求…

作者头像 李华