做架构这一行十几年,我越来越觉得,AI不是给现有系统打补丁,而是把整个架构设计的底层逻辑给颠倒了。过去我们做微服务、做分布式,核心假设是:系统的行为是可以预期的。你调用一个订单接口,传入一组参数,返回一个固定结构的结果,整个过程在毫秒级完成,状态变化完全可控。但今天一旦把大模型接进业务系统,事情就变得不一样了:同一个提示词问两次,模型给出的答案可能完全不一样;一个用户会话能持续几十分钟,上下文状态复杂到超过你所有数据库表结构的总和;AI Agent还会自己规划步骤、调用工具、决定下一步做什么,系统的行为边界变得模糊,复杂度已经不是“多加两台服务器”能扛住的了。这种由模型本身的概率性、长链路和自适应性带来的额外复杂度,我习惯叫它“智能化复杂性”。
这篇文章想聊的核心,是怎么用一套标准化的方法论去驾驭这种复杂性。不是让你抛弃微服务或分布式架构,而是要告诉你,在AI时代哪些架构原则依然成立,哪些已经失效,以及我实际落地时用的分层方式、Agent编排框架选择、可观测性设计思路。无论是已经在做AI应用开发的工程师,还是正打算把大模型接入现有系统的架构师,这篇文章应该能帮你少走不少弯路。
1. 为什么传统架构在AI时代失灵了
1.1 传统架构的核心假设正在被打破
我们在做传统软件架构时,脑子里默认有几条铁律。第一,接口是契约,输入输出结构稳定,服务之间靠明确的协议通信;第二,状态是可控的,数据库ACID事务能保证一致性,Session可以管理,超时重试就能处理异常;第三,流量是可以预估的,压测能摸到系统瓶颈,扩容是按计划进行的。这些假设在Web应用、电商系统、企业信息化里支撑了二十多年,非常有效。
但AI应用把这个最底层的“确定性假设”打掉了。模型推理本质上是概率计算,同样的输入可能得到不同的输出。这不是bug,而是特性。当你把这种不确定的组件嵌进一套追求确定性的架构里时,矛盾立刻出现:用户问“帮我查一下订单”,模型可能决定调用订单查询工具,也可能直接根据上下文编一个答案;模型的响应时间从几百毫秒到几十秒不等,完全打破了你预设的超时阈值;模型为了完成一个任务会连续调用多个工具,中间任何一步失败都可能让整条链路需要重试。如果你还在用设计订单系统的那套逻辑去设计AI应用,结果必然是大量超时、重试风暴、状态错乱。
这就像你用一个“制造标准齿轮”的流水线,突然要去制造“会自己学习的齿轮”。传统的质检标准、公差配合、装配流程统统失效,你得先想清楚新的质量定义是什么。
1.2 AI应用带来的四类新增复杂度
站在实际做项目的角度,我总结了四类必须先认清楚的新复杂度。
第一类是交互的不确定性。用户不会按你预设的意图说话,模型需要理解、拆解、反馈澄清,这种多轮交互的状态管理,要比传统表单提交复杂得多。一个对话Session里可能混合着身份信息、业务条件、历史纠偏、临时偏好,如何把它们组织成模型可用的上下文,本身就是设计重点。
第二类是链路的长时间特性。AI Agent执行一个任务可能需要几分钟甚至更久,比如“帮我调研市场数据,形成报告”,这中间可能调用搜索API、读取多个页面、对比数据、分步骤写出结论。传统HTTP请求-响应模型没法支撑这种长任务,你需要异步化、任务持久化、事件驱动。
第三类是模型集成的异构性。现实项目不会只接一家大模型,可能需要同时调用多个模型、多个工具、多个数据源,而这些服务各自的接口协议、认证方式、限流策略都不同。没有统一抽象层,业务代码就会被各种SDK绑死。
第四类是成本与性能的联动性。GPU推理有真实成本,一次复杂Agent任务可能触发几十次模型调用,费用不是线性可控的。同时,模型响应速度变化很大,如果你设计的是同步接口,系统吞吐量会直接被高延迟拖垮。这些都需要架构层面给出机制,而不是指望业务代码里做几个if判断。
这四类复杂度是AI时代架构设计的出发点。后面我讲的所有标准化方法,都是为了解决这四个问题,不是为了炫技。
2. 标准化分阶:从单体模型调用到分层架构
2.1 最容易被忽视的第一步:把模型调用封装成独立服务
很多团队一开始做AI功能,喜欢直接在业务代码里调用SDK,今天调OpenAI,明天调国内模型,后天后端又换了,业务代码里全是模型厂商的API格式。这种做法在Demo阶段没问题,但一旦上线,每一次模型供应商调整接口参数,你都要改业务代码,每一次想切换模型,都要动业务逻辑,这种耦合度会在项目三个月后变成巨大的坑。
我建议的第一步,是哪怕项目再小,也要把模型调用独立成一个内聚的模块,或者干脆独立成微服务。它在架构上扮演的角色是“模型网关”。对外暴露统一的接口,比如一个用于对话补全的方法,一个用于工具调用的方法,再一个用于获取模型状态的方法。对内负责处理不同厂商的协议差异、密钥管理、限流重试、Token统计。这层抽象的价值不是你今天能看到的,而是三个月后当你需要从A模型切换到B模型时,只需要改网关内部实现,业务层一行不动。
用生活里的例子类比,这就像你家的插座标准。电器厂商不用关心你家里是220V还是110V,插头做统一标准就行。模型网关就是那个“插座标准”,让各种电器(业务模块)能安全、稳定地用上不同电源(大模型)。
2.2 三层架构:接入层、业务编排层、基础设施层
在模型网关之上,我习惯再把AI应用拆成三个标准层次。这是我在多个项目里反复用的一套结构,效果比较稳。
第一层是接入层,负责跟用户打交道。它的职责是接收输入、流式输出、管理会话上下文和身份认证。这一层关心的是用户体验,比如打字机效果、中断响应、多模态输入。接入层不应该写任何业务逻辑,也不应该直接调用模型,它只是“门面”。
第二层是业务编排层,这是AI应用的核心。它负责理解用户意图、决定调用哪些工具、编排任务流程、维护流程状态。这一层可以是简单的Prompt+工具调用的循环,也可以是基于LangGraph这类框架的复杂状态机。重要的是,这一层应该跟模型供应商解耦,跟具体的传输协议解耦,只依赖统一的内部接口。
第三层是基础设施层,包括模型网关、向量数据库、工具服务、任务队列、可观测性组件。这些是AI应用的“地基”,比如工具服务把订单查询、文档检索、邮件发送等能力统一封装成可供Agent调用的API,向量数据库负责把非结构化知识变成可检索的向量。
这三层各司其职,改动边界清晰。接入层想从网页端拓展到小程序端,不需要动编排层;编排层想换一个Agent框架,不影响接入层和基础设施;需要新接一个大模型,只改模型网关。这套结构与微服务架构天然契合,也与传统分层架构思想一脉相承,但它对每一层的职责边界划得更加严格,因为AI应用的链条实在太长,任何一层职责不清都会导致整个系统难以维护。
2.3 Agent框架选型:LangChain与LangGraph怎么分
提到AI编排,绕不开LangChain和LangGraph这两个热门框架。但很多人搞不清楚它们的定位。我讲讲我的理解。
LangChain更像一个“工具箱”,它提供了大量与模型交互的链式封装、Prompt模板、文档加载器、模型接口适配器。它适合处理“相对线性的任务”,比如把一段文档拆成小块、做向量化、检索后拼接成Prompt再送给模型。这类任务的路径是给定的,步骤是静态的。
LangGraph则是“带状态的图引擎”。它把Agent的执行过程建模成一张图,节点是“执行某一步操作”,边是“状态转移条件”。它可以前一步的判断结果决定后一步走哪个分支,可以支持循环,可以把上下文状态持久化到外部存储并在多次请求之间共享。如果你做的Agent需要多轮规划、需要动态决策、需要中断后恢复,LangGraph会比LangChain裸写更顺手。
这两个框架不是互斥关系,实际项目里LangChain的组件可以在LangGraph的节点内部使用。我的经验是:小任务、固定流程,用LangChain的链式结构就好;要做复杂Agent,直接用LangGraph管理状态,节点内再调用LangChain的工具来简化代码。架构上不要被框架绑架,框架只是实现手段。
3. 核心实操:一个多工具Agent的完整实现
3.1 场景设计与任务拆解
纸上谈兵讲了这么多,我来一个能直接落地的例子。场景是做一个企业内部“知识助手”,它要能回答员工关于制度、文档、数据报表的问题,并且能主动调用工具去获取实时数据。比如员工问“上个月华东区销售额达标了吗”,这个任务不能靠预置文档回答,它需要:识别所需数据维度、调用报表查询接口、对比内部知识库中的目标值、计算达标情况、组织成自然语言回复。
这个场景包含了典型的智能化复杂性:多步任务(查数据、查目标、对比、总结)、动态决策(是否知道目标值、是否需要补充条件)、外部工具依赖(报表接口)、上下文持续(追问“那同比呢”)。
Agent要成功,第一关是任务拆解。跟我前面说的三层架构对应:接入层负责接收这条消息并保持Session;业务编排层里,LangGraph图来管理阶段节点;基础设施层里,一个报表工具服务提供统一的查询API,一个向量检索引擎存放制度文档。
3.2 LangGraph状态图的关键代码
下面给出核心的图编排代码,我用的是Python环境。先定义状态结构,这个结构在整张图里会被各节点读取和更新。
from typing import TypedDict, Annotated, Literal from langgraph.graph import StateGraph, END import json class AgentState(TypedDict): messages: list current_task: str tool_results: dict final_answer: str接着定义节点。第一个节点负责意图识别和任务规划,用大模型分析用户输入,输出一个结构化的规划JSON。
def plan_node(state: AgentState): prompt = f""" 你是任务规划器。分析用户的请求,输出一个JSON数组,数组每一项是一个子任务。 子任务类型只有两种:query_report(查询报表数据)和search_doc(检索知识库文档)。 输出格式: [{{"type": "query_report", "target": "华东区", "metric": "销售额", "period": "上月"}}] 用户请求: {state["messages"][-1]["content"]} """ response = call_model(prompt) # 内部走模型网关 plan = json.loads(response) state["current_task"] = plan[0].get("type", "") state["tool_results"]["plan"] = plan return state然后执行节点根据当前任务类型,调用对应的工具服务。这里的关键是,工具服务的API需要统一风格,参数传递和结果返回都走约定好的结构。
def execute_tool_node(state: AgentState): plan = state["tool_results"]["plan"] if not plan: return state task = plan[0] if task["type"] == "query_report": result = call_report_service( target=task["target"], metric=task["metric"], period=task["period"] ) if "remain_task" in task: # 还有后续任务 plan = plan[1:] state["tool_results"]["report_data"] = result elif task["type"] == "search_doc": result = call_vector_search(task["query"]) state["tool_results"]["doc_context"] = result state["current_task"] = plan[0]["type"] if plan else "done" return state最后有一个决策边,根据状态决定是继续执行下一个子任务,还是进入总结阶段。这个决策机制正是LangGraph相比普通函数链的最大价值。
def should_continue(state: AgentState) -> Literal["tool", "summarize"]: if state["current_task"] == "done": return "summarize" return "tool"然后把节点和边组装成图。
graph = StateGraph(AgentState) graph.add_node("plan", plan_node) graph.add_node("tool", execute_tool_node) graph.add_node("summarize", summarize_node) graph.set_entry_point("plan") graph.add_edge("plan", "tool") graph.add_conditional_edges( "tool", should_continue, {"tool": "tool", "summarize": "summarize"} ) graph.add_edge("summarize", END)这个代码示例不是完整生产代码,但架构形态已经出来了。你可以看到,整个流程被建模为一个有向图,状态是显式传递的,每一步都有清晰的输入输出,决策逻辑单独抽出来。这就是标准化的开始。
3.3 为什么图编排比硬编码流程更抗变化
有人会问,上面这套用普通的循环加判断也能写,为什么非要上个图引擎?区别在于三点。
第一,图把“控制流”和“业务逻辑”分开。你可以单独调整“如果工具调用失败是重试还是换策略”这样的边逻辑,不用改节点内部实现。
第二,图天然支持人为介入和断点续跑。比如Agent执行到一半,需要用户确认“是否继续调用第三方接口”,这时候你可以暂停图的执行,持久化状态,等用户确认后继续跑。这种能力在硬编码流程里实现起来非常痛苦。
第三,图结构可以可视化。LangGraph自带画图能力,整个Agent的执行路径、每个节点的耗时、每条边的选择次数都能追踪。这对于排查问题极其重要,尤其是Agent行为不稳定的情况下。
所以我的核心结论是:Agent的架构重点不是Prompt写得多花哨,而是把执行过程结构化、状态化、可追踪。这才能谈得上“标准化驾驭”。
4. 分布式架构与模型承载的工程实践
4.1 大模型服务化:部署、网关与弹性伸缩
聊完Agent编排,回到更底层的问题:模型本身怎么融入分布式系统。
模型部署方式和传统服务不太一样。一个开源大模型可能占几十GB显存,推理时需要整卡或整机资源,预热时间长,并发能力受限于显存带宽。把它封装成服务之后,你要面对的是“慢启动”和“高延迟”这两个传统负载均衡很难解决的问题。
在线推理通常需要常驻实例,但成本高,闲置浪费。我见过不少团队一开始把所有模型都常驻,结果GPU利用率不到10%。实用的方案是区分场景:核心业务路径上的轻量模型常驻,比如意图识别、文本分类;重量级生成模型做成按需启动,配合预热池和请求排队,避免冷启动让用户等几十秒。再加一个基于队列的异步调用机制,把同步请求转换成任务消息,前端轮询获取结果,这样能平滑模型推理慢带来的毛刺。
模型网关在这一层再次发挥作用。除了统一协议和密钥管理,还可以做:基于令牌桶的速率限制、并发控制、模型实例健康检查与自动摘除、不同租户的优先级队列。这些能力加在一起,模型承载层才真正具备生产可用性。
4.2 向量数据库与传统数据库的架构协同
AI应用经常需要处理非结构化知识,向量数据库几乎成了标配。但架构师容易犯一个错误:把原本存在关系型数据库里的业务数据也一股脑塞进向量库。我的建议是坚持“双库协同”:业务事实数据继续留在原库,保证事务和一致性;知识类内容、语义索引放到向量库,负责支持模糊检索。
举个例子,员工问“我们公司年假制度是什么”,答案来自企业制度文档,这类内容明显适合做向量化索引。但如果员工问“我今年的年假还剩几天”,这属于个人业务数据,必须去业务数据库查询,不能靠向量检索猜。正确的Agent设计是先通过意图识别判断需要哪种数据,再选择查询路径。这也正好呼应前面三层架构里“工具服务”存在的意义——数据源接入统一工具API,Agent不需要关心数据存在哪里,只需要调用工具并解析结果。
4.3 微服务架构在AI场景下的调整点
微服务架构在AI场景下需要一些务实调整。传统的同步RPC在调用链路上会增加延迟,而AI链路本身已经很长、已经够慢了,你再用一串多级同步调用把所有环节串起来,用户体验会崩。
我给三个调整建议。第一,链路内优先异步解耦,任务编排用消息队列传递,而不是层层HTTP嵌套。第二,超大Payload的传输要考虑限制,比如大模型返回内容可能很大,不要让其在服务间反复透传,该落盘落盘、该走对象存储走对象存储。第三,全链路要有一个统一的Trace ID贯穿,从用户请求到模型调用、到工具调用、到状态更新,每个环节都能按Trace ID检索日志。这不是说AI要推翻微服务,而是在微服务的基础上加了一层AI场景的适配规范。
5. 可观测性与评估体系:AI架构的定海神针
5.1 运行时可观测:不只盯日志,还要盯“行为逻辑”
传统架构的可观测性三板斧是日志、指标、链路追踪。AI应用需要在这个基础上增加三类观察维度。
第一类是模型输入输出监控。记录每一次模型调用的输入Token数、输出Token数、响应延迟、返回内容摘要。注意不要直接记录完整Prompt,里面可能含有用户隐私信息,要脱敏和截断。这些数据用于成本核算、延迟分析和异常定位。
第二类是Agent轨迹追踪。LangGraph里每走一步节点、选了哪条边、用了哪个工具、工具返回什么结果,都应该被记录成事件流。这样用户说“你答错了”,你可以精确回放Agent当时是怎么想的、在哪一步跑偏的。没有这套追踪,AI应用出了问题就像黑盒,你连从哪儿查起都不知道。
第三类是质量指标监控。比如用户对回答的点赞点踩、追问率、完成率。在线反馈和离线评估结合,才能持续掌握系统效果。别只看接口成功率,AI应用里“接口成功但答非所问”造成的伤害更隐蔽。
5.2 离线评估:把“感觉变好了”变成可回归的指标
AI应用上线后最怕什么?最怕改了Prompt或换了模型之后,效果到底是变好了还是变差了,全凭大家感觉。没有评估体系,你们团队会被“感觉”主导,但感觉是最不可靠的。
我的建议是建立一套离线评估集。至少准备300到500条带标准答案的测试用例,覆盖常见意图、边界情况、难题和已知Bad Case。每次更换模型、改动Prompt、调整Agent流程时,先把测试集跑一遍,用指标对比前后差异。指标不用太复杂,可以包括:准确率、关键信息命中率、格式合规率、平均延迟、平均成本。有这几项就能挡住大多数回退。
这里强调一个容易被忽视的点:评估集要持续生长。线上用户发现一个回答不对,立刻把这条记录加入评估集。否则你的系统永远在同一个坑里反复摔。标准化流程里要有这个“Bad Case回流机制”,评估集不是一次性资产,它是会进化的。
5.3 一套我可以直接给你的排查电话本
把线上AI应用的典型问题整理成速查表,按图索骥能省很多时间。
| 现象 | 可能原因 | 排查思路 |
|---|---|---|
| 回答结果与知识库不一致 | 检索召回相关度低 | 检查向量检索TopK设置和文本切分粒度 |
| 同一个问题多次回答差异大 | 温度参数过高 | 适当降低temperature,业务场景设0.2以下 |
| Agent调用工具频繁报错 | 工具输入参数格式不符 | 检查大模型生成JSON是否规范,增加输出格式校验 |
| 响应特别慢 | 模型排队或链路串行调用太多 | 看Trace耗时分布,考虑异步化或模型实例扩容 |
| 长时间运行后效果变差 | 上下文超过模型窗口被截断 | 引入上下文压缩或摘要策略 |
| 成本快速上涨 | 链路里模型调用次数过多 | 检查Agent循环是否失控,设最大迭代次数 |
这个表是通用起点,真正的坑往往藏在个别场景里,有了排查电话本,至少你能知道第一步踩在哪。
6. 避坑实录:我反复踩过的六个坑
6.1 过度编排与代码复杂度失控
刚用LangGraph那会儿,我非常兴奋,把一切能拆的都拆成节点,结果20行能解决的问题画了10个节点,代码可读性极差。后来反思,Agent架构的目标是让复杂流程可控,不是让简单流程复杂化。原则是:三条边内能解决的流程,不要画图;节点职责要足够内聚,不要设置“一个节点里既查数据又总结”的缝合怪。简单任务用简单方案,复杂任务才用图编排,这是最实在的经验。
6.2 把Prompt当配置,没有版本管理
Prompt在架构里是标准的“配置资产”,但它比普通配置更敏感。每次改Prompt,效果可能天翻地覆。我见过团队在生产环境偷偷改了一句Prompt,线上效果垮了两周,没人发现。现在我们的做法是:Prompt一定纳入版本管理,和代码一起走CI/CD流程,每次修改必须跑离线评估集,通过后才能合并发布。把这个机制养成习惯,能避免大量线上事故。
6.3 忽略上下文长度与成本联动
很多Agent的设计者在构思时永远假设模型窗口无限大,所有历史对话、所有工具结果统统塞进去。真到上线就发现,上下文越长,成本越高,延迟越大,而且模型对中段信息容易“遗忘”。我的习惯是给上下文设计“预算”:用户最近三轮对话、当前任务结果、必要长期信息摘要,这些内容严格控制总量。上下文管理不是事后优化,而是Agent架构设计的上游约束。
6.4 模型返回结果不校验直接落库
这是最容易出数据事故的坑。模型的自由文本输出直接当结构化数据写入业务系统,一旦模型产生幻觉或者格式漂移,脏数据就进去了。现在的标准化要求是:模型要输出结构化数据,必须通过Schema校验,推荐用Pydantic这类工具定义结构,模型输出后先校验再落库。自由文本可以落日志,但不能落业务表。这条规矩定得越早,后面的坑越少。
6.5 没有为用户设置“AI能力边界”
架构设计里最容易被忽略的是产品层面的语义边界。很多系统一开始什么都想让AI干,结果用户问什么都期望AI懂,期望落空了就疯狂投诉。我的经验是在接入层和编排层之间加一层“意图范围检查”,用户请求超出已定义能力范围时,明确告知“我不能处理这个”,而不是让模型硬答。能缩小幻觉爆炸半径,对系统稳定性很有帮助。
6.6 忽略小概率但高风险的操作链
Agent自动执行工具时,一定要考虑“危险动作确认”。比如一个Agent能替用户发邮件、删除记录,就必须设置策略:高影响动作先返回待确认状态,用户点击确认后再真正执行。这不是技术问题,是架构上必须有的安全闸门。LangGraph的中断机制正好能实现这个,强烈建议设计进图里,而不是事后补丁。
7. 标准化方法落地建议与未来展望
7.1 不要从零造轮子:合理利用开源与托管服务
很多团队一上来就想自研全套AI架构。我劝你冷静,AI领域的工具迭代速度太快,自研的东西大概率半年后就要推翻重来。务实的路线是:先基于成熟开源框架搭建,用LangGraph做编排、用主流模型网关方案做接入、用开源的向量库做检索。先把业务跑通,再针对痛点做定制。真正能留存的架构资产不是代码,而是你定义的那套接口、状态流转规范、评估体系和可观测性方案。
7.2 标准化不等于僵化:给架构留出“进化接口”
标准的价值在于降低认知成本,而不在于消灭变化。AI技术每个月都在变,今天的标准可能三个月后就显得笨拙。所以我建议设计架构时留三个“进化接口”:模型网关允许随时插拔新模型;编排引擎的节点允许独立替换核心实现;评估集允许持续追加新用例。这三点保证了系统能进化,不会被架构卡死。
7.3 我最终沉淀的架构清单
说了一整篇,最后整理一下我做完一个AI项目后一定会确认的架构清单:
- 模型调用是否已封装成独立网关,业务层不直接依赖厂商SDK
- 接入层、编排层、基础设施层是否职责清晰,边界是否可验证
- Agent流程是否用带状态的图引擎管理,状态是否持久化
- 所有模型输入输出是否有脱敏记录,Trace是否贯穿全链路
- 是否建有离线评估集并且纳入CI流程
- 工具接口是否统一风格并有Schema校验
- 高影响动作是否设置了人工确认机制
- 上下文大小和Token成本是否在架构设计阶段就做了预算
- 模型实例是否按场景区分常驻与按需部署
- 是否设定了迭代过程中Bad Case回流的机制
这十条每一条我都用真实的线上事故换过教训。AI架构不是把一个模型接进系统就完事的,它需要工程师从需求分析开始就带着“不确定性思维”。我用标准化来对抗这种不确定性,是这几年被坑之后摸索出来的最好用的一套路子。
我个人坚持的做法是:遇到AI的系统性问题时,先别急着调模型、调Prompt,先回看架构——是不是接口不统一?是不是状态没有做持久化?是不是评估体系缺失?大多数表面看是“效果问题”的故障,深挖到底都是架构问题。这行做得越久,我越觉得架构师要做的不是追求炫技,而是把不可控的东西,通过设计变得可控一点,再可控一点。这大概就是AI时代架构工作的最迷人之处。