资讯动态

LangChain、LangGraph、MCP与Agent工程化:企业级智能体开发实战指南

发布时间:2026/10/14 11:05:58 来源:尧图企业网站定制
1. 从会调API到能交付项目企业级Agent开发到底卡在哪很多人学LangChain的经历都差不多跟着教程跑通了几个Chain会写PromptTemplate能接OpenAI的接口然后呢然后就没有然后了。真到了公司要做一个能上线的智能体系统突然发现完全不知道从哪下手——状态怎么管、多轮对话怎么持久化、工具调用失败了怎么重试、多个Agent之间怎么协作、权限怎么控制、日志怎么追踪。这些问题没有一个能在Hello World级别的教程里找到答案。我自己在这个方向上摸索了挺长时间也带过几个从零起步的项目最大的感受是LangChain只是入场券真正决定项目能不能落地的是LangGraph、MCP和Agent工程化这三块。这四个东西不是并列关系而是层层递进的关系——LangChain解决怎么调模型和工具LangGraph解决怎么编排复杂流程和状态MCP解决工具怎么标准化接入Agent解决怎么让系统自主决策并可靠执行。这篇内容我打算把这四个框架串起来讲不是那种每个框架单独写个Demo的讲法而是按照一个真实企业项目的演进路径来展开从最简单的链式调用开始遇到瓶颈引入图编排再遇到工具管理混乱的问题引入MCP协议最后把整个系统升级成多Agent协作架构。每一步都会说清楚为什么要这么做和不这么做会怎样。适合谁看如果你已经会用Python了解基本的LLM调用但没做过完整的Agent项目这篇内容应该能帮你少走不少弯路。如果你已经做过一些Demo但总觉得离生产环境差一口气那第四、五章关于状态管理和MCP接入的部分可能对你更有用。零基础也能看但需要你边看边动手光读不练的话这些框架的坑你是体会不到的。2. LangChain的真实定位它该干什么不该干什么2.1 为什么很多人用LangChain用错了方向LangChain最大的问题不是它不好用而是它的抽象层次太多了。你打开官方文档看到Chain、Agent、Tool、Memory、Retriever、OutputParser一大堆概念很容易陷入我要把所有模块都用上的误区。实际上在企业项目里LangChain最核心的价值就三个统一模型接口、Prompt管理、输出解析。其他的功能要么用不上要么有更好的替代方案。我见过一个项目团队花了两个月时间用LangChain的Agent模块搭了一套工具调用系统结果发现调试极其困难因为LangChain的AgentExecutor把中间步骤封装得太深了出了问题根本不知道是哪一步挂的。后来他们换成了LangGraph重新做同样的功能两周就搞定了而且可观测性好得多。这个教训就是LangChain适合做组件不适合做编排。那LangChain具体该怎么用我的建议是把它当成一个适配层来用。你需要调不同厂商的模型用LangChain的ChatModel接口统一掉你需要管理大量的Prompt模板用LangChain的PromptTemplate来组织你需要让模型输出结构化的JSON用它的OutputParser来约束。这些是它做得好的地方也是经过大量项目验证的稳定功能。2.2 模型接口统一别小看这一层的价值企业项目里很少只用一个模型。可能主力用某个商业模型但某些敏感场景要用本地部署的开源模型还有些场景要用便宜的小模型来做意图分类。如果没有统一的接口层你的代码里就会到处是if-else判断换个模型要改几十个文件。LangChain的ChatModel接口帮你解决了这个问题。你只需要针对接口编程底层换模型的时候改一个配置就行。具体来说初始化模型的时候可以这样写from langchain_openai import ChatOpenAI from langchain_community.chat_models import ChatOllama # 商业模型用于复杂推理 primary_llm ChatOpenAI( modelgpt-4o, temperature0.1, max_retries3, timeout60 ) # 本地模型用于敏感数据处理 local_llm ChatOllama( modelqwen2.5:14b, temperature0.1, base_urlhttp://localhost:11434 )这里有几个参数值得注意。temperature在企业场景里通常设得很低0.1甚至0因为你需要的是稳定可复现的输出不是创意。max_retries一定要设网络抖动是常态不设重试的话线上会莫名其妙地报错。timeout也很关键默认值有时候太短复杂推理任务还没跑完就超时了。注意不同厂商的模型对temperature的敏感度不一样。有些模型在temperature0的时候反而会出现重复输出的问题建议在0.1到0.3之间做A/B测试找到你具体场景下的最优值。2.3 Prompt管理别把提示词散落在代码里新手最容易犯的错误就是把Prompt直接写在业务代码里用字符串拼接。项目小的时候没问题一旦Prompt超过20个你就完全记不住哪个Prompt对应哪个功能改了一个地方可能影响三个功能。正确的做法是把Prompt集中管理用LangChain的PromptTemplate或者ChatPromptTemplate来组织。我一般会按业务模块分文件存放比如prompts/customer_service.py、prompts/data_analysis.py这样。每个Prompt都带上版本号和变更说明方便回溯。from langchain_core.prompts import ChatPromptTemplate intent_classify_prompt ChatPromptTemplate.from_messages([ (system, 你是一个意图分类器。根据用户输入判断其意图类别。 可选类别查询订单、退换货、产品咨询、投诉建议、其他。 只输出类别名称不要输出任何其他内容。), (human, {user_input}) ]) # 使用时 chain intent_classify_prompt | primary_llm result chain.invoke({user_input: 我上周买的鞋子还没到})这种写法的好处是Prompt和代码分离产品经理要改提示词的时候不需要动代码逻辑。而且ChatPromptTemplate支持few-shot示例的注入你可以把历史对话作为示例动态加进去提升分类准确率。2.4 输出解析让模型的输出可编程模型输出的是自然语言但你的下游系统需要的是结构化数据。这个转换过程如果靠正则表达式去抠维护成本极高。LangChain的OutputParser就是干这个的它能把模型的自由文本输出转成Python对象。最常用的是PydanticOutputParser你定义一个Pydantic模型Parser会自动生成格式说明注入到Prompt里然后把模型输出解析成对应的对象。如果模型输出格式不对它还能自动重试。from langchain_core.output_parsers import PydanticOutputParser from pydantic import BaseModel, Field class OrderInfo(BaseModel): order_id: str Field(description订单编号) status: str Field(description订单状态) estimated_delivery: str Field(description预计送达时间) parser PydanticOutputParser(pydantic_objectOrderInfo) prompt ChatPromptTemplate.from_messages([ (system, 从用户描述中提取订单信息。\n{format_instructions}), (human, {user_input}) ]).partial(format_instructionsparser.get_format_instructions()) chain prompt | primary_llm | parser实测下来加了format_instructions之后模型输出格式的正确率能从60%左右提升到95%以上。剩下的5%靠Parser的自动重试机制基本能兜住。但要注意重试是有成本的每次重试都是一次完整的模型调用所以Prompt里的格式说明要写得足够清楚别指望重试来兜底。3. LangGraph当Chain不够用的时候你需要一张图3.1 为什么线性Chain撑不住真实业务LangChain的Chain本质是一条直线输入经过AA的输出给BB的输出给C结束。但真实业务几乎不可能是直线的。用户问了一个问题你可能需要先判断意图根据意图走不同的处理分支处理过程中可能需要调用外部工具工具返回的结果可能触发重试多轮对话还需要记住之前的状态。这些需求用Chain来实现会非常别扭。你可能会写一堆if-else来手动控制流程代码很快就变成了一团乱麻。LangGraph就是为解决这个问题而生的它把工作流建模成一张有向图节点是处理步骤边是流转条件状态在节点之间传递。打个比方Chain像是一条流水线产品从一头进去经过固定工序从另一头出来。LangGraph像是一个车间有不同的工位和传送带根据产品类型和检测结果可以走不同的路线有的还要回流返工。3.2 状态设计整个图运转的核心用LangGraph的第一件事是定义State。State是一个字典或者TypedDict它会在所有节点之间共享。每个节点读取State做一些处理然后返回要更新的字段。LangGraph会自动把更新合并到State里。State的设计直接决定了你的图好不好维护。我的经验是State里只放需要跨节点共享的数据节点内部的临时变量不要放进去。另外对于列表类型的字段要明确是覆盖还是追加。LangGraph提供了Annotated和operator.add来支持追加语义。from typing import TypedDict, Annotated import operator class AgentState(TypedDict): messages: Annotated[list, operator.add] # 对话历史追加模式 current_intent: str # 当前意图覆盖模式 tool_results: Annotated[list, operator.add] # 工具调用结果追加模式 retry_count: int # 重试次数覆盖模式 final_answer: str # 最终答案覆盖模式这里messages用了operator.add意味着每次节点返回新的消息列表时LangGraph会把它追加到已有的列表后面而不是替换掉。这个设计对多轮对话非常关键你不需要手动去维护历史消息的拼接。3.3 条件边与循环让流程真正活起来LangGraph最强大的地方是条件边conditional edge。你可以定义一个路由函数根据当前State决定下一步走哪个节点。这让根据意图分流、失败重试、人工审核介入这些逻辑变得非常自然。from langgraph.graph import StateGraph, END def route_by_intent(state: AgentState): intent state[current_intent] if intent 查询订单: return query_order elif intent 退换货: return process_return elif state[retry_count] 3: return human_handoff else: return general_response builder StateGraph(AgentState) builder.add_node(classify, classify_intent) builder.add_node(query_order, handle_order_query) builder.add_node(process_return, handle_return) builder.add_node(general_response, handle_general) builder.add_node(human_handoff, escalate_to_human) builder.set_entry_point(classify) builder.add_conditional_edges(classify, route_by_intent) builder.add_edge(query_order, END) builder.add_edge(process_return, END) builder.add_edge(general_response, END) builder.add_edge(human_handoff, END) graph builder.compile()这段代码定义了一个意图分类后分流的图。注意retry_count 3那个分支这就是一个保护机制——当系统反复失败时自动转人工避免无限循环消耗资源。这种兜底逻辑在企业项目里是必须的我见过太多Demo级别的Agent因为缺少兜底在生产环境里陷入死循环把Token烧光。3.4 持久化与断点续跑生产环境的刚需LangGraph支持Checkpointer机制可以把每一步的状态持久化到数据库。这意味着如果服务重启了可以从上次中断的地方继续跑而不是从头开始。对于长流程的任务比如需要人工审核的审批流这个功能是刚需。from langgraph.checkpoint.sqlite import SqliteSaver memory SqliteSaver.from_conn_string(checkpoints.db) graph builder.compile(checkpointermemory) # 每次调用带上thread_id同一个thread_id共享状态 config {configurable: {thread_id: user_123_session_1}} result graph.invoke({messages: [(human, 我的订单到哪了)]}, config)thread_id是会话标识同一个用户的多轮对话用同一个thread_id状态就能串起来。生产环境建议用PostgreSQL或者Redis做CheckpointerSQLite只适合本地开发。另外要注意Checkpointer的数据量会随着对话轮次增长需要定期归档或清理。提示如果你用的是分布式部署多个实例共享同一个Checkpointer要确保thread_id的分配是幂等的否则会出现状态覆盖的问题。我一般用用户ID会话ID的组合来生成thread_id并在入口处做去重。4. MCP协议工具接入的标准化答案4.1 工具管理的混乱现状在没有MCP之前给Agent接工具是一件很痛苦的事。每个工具都要写一套描述、参数定义、调用逻辑而且不同框架之间的工具定义格式还不一样。你在LangChain里定义的工具换到另一个框架就得重写。更麻烦的是当工具有几十个的时候怎么让模型准确选择正确的工具成了一个玄学问题。MCPModel Context Protocol的出现就是为了解决这个问题。它定义了一套标准协议工具提供方按照协议暴露自己的能力Agent按照协议去发现和调用工具。你可以把它理解成AI领域的USB接口——不管什么设备只要符合USB标准插上就能用。4.2 MCP的三种能力Tools、Resources、PromptsMCP协议里定义了三种核心能力理解这三者的区别很重要能力类型作用典型场景控制方Tools可执行的操作查数据库、发邮件、调API模型决定调用Resources可读取的数据文件内容、数据库记录应用决定加载Prompts预定义的提示模板标准化任务模板用户主动选择Tools是模型主动调用的比如用户问帮我查一下库存模型会决定调用query_inventory这个Tool。Resources是应用层主动加载的比如系统启动时把产品目录加载进来作为上下文。Prompts是用户或者应用选择的模板比如帮我写一封投诉回复邮件对应一个预定义的Prompt模板。在实际项目中Tools用得最多Resources次之Prompts用得相对少。但三者配合起来才能发挥MCP的全部价值。4.3 接入MCP Server的实操步骤假设你有一个内部的订单管理系统想把它暴露成MCP工具给Agent用。你需要写一个MCP Server定义好工具的名称、描述、参数schema然后启动服务。Agent这边通过MCP Client去连接这个Server自动发现可用的工具。from mcp.server import Server from mcp.types import Tool, TextContent server Server(order-system) server.list_tools() async def list_tools(): return [ Tool( namequery_order, description根据订单号查询订单状态和物流信息, inputSchema{ type: object, properties: { order_id: {type: string, description: 订单编号} }, required: [order_id] } ), Tool( namecancel_order, description取消指定订单仅在订单未发货时有效, inputSchema{ type: object, properties: { order_id: {type: string, description: 订单编号}, reason: {type: string, description: 取消原因} }, required: [order_id] } ) ] server.call_tool() async def call_tool(name: str, arguments: dict): if name query_order: result await order_service.query(arguments[order_id]) return [TextContent(typetext, textresult)] elif name cancel_order: result await order_service.cancel( arguments[order_id], arguments.get(reason, ) ) return [TextContent(typetext, textresult)]Agent这边接入就很简单了from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client server_params StdioServerParameters( commandpython, args[order_server.py] ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() # 把tools转换成LangChain的Tool格式 langchain_tools convert_mcp_tools(tools)4.4 工具描述怎么写模型才选得准MCP解决了工具接入的标准化问题但工具选择准确率的问题还是得靠描述质量。我踩过的坑是工具描述写得太简略模型经常选错工具。比如有两个工具一个叫get_user_info一个叫get_user_profile描述都写获取用户信息模型根本分不清。好的工具描述应该包含三个要素做什么、什么时候用、什么时候不用。比如Tool( nameget_user_basic_info, description获取用户的基本信息包括姓名、手机号、注册时间。 适用于需要确认用户身份或展示用户基本资料的场景。 如果需要获取用户的订单历史或消费记录请使用get_user_orders工具。, ... )加上什么时候不用这一句之后工具选择的准确率提升非常明显。另外参数描述也要写清楚格式要求比如日期是YYYY-MM-DD还是时间戳不写清楚的话模型会瞎猜。注意工具数量超过20个之后建议做分组或者分层。一次性把所有工具塞给模型不仅消耗Token还会降低选择准确率。我一般的做法是按业务域分组先用一个轻量模型做工具域路由再在域内做具体工具选择。5. Agent工程化从Demo到生产要跨过的坎5.1 单Agent的能力边界在哪里很多人对Agent的期待是给它一个目标它自己搞定一切。实际做下来你会发现单Agent在复杂任务上的表现远不如预期。原因很简单上下文窗口有限工具太多会干扰选择长流程中容易丢失目标。我做过一个测试让单Agent处理一个需要5步以上工具调用的任务成功率不到40%。失败的原因主要是两类一是中间步骤的结果没有正确传递到下一步二是模型在长上下文中忘记了最初的目标。这不是模型能力的问题是架构的问题。所以企业级项目里多Agent协作几乎是必然选择。但多Agent不是简单地把任务拆给几个Agent就完事了怎么拆、怎么通信、怎么汇总每一步都有讲究。5.2 多Agent协作的三种模式根据我的实践经验多Agent协作主要有三种模式适用场景不同模式一主管-工人模式Supervisor-Worker。一个主管Agent负责拆解任务和分配多个工人Agent负责执行具体子任务。适合任务可以清晰拆解的场景比如分析这份报告可以拆成提取数据、生成图表、撰写结论三个子任务。模式二流水线模式Pipeline。多个Agent按顺序处理前一个的输出是后一个的输入。适合有明确阶段划分的场景比如内容生产流水线选题Agent → 大纲Agent → 撰写Agent → 审核Agent。模式三辩论模式Debate。多个Agent对同一问题给出不同答案然后由一个仲裁Agent综合判断。适合需要多角度分析的场景比如风险评估、方案评审。在LangGraph里实现这些模式核心是用好条件边和子图。主管-工人模式可以用条件边做任务分发流水线模式用顺序边串联辩论模式用并行节点加汇总节点。from langgraph.graph import StateGraph, END def create_supervisor_graph(): builder StateGraph(SupervisorState) builder.add_node(supervisor, supervisor_node) builder.add_node(data_worker, data_worker_node) builder.add_node(chart_worker, chart_worker_node) builder.add_node(report_worker, report_worker_node) builder.set_entry_point(supervisor) builder.add_conditional_edges( supervisor, lambda s: s[next_worker], { data: data_worker, chart: chart_worker, report: report_worker, finish: END } ) # 每个worker完成后回到supervisor builder.add_edge(data_worker, supervisor) builder.add_edge(chart_worker, supervisor) builder.add_edge(report_worker, supervisor) return builder.compile()这个结构里supervisor节点负责决定下一步派给谁worker完成后回到supervisor由supervisor判断是继续派活还是结束。这种中心辐射的结构比让worker之间直接通信要好维护得多。5.3 可观测性出了问题你得知道是哪出的Agent系统最让人头疼的就是调试。用户说它回答错了你去看日志只看到一堆模型调用记录根本不知道中间发生了什么。所以可观测性不是可选项是必选项。我一般会在三个层面做埋点节点级别记录每个节点的输入输出和耗时工具级别记录每次工具调用的参数和返回模型级别记录Token消耗和延迟。这些数据汇总起来才能定位问题。LangGraph本身支持Streaming可以实时输出每个节点的执行情况。配合LangSmith或者自建的追踪系统能把整个执行链路可视化出来。我建议在开发阶段就把这套东西搭好别等到上线出了问题再补那时候你会非常痛苦。async for event in graph.astream( {messages: [(human, user_input)]}, config{configurable: {thread_id: session_id}} ): for node_name, node_output in event.items(): logger.info(fNode: {node_name}, extra{ input: node_output.get(input), output: node_output.get(output), timestamp: time.time() })5.4 成本控制别让Agent变成烧钱机器Agent系统跑起来之后成本很容易失控。一次用户请求可能触发十几次模型调用如果每次都用大模型账单会非常难看。我的经验是做好三件事第一模型分级。意图分类、参数提取这种简单任务用小模型复杂推理才用大模型。实测下来简单任务用小模型的效果差距不大但成本能降80%以上。第二缓存。相同的输入直接返回缓存结果尤其是那些高频的、确定性的查询。LangChain提供了CacheBackedEmbeddings和LLM缓存机制配置一下就能用。第三限制循环次数。每个图都要设置最大迭代次数超过就强制结束或者转人工。我见过一个项目因为没设限制一个用户请求触发了200多次模型调用单次成本超过10块钱。# 设置递归限制 config { configurable: {thread_id: session_id}, recursion_limit: 25 # 最大节点执行次数 }recursion_limit是LangGraph提供的保护机制超过这个次数会抛出异常。建议根据你的图复杂度设置一般20到50之间比较合理。6. 一个完整的企业级Agent项目是怎么搭起来的6.1 项目结构别把所有代码塞一个文件里我见过太多Demo项目把所有代码写在一个main.py里几百行堆在一起。这种代码自己看着都累更别说维护了。企业级项目一定要有清晰的结构。我一般会这样组织project/ ├── config/ │ ├── settings.py # 配置管理 │ └── prompts/ # Prompt模板 ├── core/ │ ├── llm_factory.py # 模型工厂 │ ├── state.py # 状态定义 │ └── graph_builder.py # 图构建 ├── nodes/ │ ├── classify.py # 意图分类节点 │ ├── tools.py # 工具调用节点 │ └── response.py # 响应生成节点 ├── mcp_servers/ │ ├── order_server.py # 订单系统MCP Server │ └── knowledge_server.py # 知识库MCP Server ├── agents/ │ ├── supervisor.py # 主管Agent │ └── workers.py # 工人Agent ├── observability/ │ ├── logger.py # 日志 │ └── tracer.py # 追踪 └── main.py # 入口这个结构的好处是职责清晰改Prompt不用动代码加工具不用改图换模型不用改业务逻辑。团队协作的时候每个人负责的模块边界很清楚。6.2 从需求到落地的完整流程假设我们要做一个客服Agent系统需求是用户可以用自然语言咨询订单、退换货、产品问题系统自动处理处理不了的转人工。第一步定义状态。根据需求State里需要包含对话历史、用户ID、当前意图、订单信息、工具调用结果、是否需要转人工。第二步画流程图。入口是意图分类分三个分支订单查询、退换货、产品咨询。订单查询调MCP工具查订单退换货走审批流程产品咨询查知识库。每个分支处理完后生成回复如果置信度低或者用户明确要求转人工。第三步实现节点。每个节点是一个函数接收State返回更新。意图分类节点用小模型工具调用节点通过MCP Client调工具回复生成节点用大模型。第四步组装图。用StateGraph把节点连起来加条件边做分流加Checkpointer做持久化加recursion_limit做保护。第五步测试与调优。用真实对话数据测试记录每个节点的准确率和耗时针对薄弱环节优化Prompt或者换模型。6.3 上线前必须检查的几件事项目跑通和能上线是两回事。上线前我一般会检查这些异常处理每个节点都要有try-except工具调用失败要有降级方案模型超时要有重试。限流入口处做用户级别的限流防止单个用户刷爆系统。日志脱敏用户手机号、地址这些敏感信息在日志里要脱敏。回滚方案新版本上线要有快速回滚的能力Prompt和模型配置都要能热切换。压测模拟并发请求看看系统的瓶颈在哪。Agent系统通常是IO密集型的瓶颈一般在模型调用和工具调用上。提示上线初期建议用灰度发布先放10%的流量进来观察一周再全量。Agent系统的行为不确定性比传统系统高灰度能帮你发现很多测试环境发现不了的问题。7. 几个我踩过的坑和对应的解法7.1 状态污染多轮对话里的隐形杀手多轮对话最容易出的问题是状态污染。用户第一轮问了订单A第二轮问订单B如果State里的订单信息没有正确更新系统可能还在用订单A的数据回答。这个问题的根源是State的更新逻辑不清晰。我的解法是每个节点返回State更新时明确指定是覆盖还是追加。对于订单信息这种当前上下文的数据用覆盖模式对于对话历史这种累积的数据用追加模式。另外在意图分类节点里加一个上下文重置的判断当用户切换话题时清空上一轮的临时数据。7.2 工具调用超时用户等不起工具调用超时是另一个高频问题。外部API响应慢用户等了十几秒还没结果体验极差。我的做法是设置分级超时3秒内没返回就先给用户一个正在查询的提示10秒还没返回就降级到备用方案比如查缓存或者转人工。LangGraph的节点里可以用asyncio.wait_for来实现超时控制import asyncio async def call_tool_with_timeout(tool, args, timeout10): try: return await asyncio.wait_for(tool.ainvoke(args), timeouttimeout) except asyncio.TimeoutError: return {error: 工具调用超时, fallback: True}7.3 Prompt漂移模型升级后的意外模型厂商升级模型版本是常事但升级之后你的Prompt可能就不work了。我遇到过一次模型升级后原本稳定的输出格式突然变了导致Parser大量报错。后来我养成了习惯每次模型版本变更先跑一遍回归测试集确认关键指标没有下降再全量切换。回归测试集不用很大覆盖核心场景就行一般50到100条测试用例足够。重点看三个指标意图分类准确率、工具选择准确率、输出格式正确率。任何一个指标下降超过5%就要重新调Prompt。7.4 上下文窗口不是越大越好很多人觉得上下文窗口越大越好恨不得把整个知识库都塞进去。实际测试下来上下文太长反而会降低模型的表现因为关键信息被淹没了。我的经验是上下文里只放当前任务真正需要的信息无关的历史对话和文档要主动裁剪。具体做法是在State里维护一个当前任务相关上下文的字段每次节点更新时只把相关的信息加进去。历史对话超过一定轮次后用摘要代替原文。这样既控制了Token消耗又提升了模型的表现。8. 写在最后一些个人体会这套东西我从头到尾搭过几遍最大的体会是框架是工具架构是能力。LangChain、LangGraph、MCP这些框架会不断更新迭代但底层的架构思维是通用的——怎么设计状态、怎么编排流程、怎么管理工具、怎么保证可靠性这些想清楚了换什么框架都能快速上手。另外就是别追求一步到位。我见过一些团队一上来就想搭一个全能Agent结果做了半年还在调bug。正确的做法是从一个小场景切入把单点跑通再逐步扩展。先做一个能查订单的Agent跑稳了再加退换货再加产品咨询每一步都验证过再往前走。最后说一个容易被忽视的点Agent系统的评估体系要提前建。不要等到上线了才想怎么衡量好坏。从第一天起就记录每次交互的完整链路定义清楚什么是成功什么是失败积累测试集。这些东西在后期调优的时候价值巨大没有它们你就是在盲调。这个方向变化很快今天好用的方案明天可能就有更好的替代。保持动手保持测试别光看文章不动手。很多坑只有自己踩过才知道有多深别人告诉你的经验你听的时候觉得懂了真到用的时候还是会犯同样的错。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑