去年我接到一个任务一个月内交付一个能自动处理客服工单的AI Agent。一开始我还挺乐观觉得把提示词、工具函数、聊天循环写在一个脚本里就完事了。结果第二周就发现这个思路根本撑不住——同一个业务要换模型、加渠道、做权限隔离还要拆成多个“数字同事”并行处理那堆用if-else拼起来的代码很快就变成没人敢碰的泥潭。后来我把代码重构成了一个“能生产Agent的平台”事情才真正转起来。这篇文章想聊的就是这条从0到1搭建AI Agent平台的完整路线为什么需要平台、Agent和LLM之间到底什么关系、平台该怎么分层、第一版程序该怎么写以及我踩过的那些让Agent“跑不稳”的坑。适合两类人读一是刚接触Agent开发、想找个靠谱起点的工程师二是在企业里想把Agent落地成团队资产、而不是停留在玩具Demo的人。1. 为什么我管Agent平台叫“工厂”而不是“框架”1.1 手工作坊式开发与流水线生产的区别先说我踩过的第一个坑。刚开始写单个Agent时我会为每一个新场景从零写一套循环读用户输入、拼System Prompt、循环调用模型、解析工具返回结果。第一个客服Agent做出来的时候感觉很爽第二个知识问答Agent也还行到第三个、第四个的时候光是把每个Agent的“性格设定”“工具开关”“最大步数”散落在不同代码文件里就已经让我头疼了。单写一个Agent很像手工作坊你为某个特定岗位量身定制一套流程交付之后基本没有复用。换个人接手他要重新读一遍代码才能搞懂这个Agent“为什么这么干”。而平台化改造之后核心逻辑变成了一条流水线Agent的定义是配置工具是注册进去的零件运行时是统一的传送带新的Agent只是往生产线上放一份新的“岗位说明书”。所以我把这套东西叫“工厂”而不是“框架”。框架解决的是代码复用工厂解决的是“批量生产可治理的Agent”。如果你只打算做一个演示性质的Agent那框架就够用了但如果你想让多个Agent在一个团队里长期协作、被人持续维护和审计没有工厂逻辑会很痛苦。1.2 市面上的AI Agent产品到底谁是谁很多刚接触这个领域的同学会问“AI Agent有哪些产品”这个问题其实很宽泛我习惯把它们分成三类来看类型代表产品/工具一句话定位底层模型 / LLMDeepSeek、GPT系列、Claude、Gemini、Qwen等提供“思考”能力是大脑而不是Agent本身成品Agent应用Manus、ChatGPT的Tasks/Deep Research、Claude Code、Codex等已经帮你封装好完整Agent流程拿来即用Agent开发平台/框架LangGraph、Pydantic AI、CrewAI、MetaGPT、Dify、Coze、Spring AI等帮你造Agent相当于“生产AI同事的机床”这三者经常被混着讲。比如有人说“我用DeepSeek开发了一个Agent”这句话准确的说法是“我以DeepSeek作为Agent的大脑搭了一套Agent应用”。搞清楚这个分类后续做技术选型时就不会拿模型去跟框架比。1.3 平台真正解决的三个问题我复盘过后发现平台化带来的核心价值可以收敛成三点。第一是定义复用。一个Agent不再是一段写死的代码而是一份配置。这份配置可以放在Git里评审、版本化、回滚换环境部署时直接从配置重建。第二是工具统一接入。订单查询、天气查询、内部API这些能力都通过一套工具注册机制进入平台。Agent只看到“工具名参数Schema”不需要关心工具背后是HTTP调用还是本地函数。第三是治理和观测。每一次Agent调用模型、每一次工具调用结果、每一步思考过程都该留日志。平台化之后这些是默认能力而不是靠程序员自觉补齐。没有这三点你拥有的只是十个互相没有关系的脚本而不是一个能持续演进的Agent平台。2. 先补一堂概念课Agent、LLM、AI模型的边界与关系2.1 三者在一条产业链上的位置我遇到很多刚入门的同学会把“AI模型”“LLM”“Agent”当成同义词。它们确实有关系但位置完全不同。可以把AI模型想象成“发动机”。发动机有很多种汽油发动机、柴油发动机、电动机LLM只是其中一种适合处理语言任务的“发动机”。而Agent不是一个发动机它更像是“装上了发动机、还带着地图和工作台的工人”。工人需要发动机提供动力但工人还知道什么时候该踩油门、什么时候该看地图、什么时候该用扳手。这个类比对应到技术上就是LLM只能做“给定上下文预测下一个词”这件事。Agent则是在LLM外面套了一个循环——它把用户目标拆成步骤调用工具获取新信息再把结果喂回给LLM直到问题解决或达到上限。2.2 DeepSeek到底属于哪一类这是热词里被问得最多的一个DeepSeek属于哪一类直接说结论DeepSeek是一个LLM大语言模型不是AI Agent本身。很多人觉得DeepSeek能自己“思考”和“回答问题”所以它是Agent。这是误解。DeepSeek很强的地方在于推理和生成能力但它本身不会主动去调用外部系统、不会持久化记忆、不会在无人指挥时自己规划并执行一个多步骤任务。这些能力需要你在它外面搭一层Agent循环。你可以在项目里这样组合大脑DeepSeek记忆数据库或向量库工具订单系统API、企业微信机器人、搜索服务编排你自己写的一套循环或LangGraph、Dify、Spring AI这类平台只有当这四部分拼在一起这个系统才能被称为“一个AI Agent”。2.3 Agent的组成结构拆解不管用什么框架Agent的核心组成结构其实相当固定。我习惯拆成五块来理解感知接收用户输入、环境状态、工具返回结果。规划由LLM驱动把大目标拆成小步骤。常见模式是ReActReasoning Acting也就是“推理一下我怎么处理然后采取动作”。行动调用工具或外部API。这里的工具不一定是函数也可以是另一个Agent。记忆短记忆是当前会话消息长记忆是历史事实和知识库。反思与校验判断当前结果是否满足目标不满足就继续循环满足就停止。这五个部分合起来才形成大家常说的“Agent循环”。如果你去看LangGraph或者自研平台会发现底层都是围绕这几块在做工程化。2.4 那个被反复问的问题Codex能直接读别的Agent会话内容吗热词里有一条问“Codex可以直接读取其他AI Agent会话内容吗”。我的答案是默认不行但平台可以做。Codex是一个偏编码场景的Agent产品它默认只能访问你给它的上下文、仓库和配置好的工具。它没有权限跑到另一个Agent产品里翻聊天记录除非那个产品主动暴露了API并且你把“读取该API”作为一个工具交给了Codex。这也引出了平台设计里的一个重要原则跨Agent读取会话本质是权限问题不是能力问题。如果你希望“同事A”能查看“同事B”处理过的工单记录应该由平台统一提供会话查询API并通过Token鉴权控制访问范围。不要直接给Agent开数据库查询权限否则它一冲动什么都查。3. 工厂流水线长什么样平台的分层结构与选型清单3.1 一个可扩展Agent平台的分层设计我把平台分成五层每层只跟相邻层通信这样上层改动不会牵连底层。第一层是接入与会话层。负责接收来自网页、IM、API的请求把消息转换成一个统一的会话对象。它屏蔽掉渠道差异让后台的Agent只管处理“标准格式的输入”。第二层是模型网关层。所有LLM调用都走这一层不直接在业务代码里写死某个厂商的SDK。这一层负责路由、限流、缓存、成本统计和故障切换。有了它把Agent的底座从A模型切到B模型通常只是改一条配置。第三层是Agent运行时。这是最核心的编排引擎执行“调用LLM - 解析意图 - 调用工具 - 把结果返回LLM”的循环。运行时要对工具调用数量和步数做硬限制防止失控。第四层是工具与技能层。每个工具都是一个接口契约入参、出参、权限、超时都很明确。工具层独立部署或注册让不同Agent可复用同一套企业能力。第五层是记忆与知识层。它提供向量检索、持久化会话、长期事实存储等能力相当于给Agent建了一个“档案柜”。横跨所有层的还有日志、审计、指标、安全策略。你可以先在单机上把这五层跑通再逐步容器化。3.2 技术选型Python、Java还是低代码选型没有银弹我的建议是先看技术存量再看团队目标。如果你的团队主要在Python生态想深度控制Agent逻辑LangGraph和Pydantic AI都很合适。LangGraph擅长把多Agent流程定义成图Pydantic AI更轻量适合快速做工具调用。如果不想写太多底层代码Dify和Coze这类平台能让你用界面拼Agent适合先做业务验证。如果你们是Java为主的企业团队Spring AI是目前最顺手的路线。它把模型调用、Prompt模板、工具调用封装成Spring风格团队上手成本低。如果研究方向是多Agent角色扮演、任务自动拆解CrewAI和MetaGPT这类框架能帮你快速搭出“管理者执行者”结构。我在自己的练手项目里选择的是Python生态因为后续要频繁实验新的工具调用方式代码越薄越好。3.3 Agent的“岗位说明书”配置化定义平台化之后“新招一个同事”的动作应该从写代码变成“写配置”。我建议先用一份YAML定义Agentagent_id: order-service-bot name: 订单客服 model: deepseek-chat temperature: 0.2 instructions: | 你是订单后台的客服助手。 你需要礼貌、简洁地回应用户。 查询订单状态前必须调用 get_order_status 工具。 tools: - name: get_order_status description: 根据订单ID查询订单状态 parameters: order_id: string max_iterations: 6 model_timeout_seconds: 30这份配置就是“岗位说明书”。同一个Agent部署到测试环境可以接Mock数据部署到生产环境可以换真实工具因为工具接入是配置驱动的。3.4 模型网关为什么平台前面要有一层统一入口很多人一开始会直接在自己的Agent代码里调用某个模型的SDK比如client.chat.completions.create。单机Demo没问题但一旦有多个Agent、多个模型就会遇到三个麻烦每个Agent都要写一遍模型参数、鉴权逻辑。模型调用量涨起来后没法统一做成本预算。某一家模型服务不稳定时全局都要跟着改代码。模型网关就是把“调用模型”这件事收口。请求先到网关网关根据规则决定走哪个模型、有没有命中缓存、是否需要限流。我自建的一个轻量版本核心就是一个FastAPI服务对外暴露一个OpenAI兼容的/chat/completions接口内部再转发给真实模型厂商。这样App代码和模型厂商SDK彻底解耦。4. 第一版“造人”流程从零搭出最小可用Agent平台4.1 环境与依赖我建议先做一个小而能跑的平台不追求全功能。我用的是Python 3.10 FastAPI requests没有引入重量级框架方便你理解每一行代码在做什么。初始化项目mkdir agent-factory cd agent-factory python -m venv .venv source .venv/bin/activate pip install fastapi uvicorn requests pydantic这里解释一下选择FastAPI用来包HTTP接口requests用来调用模型API和模拟工具请求Pydantic用来定义Agent配置结构。先不装LangChain或LangGraph因为第一版只需要一个循环。4.2 定义Agent注册表平台的核心数据模型是AgentSpec。我用Pydantic定义它from pydantic import BaseModel, Field class ToolSpec(BaseModel): name: str description: str parameters: dict Field(default_factorydict) class AgentSpec(BaseModel): agent_id: str name: str instructions: str model: str deepseek-chat tools: list[ToolSpec] Field(default_factorylist) max_iterations: int 5 temperature: float 0.2把Agent放进全局注册表REGISTRY: dict[str, AgentSpec] {} def register_agent(spec: AgentSpec): REGISTRY[spec.agent_id] spec将来可以把注册表改成数据库存储但这个内存版足够跑通第一次实验。4.3 写一个不依赖特定SDK的运行时核心运行时核心负责循环调用模型。我用一个call_llm函数包装模型API它接收消息列表和可选工具定义返回OpenAI风格的响应对象。import json import os import requests LLM_BASE_URL os.getenv(LLM_BASE_URL, https://api.deepseek.com) LLM_API_KEY os.getenv(LLM_API_KEY, your-key-here) def call_llm(messages, toolsNone, modeldeepseek-chat, temperature0.2): payload { model: model, messages: messages, temperature: temperature, } if tools: payload[tools] tools payload[tool_choice] auto resp requests.post( f{LLM_BASE_URL}/chat/completions, headers{Authorization: fBearer {LLM_API_KEY}}, jsonpayload, timeout30, ) resp.raise_for_status() return resp.json()有了这个函数Agent循环可以写得很简洁def run_agent(spec: AgentSpec, user_messages: list[dict], tool_registry: dict): messages [{role: system, content: spec.instructions}] messages.extend(user_messages) tools [t.model_dump() for t in spec.tools] for step in range(spec.max_iterations): data call_llm(messages, toolstools, modelspec.model, temperaturespec.temperature) msg data[choices][0][message] messages.append({role: assistant, content: msg.get(content), tool_calls: msg.get(tool_calls)}) if msg.get(tool_calls): for tool_call in msg[tool_calls]: fn_name tool_call[function][name] fn_args json.loads(tool_call[function][arguments]) result tool_registry[fn_name](**fn_args) messages.append({ role: tool, tool_call_id: tool_call[id], content: json.dumps(result, ensure_asciiFalse), }) elif msg.get(content): return msg[content] return 已达到最大迭代次数任务未完成。这个循环的思路是只要模型返回tool_calls就把结果回填给模型继续思考一旦模型直接返回content就当作最终回答输出。步数限制是你兜底的保险丝。4.4 注册第一个工具工具层可以先用普通函数加一个注册函数TOOL_REGISTRY {} def tool(name: str): def decorator(func): TOOL_REGISTRY[name] func return func return decorator tool(get_order_status) def get_order_status(order_id: str) - dict: # 模拟真实系统查询 return {order_id: order_id, status: 已发货, logistics: 顺丰快递}真实项目里这里可以改成调用订单库或者HTTP接口。关键是让Agent能通过“工具名参数”触达真实系统而不是自己去拼接口文档。4.5 用FastAPI把它包成HTTP服务Agent循环写好后用FastAPI暴露一个标准接口from fastapi import FastAPI, HTTPException from pydantic import BaseModel app FastAPI() class RunRequest(BaseModel): messages: list[dict] class RunResponse(BaseModel): reply: str app.post(/agents/{agent_id}/run, response_modelRunResponse) async def run_agent_endpoint(agent_id: str, req: RunRequest): spec REGISTRY.get(agent_id) if not spec: raise HTTPException(status_code404, detailAgent not found) reply run_agent(spec, req.messages, TOOL_REGISTRY) return RunResponse(replyreply)启动服务uvicorn main:app --host 0.0.0.0 --port 8000这里有个容易被忽略的细节tool_calls里的arguments在模型返回时往往是一个字符串不是对象。我在运行时里用json.loads解析但某些模型偶尔会返回带注释或多出来的逗号所以生产环境必须做容错处理后面我会专门讲这个坑。4.6 把第一个“同事”推到生产前先这样自测接口起来后先用curl测一发curl -X POST http://localhost:8000/agents/order-service-bot/run \ -H Content-Type: application/json \ -d {messages:[{role:user,content:帮我查一下订单20240001的状态}]}如果一切正常你会看到Agent先调用get_order_status工具然后基于工具返回结果生成回答。在日志里要注意观察两件事模型有没有正确解析出工具名以及工具结果有没有被模型正确引用。这两步经常出幺蛾子等出了问题再查很费劲。5. 让Agent不只是一串对话编排、记忆与多Agent协作5.1 短期记忆会话窗口怎么管理上面这个最小平台已经具备了“单轮对话工具调用”的能力但要让它像真正的同事一样连续干活还需要把历史消息保存下来。最简单的做法是把每次对话的消息列表存进数据库下一轮请求时完整传给模型。但完整传递有个问题上下文窗口是有限的。一个Agent跑了一百轮之后前面所有消息都塞进请求很快会超过模型能处理的上限。我的做法是配置化地限制消息窗口。比如保留最近20条消息更早的对话做摘要压缩把摘要当作系统Prompt的一部分。这样既保留了关键上下文又不会让Token无限制膨胀。5.2 长期记忆向量库与知识检索有些知识不该放在对话历史里比如产品文档、运维手册。如果每次都把它们怼进Prompt费用高而且模型容易“迷失在长文本”里。更合理的做法是把这些文档向量化存入向量库然后给Agent配一个search_knowledge_base工具。当用户问“退款流程是什么”时Agent先调用检索工具拿到相关的几条片段再结合片段做回答。这比把整本手册扔给模型要省太多成本而且回答准确率反而更高。你可以先用Chroma或Milvus跑本地测试等数据量大了再接企业级向量库。5.3 多Agent“同事间协作”的一种可落地写法“当Agent有了工厂人人都能造同事”这句话的另一层含义是你不仅可能造一个Agent还可能造一群Agent让它们像同事一样分工协作。我实践下来最稳妥的协作模式是“管理者-执行者-检查者”。管理者Agent负责理解用户整体目标并拆成子任务执行者Agent负责完成具体任务比如“调用订单API查数据”检查者Agent负责验收结果是否符合要求。一个非常简化的编排思路def orchestrate(user_request): tasks manager_agent.plan(user_request) results [] for task in tasks: result executor_agent.run(task) ok reviewer_agent.check(task, result) while not ok and retry_count 3: result executor_agent.run(task 上次结果未通过请修正 reviewer.feedback) ok reviewer_agent.check(task, result) retry_count 1 results.append(result) return manager_agent.summarize(results)在这个流程里每个Agent依然是独立的“岗位”但多了一层工作流。后续可以引入消息队列做异步任务甚至给执行者一个“待办列表”。但第一版不要太复杂先用同步循环验证业务闭环。5.4 会话隔离与跨Agent访问权限多Agent协作带来的第一个安全问题就是“同事”之间能不能互相读会话。我见过有人为了省事把所有Agent的消息记录都放到同一个表里结果A部门的知识问答Agent把B部门的内部工单详情背出来了。正确的做法是给每个会话、每个Agent、甚至每个工具调用增加可见性边界。会话数据按租户或项目隔离Agent访问某个工具时要校验身份和权限。跨Agent读取对方会话应该被设计成一项显式授权的工具能力而不是默认就能访问的状态。6. 实测中的头号问题Agent平台跑不稳的五个根因6.1 工具参数解析翻车你以为的JSON格式不是JSON我在第一版平台里遇到最频繁的故障是模型返回的arguments不是合法JSON。现象很典型日志里抛JSONDecodeErrorAgent被迫中断。排查链路是这样的先打印原始arguments发现模型在JSON里用了单引号或者末尾多了一个逗号有时候还夹杂注释。原因是大模型的输出本质是概率采样即使你要求“只返回JSON”它也可能输出带格式噪声的内容。解决思路分三层。第一层在工具描述里写上“必须返回无注释、无尾逗号的JSON对象”。第二层在运行时对解析失败做一次自修复把错误片段和一个新的修复提示词发给模型让它重新生成参数。第三层如果仍失败放弃本轮工具调用转由Agent用文本告诉用户“暂时无法完成”。这三层不一定都要上但至少前两值得做它们能让你的平台从“经常挂”变成“偶尔慢”。6.2 死循环Agent反复做同一件事另一个头号问题是“死循环”。现象是日志里同一个工具被调用了十几次参数一模一样模型一直在重复“查一次订单 - 看结果 - 再查一次”。我定位时发现根因往往不是模型变笨而是Prompt里没有告诉它“什么时候该停止”。如果System Prompt只说“查订单”没说“查完之后给出最终结论”模型就可能把工具调用当成安全区一直没有输出最终文本。解决方法是三管齐下。一是明确在Instructions里写清楚终止条件比如“查看到订单状态后直接给用户最终答复不要再查询”。二是设置max_iterations硬限制超限就强制结束。三是增加“重复检测”如果工具调用名词和参数与上一轮完全相同就丢弃本轮并让模型换一种思路。6.3 上下文爆炸贵不是主要问题错误才是上下文爆炸是我最心疼的一个坑。当时平台同时接了好几类Agent有的Agent处理长文档时消息列表里的历史内容越积越多单次请求Token从几千涨到几万费用肉眼可见地飙升。更坑的是超长上下文会让模型“分心”。我曾经让客服Agent在处理到第5轮时突然忘了最初的口径要求原因就是前面塞了太多无关文档片段。我后来的习惯是每一个进入上下文的文档块都要先过一道“是否必要”的判断。能用检索结果替代全文就不传全文能保留最近消息就不保留几个月前的聊天记录。过长的历史定期压缩成摘要但摘要里要保留“用户诉求”“已经确认的事实”“未完成事项”这三个关键字段。6.4 外部工具超时一个卡住的API把整个Agent拖死Agent高度依赖工具所以工具是它的生命线也是它的最大单点风险。有一次我让Agent调用第三方物流查询接口接口突然卡住因为请求没有设超时整个Agent线程也跟着卡了十分钟没有响应。我当时对整个工具层做了一个统一改造每个工具调用必须包一层超时控制和重试策略。轻量级的做法是用functools.partial给HTTP客户端默认超时10秒失败后指数退避重试两次再失败就降级返回一个固定文案比如“物流接口暂不可用”。记住一个原则工具可以失败但Agent不能跟着崩溃。失败要变成可理解的返回值而不是让整个流程悬挂。6.5 多Agent共享状态写坏并发下的脏数据多Agent协作时如果多个执行者同时读写同一个任务状态很容易出现“脏数据”。比如两个执行者同时收到“更新工单状态”的任务后写入的覆盖了先写入的最后结果和真实业务状态对不上。定位这个问题的排查链路比较长先看日志里两个Agent的写入时间发现它们几乎同时发起UPDATE语句然后查数据库事务隔离级别确认默认配置会让后提交的事务直接覆盖。解决思路有两个层面。数据层面给任务记录加乐观锁版本号更新时必须带上旧版本号不一致就重试。流程层面同一个任务的执行者尽量只保留一个不要用两个Agent同时改同一份数据。如果必须并行就拆成“读任务”和“写任务”写任务串行化。7. 把平台塞进现有系统Spring AI、CI/CD与团队的磕碰7.1 Java团队为什么值得从Spring AI入手如果你的公司技术栈以Java为主硬套Python平台会引入割裂的语言维护成本。这时候我反而更推荐Spring AI它把模型调用抽象成了Spring风格跟Spring Boot应用天然融合。Spring AI里有一个很顺手的抽象叫ChatClient。你注册一个Bean然后像写普通业务代码一样调用Agent能力工具方法可以用Tool注解直接暴露。团队里那些写了好几年Java的人理解起来非常快不用去补Python生态的新模型。我的建议是Java团队先别急着自研完整运行时先用Spring AI跑通“HTTP接口-ChatClient-Tool方法”这条链路等需求变复杂了再在它外面加自己的编排层和模型网关。7.2 让Jenkins里跑一个“构建医生”Agent热词里提到了Jenkins AI Agent。我在CI体系里做过一个很实用的“构建医生”当构建失败时Jenkins把失败日志发给AgentAgent先归类错误阶段编译失败、测试失败、依赖拉取失败再给出修复建议最后在评论里负责人。这里要强调安全红线Agent只给建议不要让它自动改代码。自动改代码看起来效率高但一旦Agent改错方向会让问题隐藏得更深。比较合适的方式是把它定位成“诊断和提效工具”把最终决定权留给工程师。7.3 工业场景Agent平台能不能和PLC对话热词里还有一条“AI Agent与PLC编程”。在真实工业现场Agent平台的玩法会不一样PLC位于OT网络Agent如果要读产线状态不能直接从办公网访问PLC必须通过网关设备或边缘节点做协议转换和安全隔离。如果你要在工厂里搭Agent平台第一件事不是训练大模型而是画清楚网络边界。Agent可以跑在边缘服务器上通过Modbus或OPC UA协议采集数据也可以把这些协议能力封装成平台里的一个工具。核心原则是“Agent可以读状态、给建议但改变产线参数之前必须经过人工审批”。7.4 多Agent Coding开发规范先定规矩再写入口用Agent辅助编码现在越来越普遍但团队容易陷入混乱。我建议在开放入口前先定几条规矩任务边界要清楚让Agent做什么、不做什么写进System Prompt里。所有Agent生成的代码必须经过人工Review不能直接合并主分支。Agent调用外部命令时要在日志里完整记录。这一点最容易漏出了问题很难回溯。建立一个小型评估集每次改Prompt或换模型都先跑同一批回归用例防止“改一个场景坏另一个场景”。这些规范不是限制Agent而是保证它不会成为团队里的“不可控变量”。7.5 部署与运维让你的工厂7x24小时不熄火平台从本地跑通到生产部署我会重点盯这几项容器化Agent进程要无状态配置放环境变量或配置中心好处是多个副本可以随意扩缩容。模型网关限流同一时间大量用户触发Agent时网关要有默认限流避免把模型API调用额度瞬间打爆。成本可视化每次调用记录Token数和模型名按Agent维度聚合成日报。Agent运行监控除了服务器指标更要在意“Agent步数”“工具失败率”“任务完成率”这些业务指标。我见过团队第一天上线Agent很开心第二天模型账单翻倍却查不出原因。不是模型出问题而是缺少“谁在什么场景下、调用了多少次模型”的观测能力。所以部署阶段日志和指标不是可选项是硬需求。8. 关于“人人都能造同事”的几句实话8.1 不是所有流程都值得造Agent这句话写出来可能有点泼冷水但确实是我吃过亏后的体会Agent不是银弹。如果一个业务的判断链路是固定的比如“IF库存0则下单否则提示缺货”用传统工作流或者定时任务就能搞定完全不需要模型在循环里猜来猜去。Agent真正有价值的场景是那些没有标准答案、需要组合多个工具动态决策的任务。我现在的选型标准是先尝试用函数脚本解决只有脚本搞不定时才把这段逻辑升级为Agent。8.2 我心中优先级排序如果让我给过来人一句忠告先通工具再通循环最后玩多Agent。第一优先是梳理好工具层因为Agent的战斗力基本取决于它能触达多少高质量API。第二优先是让单Agent在真实业务上稳定跑通100次把解析、超时、重复动作这些坑全部磨平。最后才是引入多Agent协作因为它带来的状态管理和可观测性成本会成倍上升。这个顺序反过来通常会变成“多Agent框架搭得很酷但放到真实业务里有各种小毛病”最后光排查就得花掉大量时间。8.3 下一步可以扩展的方向平台有了第一批“同事”之后我下一个会做的是AgentOps建设。核心是把每个Agent的输入、输出、工具调用轨迹沉淀成数据定期复盘“哪些步骤拖慢了回答”“哪些Prompt让模型老走弯路”。有条件的话为每一个Agent准备一组评估用例每次改动都在评估集上跑分用分数代替感觉去判断“这个Agent有没有变聪明”。还有一个方向值得关注人机协同。让Agent先给出草稿人在界面上确认和修改。听起来不够硬核但在真实业务里这是风险最低、最容易被用户接受的形式。我自己更偏爱这种“Agent干活人类把关”的模式因为AI同事再能干最终责任还是需要人来承担。