
假设你接到一个很常见的需求。客服团队希望做一个助手。它要能回答公司政策查询订单状态必要时创建工单。有人会立刻说做个 Agent接上搜索、数据库和工单工具不就行了这句话只对了一半。如果用户问的是「把这段投诉改得更礼貌」Agent 是多余的。如果用户问的是「我的订单在哪里」模型也不应该自己编一个答案。如果用户要退款系统更不能让模型不经校验直接执行。这篇文章要解决的不是「怎样把 Agent 跑起来」而是更靠前的问题什么时候该用 Prompt、结构化输出、RAG、确定性工作流或 Agent。读完后你应该能为一个新需求选出最小可行的技术组合并知道为什么不该一开始就堆最复杂的框架。先把同一个需求拆开仍然是客服助手。把用户问题分成四类技术选择就会清晰很多。用户问题真正缺少的能力优先方案不该做什么把投诉改成正式邮件文本生成Prompt接数据库和 Agent从邮件提取订单号和诉求稳定字段结构化输出 校验用正则解析自由文本退货政策是什么可更新的领域知识RAG让模型靠训练记忆回答查订单并决定是否创建工单外部系统与路径判断工具 工作流或 Agent让模型直接写库是否是否否是能不能收到一个业务需求只需要生成、改写或分类文本?Prompt 模型调用答案必须基于私有或时效信息?检索增强生成 RAG需要读取或操作外部系统?步骤能事先写清吗?确定性工作流 受控工具Agent 工具 运行边界这不是从低级到高级的升级路线。它是一条复杂度阶梯。每往右走一步系统能处理更多不确定性同时也会增加测试、权限、成本和故障恢复的难度。第一层, Prompt 解决表达不解决事实模型最擅长的是根据上下文生成、改写、归纳或分类语言。把任务说清楚、给出必要约束、定义合格输出往往就能完成大量工作。例如下面的任务是把用户来信分流。它没有任何外部动作且结果可以人工抽查没必要引入 Agent。frompydanticimportBaseModel,Fieldfromlangchain.chat_modelsimportinit_chat_modelclassTicketIntent(BaseModel):category:strField(description退款、物流、产品咨询或其他)urgency:intField(ge1,le5)summary:strmodelinit_chat_model(openai:gpt-5.5,temperature0)structured_modelmodel.with_structured_output(TicketIntent)resultstructured_model.invoke(包裹三天没有更新我明天出差前必须收到请尽快处理。)print(result.model_dump())这里的关键不是temperature0也不是 Prompt 写得多花哨。关键是应用先定义了自己真正要消费的数据结构。模型负责理解语言Pydantic 负责拒绝不符合契约的结果。Prompt 方案的边界Prompt 不能让模型获得它并不知道的事实也不能让它安全地操作订单系统。一个模型可以把「退款政策」讲得非常流畅却不代表它说的是当前版本。把流畅当正确是大模型应用里最危险的错觉之一。第二层, RAG 解决依据不替你判断业务规则当答案必须来自公司制度、产品说明或经常变化的知识库时RAG 才是正确的工具。它做的事情很朴素。用户问题检索相关片段片段、来源和问题一起交给模型带依据的回答引用来源或提示无法确认一个可靠的 RAG 流程至少有四个可检验环节。文档是否完整、最新、权限正确。文档如何切分单段是否保留足够上下文。检索结果是否真的召回了答案所在片段。模型是否被要求只根据召回内容作答并在证据不足时承认不知道。读者常把注意力放在向量数据库却忽略前两步。实际项目里知识库混入过期政策、表格被错误解析、权限边界没有过滤比「换一个更大的 Embedding 模型」更常导致错误答案。RAG 的一个失败场景假设知识库里同时存在去年的七天无理由退货政策和今天的特殊活动政策。检索返回了旧文档模型完全可能写出一段条理清晰、语气坚定、但已经失效的答案。解决办法不是「再强调一次不要幻觉」。需要给文档加版本和生效时间检索时过滤过期内容并在回答中保留来源。模型是最后一棒不是可信度的唯一来源。第三层, 工具调用解决行动但行动必须有闸门模型要查询订单、读取库存、创建工单就必须通过工具访问外部系统。工具调用让模型拥有行动能力也把安全和可恢复性问题带进了系统。是否模型提出工具调用参数 Schema 校验是否为只读操作?调用查询工具权限检查、幂等键、人工确认执行有副作用操作将结果返回模型工具设计要像 API 设计一样严格。它应该有类型清晰的参数、最小权限、可审计日志和明确错误语义。下面这个例子把查询和退款刻意拆开。查询工具可供模型直接使用退款工具则只创建待审批请求最终扣款由确定性业务服务完成。frompydanticimportBaseModel,FieldclassRefundRequest(BaseModel):order_id:strreason:strField(min_length5,max_length300)deflookup_order(order_id:str)-dict:只读查询。真实实现应检查当前用户是否拥有该订单。return{order_id:order_id,status:shipped}defcreate_refund_review(request:RefundRequest)-dict:只创建待审批记录不在此处直接退款。return{review_id:review_123,status:pending_approval}模型可以帮助收集信息、选择下一步和解释结果。但系统不能把「模型决定调用了工具」误解为「操作已经安全」。第四层, 工作流和 Agent 的分界线如果步骤固定例如「校验订单号 → 查物流 → 生成回复 → 写入工单」应把它写成确定性工作流。每个节点都可以单独测试失败后知道从哪一步恢复。如果目标固定、路径不固定例如「根据用户描述判断是查订单、查政策还是转人工」Agent 才有价值。它的职责是从有限工具集合中选择路径不是取代所有业务逻辑。固定步骤工作流可预测、易测试、易审计路径取决于中间结果Agent需要工具边界、循环上限和回退策略一个实用判断是能否把流程画成一张没有菱形判断节点的图。如果能通常先写工作流。只有当判断节点确实需要语言理解、开放式规划或动态工具选择时才把那一小段交给 Agent。用一套测试题决定要不要升级在写框架前先收集 20 到 50 个真实请求。不要只选容易成功的例子要包括缺少信息、矛盾信息、超权限请求、过期知识和工具失败。观察到的问题优先补的能力输出格式经常乱Schema、校验和修复流程回答找不到依据RAG 与引用展示答案需要系统数据只读工具固定流程容易漏步骤确定性工作流每次路径都不同受限 Agent无法解释一次失败追踪、日志与评测这组测试题会成为以后换模型、改 Prompt、增加工具时的回归测试。没有它系统每次看似变强实际上可能只是换了一种失败方式。发布到生产前做这五个检查输出是否有结构化契约和失败处理。知识回答是否能展示依据并拒绝无依据结论。工具是否区分只读和有副作用操作。有副作用操作是否有权限、幂等和人工确认。是否能追踪一次请求调用了什么模型、什么工具、消耗多少时间和 token。LangChain 的价值不是让每个需求都变成 Agent。而是让模型、消息、检索、工具和运行时配置能够按需组合。先用最少的组件解决一个真实问题才能知道下一层复杂度是否真的值得。延伸阅读LangChain ModelsLangChain AgentsLangChain Structured output