ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从Chatbot到智能Agent:为什么多数AI项目仍停留在落地第一阶段?

从Chatbot到智能Agent:为什么多数AI项目仍停留在落地第一阶段? 为什么做了几十个Agent可能仍然只是AI落地第一阶段最近在技术社群里看到不少团队分享自己的 Agent 项目有做客服机器人的有做代码审查助手的也有做自动化运维Agent的。大家普遍有一种感觉Demo 很好跑POC 也能过但真正要放到生产环境里总觉得差了一大截。我也做过不少 Agent 相关的开发早期用 Prompt 模板 函数调用后面开始引入工作流编排、状态管理、长期记忆。回头复盘这些项目发现一个很扎心的事实即使做了几十个 Agent很多团队其实仍然停留在 AI 落地第一阶段距离真正的“智能化系统”还有不小距离。这篇文章想从技术角度拆一拆这件事。我会先给 Agent 的能力做一个分级然后分析第一阶段 Agent 的典型特征接着讲清楚为什么多数项目会卡在第一阶段最后给出向第二阶段演进的具体路径和代码示例。1. 先搞清楚什么是真正的 Agent1.1 Agent 不是一个 Chatbot很多开发者在聊 Agent 时实际上聊的还是 Chatbot。两者有本质区别维度ChatbotAgent交互方式一问一答多轮任务驱动记忆能力单轮或短期长期记忆 状态管理工具使用很少或没有主动调用外部工具 API决策方式固定规则或模型直接输出规划 反思 执行循环目标导向回答用户问题拆解并完成一个复杂任务换句话说Chatbot 是“你来问它来答”Agent 是“你给目标它想办法完成”。一个合格的 Agent 应该具备感知、决策、行动、反思这四个核心能力。感知是接收外部输入并理解上下文决策是根据目标和当前状态选择行动方案行动是调用工具或 API 去执行反思是观察执行结果并决定下一步动作。如果你做的“Agent”只是给大模型套了一层 API 包装用户问一句、你调一次模型、返回一个答案那它本质上仍然是一个增强版 Chatbot。1.2 Agent 的能力分层为了更清晰地讨论问题我先把 Agent 的能力分成五个层级L1单轮工具调用。用户提问模型判断需要调用什么工具执行后返回结果。这是最基础的 Agent 形态。L2多步任务编排。模型能够将复杂任务拆成多个步骤并依次执行但每一步之间没有状态共享或依赖管理。L3带状态的自适应执行。Agent 维护任务状态能够根据中间结果动态调整后续步骤支持失败重试和路径修正。L4长期记忆与学习。Agent 能从历史任务中提取经验跨会话保留用户偏好、领域知识持续优化自身行为。L5多 Agent 协同。多个 Agent 分工协作各自承担不同角色通过消息通信完成一个复杂系统级目标。从我自己观察到的项目现状来看80% 以上的 Agent 项目集中在 L1 和 L2能够稳定达到 L3 的比较少做到 L4 和 L5 的更是凤毛麟角。但问题在于很多团队并没有意识到自己停留在 L1/L2反而觉得“Agent 已经落地了”。2. 第一阶段 Agent 的典型特征所谓“第一阶段”我定义的是L1 到 L2 这个区间。这个阶段的 Agent 项目通常具备以下四个非常明显的特征。2.1 工具调用是核心但只有工具调用第一阶段 Agent 最典型的表现有一个 ReAct 循环或 Function Calling 机制大模型能够从预定义的工具列表里选一个来调用。伪代码大概是这样的def run_agent(user_query): messages [{role: user, content: user_query}] while True: response llm.chat(messages, toolsTOOL_SCHEMAS) if response.tool_calls: # 执行工具调用 tool_result execute_tool(response.tool_calls[0]) messages.append(response) messages.append({ role: tool, content: tool_result }) else: return response.content这个循环本身没有错它是 Agent 基础能力的核心。但如果整个系统只有这个循环没有任务拆解、没有状态管理、没有执行计划那么它仍然只是“带工具的对话模型”。这类 Agent 能处理的任务边界也很明显只要用户需求超出预定义工具的表达范围它就宕机了。比如你定义了查询天气、设置提醒、搜索资讯三个工具用户说“帮我规划一下周五去杭州出差顺便查一下那边的天气”Agent 就会比较吃力因为它不知道要先查日历、再查交通、再关联天气信息。2.2 状态管理缺失或极其薄弱第一阶段的 Agent 大多数是无状态的Stateless或者只有简单的临时上下文。每次用户请求进来Agent 会把 Prompt 历史消息 工具定义一起发给大模型。模型本身不会记忆上一次任务的状态所有上下文都在请求里传递。这在单轮工具调用场景下没有问题但一旦任务变得复杂就会出问题任务执行到一半上下文长度超限。多个任务之间无法共享中间数据。无法理解“上一轮你说机票已订好那现在帮我订酒店”这类依赖型指令。真正的 Agent 需要维护一个 Task State记录当前目标、已完成步骤、中间产物、剩余动作。这个状态可以放在内存里也可以持久化到 Redis 或数据库中。2.3 规划能力依赖大模型“临场发挥”第一阶段 Agent 的另一个典型问题是没有独立的规划模块规划工作全部交给了大模型的上下文理解能力。用户给一个目标模型直接在 ReAct 循环里一步步尝试走一步看一步。如果模型在某个环节产生幻觉或误判Agent 就会跑偏而且很难自纠。因为没有全局计划模型并不知道“我原本打算做五步现在才走到第二步方向偏了”。高阶一点的 Agent 会先让模型输出一个 Plan然后按 Plan 执行def create_plan(user_query): prompt f 你是一个任务规划器。请把以下用户目标拆解为3-5个可执行的步骤。 每个步骤必须能够调用现有工具完成且步骤之间要有依赖关系。 用户目标: {user_query} 可用工具: {TOOL_DESCRIPTIONS} 请输出JSON格式的计划: {{ steps: [ {{id: 1, description: ..., tool: ..., depends_on: []}} ] }} # 调用模型解析计划但即使输出了 Plan如果执行过程中遇到计划外的反馈很多 Agent 也不会动态调整计划而是强行按原计划走最终把任务做歪。2.4 记忆能力为零第一阶段 Agent 通常没有持久化记忆。每次对话都是一次全新的开始Agent 不记得用户之前提过什么偏好不记得上次任务做到哪里也不从过去的错误中学习。举个例子用户上次要求“报告用 Markdown 格式输出”下一次 Agent 依然会输出纯文本。用户上次明确说“不要调用第三方搜索API直接用内部数据库”下次 Agent 还是会优先选择第三方工具。为什么很多 Agent 项目在 Demo 阶段看着很好上线后就变“智障”核心原因之一就是没有记忆。Demo 的时候用户会顺着 Agent 的路径走生产环境下用户的需求是开放的没有记忆的 Agent 每次都在盲人摸象。3. 为什么做了几十个 Agent仍然在第一阶段与其说“不会做”不如说“没意识到要往下一阶段走”。我整理了三个层面的原因。3.1 技术层面工具链成熟度高但系统能力门槛陡增目前的主流 Agent 开发框架比如 LangChain、LlamaIndex、AutoGen、Spring AI 以及各类国产 Agent 平台都已经把 L1/L2 能力封装得非常成熟。开发者只需要定义几个工具函数写一段 ReAct 循环就能跑起来一个 Agent。但也正因为框架把工具调用做得太好导致很多人误以为“Agent 开发不过如此”。到了 L3 以上事情开始变得复杂需要设计任务状态机。需要一套存储方案来保存任务中间状态。需要处理模型输出不稳定带来的状态污染。需要设计失败重试、超时熔断、上下文裁剪策略。这些内容超出了框架本身的能力范围需要开发者有分布式系统设计经验。很多团队在这个环节会发现复杂度不是线性增长而是指数级增长。3.2 工程层面POC 容易生产级很难我可以负责任地说做一个功能演示级别的 Agent可能只要两天。但把它做成一个生产级系统可能需要两个月甚至更久。生产级意味着什么高可用模型 API 不稳定时怎么办要不要做降级方案可观测Agent 内部推理过程如何追踪如何排查一个错误决策数据安全Agent 获取的数据权限如何控制工具调用是否需要审批成本控制一次复杂任务可能调用几十次模型 API费用怎么管控结果一致性模型输出不稳定如何做结果校验和兜底这些工程问题每一个都足以让一个 Agent 项目从“看起来不错”变成“根本不敢上线”。很多团队被这些问题卡住之后会不自觉地退回第一阶段只做最小可用闭环结果就是做了几十个 Agent每一个都浅尝辄止。3.3 认知层面把 Transformer 上下文当成系统记忆还有一个很隐蔽的原因不少团队把大模型的 Context Window 当成了 Agent 的记忆系统。大模型确实有一个很大的上下文窗口但它的本质是“当前任务的临时工作区”不是长期存储。把上下文窗口当记忆就像把 CPU 寄存器当硬盘用——容量有限、掉电即失、无法共享。一个只依赖上下文的 Agent会话一结束就失忆。它无法回答“上周我让你分析的数据集这周我又更新了按同样的口径再分析一次”因为它的上下文里根本没有上周的信息。如果团队在认知上不区分“上下文”和“记忆”那么无论开发多少 Agent都只是在同一层做重复建设永远进入不了下一阶段。4. 第二阶段 Agent 需要具备的四个核心能力要想从第一阶段走出来我建议重点构建以下四个能力。4.1 任务状态机从无状态到有状态一个真正的 Agent 应该有显式的任务状态机用来追踪整个任务的执行生命周期。一个通用的任务状态定义如下# 文件路径agent/task_state.py from enum import Enum from dataclasses import dataclass, field from typing import Any, Dict, List class TaskStatus(Enum): PENDING pending # 待处理 PLANNING planning # 规划中 EXECUTING executing # 执行中 WAITING waiting # 等待外部输入 COMPLETED completed # 已完成 FAILED failed # 失败 dataclass class TaskState: task_id: str user_goal: str status: TaskStatus plan: List[Dict[str, Any]] field(default_factorylist) current_step: int 0 memory: Dict[str, Any] field(default_factorydict) created_at: float field(default_factorytime.time) updated_at: float field(default_factorytime.time)每一步工具执行的结果都写入memory字段后续步骤可以从 memory 中读取中间产物而不需要重新调用模型生成。4.2 长期记忆向量数据库 结构化存储长期记忆需要分层设计对话记忆保存用户和 Agent 的交互记录用于多轮对话场景。用户偏好记忆记录用户的显式偏好和模型推断出的偏好比如“用户喜欢简洁回答”“用户常用 Python”。任务经验记忆记录历史任务的目标、计划、执行过程和结果当遇到相似任务时可以复用。对于非结构化文本记忆使用向量数据库是常见方案# 文件路径agent/memory/vector_memory.py from typing import List import chromadb from chromadb.utils import embedding_functions class VectorMemory: def __init__(self, collection_nameagent_memory): self.client chromadb.Client() self.collection self.client.get_or_create_collection( namecollection_name, embedding_functionembedding_functions.DefaultEmbeddingFunction() ) def save_memory(self, memory_id: str, text: str, metadata: dict None): 保存一段长期记忆。 参数说明: - memory_id: 记忆的唯一ID用于更新或删除。 - text: 记忆内容。 - metadata: 额外的结构信息如任务类型、用户ID等。 self.collection.upsert( ids[memory_id], documents[text], metadatas[metadata or {}] ) def search_memory(self, query: str, top_k: int 3) - List[str]: 根据当前输入检索相关记忆。 results self.collection.query( query_texts[query], n_resultstop_k ) return results[documents][0]长记忆数据的更新策略需要注意生产环境建议对敏感记忆做脱敏存储并遵循最小必要原则避免把用户的隐私信息不加处理地写入外部存储。4.3 自主规划与动态修正第二阶段 Agent 的规划模块不应该只是“让模型输出一个 JSON 计划”而应该是一个独立模块负责将用户目标转为可执行步骤。对每个步骤评估是否需要工具调用。在执行过程中监控步骤状态。当某个步骤执行失败时重新规划后续路径。这里有一个很关键的设计思路规划和执行应该解耦。模型只负责生成候选计划而是否采纳计划、是否调整计划由代码逻辑决定而不是继续让模型“看着办”。# 文件路径agent/planner.py class Planner: def __init__(self, llm, tools): self.llm llm self.tools tools def generate_plan(self, user_goal: str, context: dict) - list: 根据用户目标和现有上下文生成任务计划。 返回一个步骤列表每个步骤包含: - step_name: 步骤名称 - tool: 需要调用的工具名 - input_template: 从上下文中生成工具输入的模板 - fallback: 失败时的替代方案 prompt self._build_planner_prompt(user_goal, context) plan_json self.llm.complete(prompt, response_formatjson) return self._validate_and_normalize(plan_json) def revise_plan(self, original_plan: list, current_step: int, failure_reason: str) - list: 当某一步执行失败时根据失败原因对计划进行局部修正。 # 只重新规划失败步骤之后的子任务 sub_goal self._extract_remaining_goal(original_plan, current_step) new_plan self.generate_plan(sub_goal, {failure_reason: failure_reason}) return original_plan[:current_step] new_plan4.4 自省机制让 Agent 能够评估自己的输出第二阶段 Agent 还需要一个 Evaluate 环节。每一步工具调用完成后Agent 要回答三个问题结果是否符合预期当前状态是否与计划一致是否出现了计划外的信息需不需要调整目标自省机制不一定要额外调用一次大模型也可以通过规则检查。例如工具返回的数据结构校验、必填字段是否缺失、结果与预期值的偏差范围。对于复杂任务可以先让一个轻量级模型做结果评估再决定是继续执行还是重试。# 文件路径agent/evaluator.py def evaluate_step_output(step_name: str, expected: dict, actual: dict) - bool: 验证工具输出是否符合预期。 示例规则: 1. 必须包含status字段。 2. status必须为success。 3. 如果步骤要求返回数据列表列表不能为空。 if status not in actual: return False if actual[status] ! success: return False if expected.get(required_list_field) and not actual.get(expected[required_list_field]): return False return True5. 从第一阶段走向第二阶段的落地示例下面用一个真实的简化例子来串一遍。假设我们要做一个“竞品分析 Agent”用户提供竞品名称Agent 自动完成信息收集、数据整理、生成报告三个步骤。5.1 第一阶段写法单循环一把梭# 文件路径agent/v1/simple_agent.py # 注意这是第一阶段的简化实现用于对照讲解 import json from openai import OpenAI client OpenAI() TOOLS [ { type: function, function: { name: search_web, description: 搜索指定关键词并返回搜索结果, parameters: { type: object, properties: { query: {type: string, description: 搜索关键词} }, required: [query] } } }, { type: function, function: { name: generate_report, description: 根据分析数据生成Markdown报告, parameters: { type: object, properties: { data: {type: object, description: 分析数据} }, required: [data] } } } ] def execute_tool(name, args): if name search_web: return {status: success, data: f关于{args[query]}的仿真搜索结果} if name generate_report: return {status: success, data: f# 竞品分析报告\n\n{json.dumps(args[data], ensure_asciiFalse)}} return {status: error, data: 未知工具} def run_v1_agent(user_query): messages [ {role: system, content: 你是一个智能助手。}, {role: user, content: user_query} ] for _ in range(5): # 限制最多5轮 response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolsTOOLS ) msg response.choices[0].message if msg.tool_calls: for tc in msg.tool_calls: result execute_tool(tc.function.name, json.loads(tc.function.arguments)) messages.append(msg) messages.append({ role: tool, tool_call_id: tc.id, content: json.dumps(result, ensure_asciiFalse) }) else: return msg.content return 执行步骤过多已终止这段代码的问题非常明显所有的任务路径都在模型上下文里隐式流转没有计划、没有状态、没有任务记忆。如果中间某一步搜索返回的结果格式变化整个任务就可能中断。5.2 第二阶段写法状态机 规划 校验下面是第二阶段的核心实现片段思路比完整实现更值得借鉴# 文件路径agent/v2/analysis_agent.py # 这是一个结构化Agent的骨架示例 from task_state import TaskState, TaskStatus from planner import Planner from evaluator import evaluate_step_output class CompetitiveAnalysisAgent: def __init__(self, llm, tool_executor): self.llm llm self.tools tool_executor self.planner Planner(llm, tool_executor.get_tool_schemas()) self.task_state None def run(self, user_goal: str) - TaskState: # 1. 初始化任务状态 self.task_state TaskState( task_idgenerate_id(), user_goaluser_goal, statusTaskStatus.PLANNING ) # 2. 生成初始计划 plan self.planner.generate_plan(user_goal, context{}) self.task_state.plan plan # 3. 逐步执行计划 for step_index, step in enumerate(plan): self.task_state.current_step step_index self.task_state.status TaskStatus.EXECUTING # 3.1 从记忆/上下文中准备工具输入 tool_input self._prepare_tool_input(step) # 3.2 执行工具调用 result self.tools.execute(step[tool], tool_input) # 3.3 校验结果 expected step.get(expected_output, {}) if not evaluate_step_output(step[tool], expected, result): # 执行失败触发计划修正 new_plan self.planner.revise_plan( original_planself.task_state.plan, current_stepstep_index, failure_reasonresult.get(error, unknown) ) self.task_state.plan new_plan continue # 3.4 将中间结果写入任务记忆 self.task_state.memory[step[step_name]] result[data] # 4. 生成最终报告 self.task_state.status TaskStatus.COMPLETED return self.task_state可以看到第二阶段的代码并不复杂到难以落地核心在于把原来靠“模型临场发挥”的部分变成了由代码掌控的显式流程。这个转变是第一阶段到第二阶段的分水岭。5.3 关键区别对照用两个不同阶段实现对比读者能更容易理解差异设计维度第一阶段 Agent第二阶段 Agent任务计划模型在上下文中隐式生成显式的 Plan 数据结构状态保存无状态上下文即状态TaskState 持久化存储失败处理重试整个循环局部重新规划结果校验没有规则 轻量模型校验长期记忆无向量数据库 结构化记录6. 团队做 Agent 常见的误区与排查清单6.1 误区“Agent 效果不好就换更大的模型”遇到 Agent 效果不佳很多团队第一反应是升级模型从 7B 换 70B从开源模型换商业大模型。模型能力确实重要但大多数 Agent 失败的根因不在模型而在系统设计。如果你没有任务状态管理换再大的模型也会在长任务中迷失。如果你没有结果校验换再大的模型也会一本正经地输出错误内容。如果你没有记忆系统换再大的模型也不会记得用户偏好。我建议按下面的排查顺序来检查 Agent 项目排查项检查方式调整方向任务目标是否明确看 System Prompt 是否包含目标和边界重构 Prompt明确目标定义工具描述是否清晰检查工具 schema 里的 description补充参数示例、返回格式、边界情况状态管理是否存在看是否有 TaskState 或类似结构引入状态管理模块结果是否经过校验检查工具调用后是否有校验逻辑增加规则校验和评估器长期记忆是否接入看是否有持久化存储增加向量记忆模块失败路径是否有兜底看是否有重试、降级、重新规划增加失败处理策略6.2 误区“Agent 越自动化越好”很多开发者的目标是“用户给一个指令Agent 全自动完成”。这个目标本身没错但在当前模型能力下盲目的全自动会带来极大的不可控风险。更务实的做法是人机协同高确定性环节自动化执行。低确定性环节Agent 给出候选方案由人来确认。高影响操作删除数据、转账、发布内容必须增加人工审批节点先让 Agent 生成操作方案审批通过后再执行。不可逆操作必须先沙箱演练或预检确认安全后再在生产环境执行。这里有一点需要特别强调涉及生产环境变更、数据删除、权限修改等敏感操作时必须遵循最小权限原则。Agent 使用的 API Key 和账号应该只具备完成任务所需的最低权限并且所有高影响操作都要有审计日志。建议在开发阶段就建立一套工具调用审批流而不是等到出现问题后再补。6.3 Agent 安全边界最近关于 Agent 安全的讨论也多了起来。很多攻击者会利用 Prompt 注入来操控 Agent 执行未授权的操作。常见的安全风险包括恶意工具描述注入。外部网页内容包含恶意指令。工具返回结果中夹带 prompt injection。Agent 权限过宽导致横向移动。开发 Agent 时的安全基线建议如下表风险类型安全实践Prompt 注入对外部输入做分类和隔离不直接拼接进 System Prompt工具权限对工具调用做白名单和审批机制限制敏感操作数据泄露对发送给模型的 Prompt 做脱敏避免传入不必要的信息资源消耗设置工具调用次数上限和超时控制防止无限循环过期审计追踪记录每次工具调用的输入输出便于安全审查7. 从第一阶段到更高阶段的学习路线建议如果你所在的团队正在做 Agent但发现自己还在第一阶段不要焦虑这是大多数团队的真实状态。重要的是要有清晰的进阶路径。第一步把工程基础打牢。先把任务状态管理、工具调用规范、结果校验、日志追踪这些基础能力做扎实。这个阶段不要追求花哨的“自主规划”“自我进化”先把确定的部分做稳定。第二步引入长期记忆。选择一款趁手的向量数据库设计好记忆的写入、检索和更新流程。最关键的是设计好记忆的 Schema思考清楚什么信息值得存、存多久、如何更新。第三步实现规划与执行的解耦。把 Agent 从“一步一试探”改造成“先生成计划、按计划执行、失败再规划”的闭环。这个阶段你会明显感觉到 Agent 的任务完成率有一个跳跃式提升。第四步探索多 Agent 协作。当单 Agent 无法处理复杂任务时再考虑多 Agent 架构。把一个大型任务拆成多个子任务由不同的 Agent 分工完成。多 Agent 的核心设计是通信协议和任务分配机制而不是简单的“多个 ReAct 循环并行跑”。此外当前 Agent 开发框架演进非常快。市面上有 LangChain、AutoGen、Spring AI以及各类 Agent 平台。框架能帮你省去不少重复工作但对框架的能力边界要有清醒认知。框架给你的是“积木”但怎么设计一个稳定可靠的系统仍然取决于你自己的工程能力。8. 总结真正拉开差距的不是模型而是系统设计能力回到文章标题为什么做了几十个 Agent可能仍然只是 AI 落地第一阶段我觉得答案已经比较清晰了。因为Agent 开发的门槛被框架大幅降低了但 Agent 系统落地的门槛并没有降低。工具调用、函数路由、ReAct 循环这些只是 Agent 的外壳。真正的内核是状态管理、记忆系统、规划能力、结果校验、安全机制和工程稳定性。团队如果只停留在“模型能输出 JSON、能调用工具、能跑通 demo”的层面那么无论做多少个 Agent都只是在第一阶段反复徘徊。每次项目看似是“新的 Agent”实际只是换了一组 Prompt 和工具定义的“同一种 Agent”。相反如果一个团队能把下面这几件事做好有显式的任务状态机能管理复杂任务有分层记忆系统Agent 能持续学习有规划与执行解耦的架构Agent 能应对异常有严格的安全和审计机制Agent 能放心上岗那么哪怕只做了一两个 Agent也已经站在了 AI 落地的更靠前的位置。Agent 的终局不是“更多”而是“更稳”。下一阶段一起把状态、记忆和规划这三座地基打好。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进