AI全栈开发实战:从架构设计到成本控制的关键实践
发布时间:2026/9/8 22:36:34 作者:尧图编辑部 阅读量:1,286

我第一次带团队做AI全栈项目时最深的感受是大家以为这是“调一下大模型API”结果做成了一个涵盖模型网关、RAG管线、Agent编排、流式前端、成本治理的系统工程。我是传统全栈出身写了好几年CRUD真正上手AI应用开发后才发现有一部分经验能复用但更多经验需要推翻重来。这篇文章是我近一年在AI全栈开发上的实践总结适合三种人看打算从0到1构建AI应用的工程师负责AI产品落地的产品经理以及想系统化提升团队AI工程能力的技术负责人。我会把技术选型、架构设计、前端联调、测试评估、部署运维还有团队协作里容易踩的坑一起讲透。内容里面有很多是我自己踩过之后补起来的“应该这样做”不是教科书式的理论。1. 先理清边界AI全栈项目与传统应用到底哪里不一样1.1 传统全栈的思路为什么会失灵传统全栈开发本质上是写一个确定的函数用户传参系统校验业务逻辑处理返回固定结构的结果。接口定义清楚异常路径明确一个订单接口从入参到出参几乎可以穷举所有情况。但AI应用不一样用户输入是自然语言模型输出具有概率性——同一个Prompt温度调到0.7和调到0.2产出的结果可能完全不同甚至温度相同、连续调用两次也可能得到两个版本。我见过最典型的翻车方式是团队用传统接口思维去做AI后端先定义一个“完美”的输出JSON Schema然后要求大模型必须返回这个格式结果模型偶尔多了一个字段或者漏了一个字段整个接口就崩了。他们花了两周时间写各种正则和重试逻辑去修补最后还是不稳定。正确的思路应该是不要试图用if-else去兜住模型的不确定性而是用架构去兜底。1.2 模型在架构中的真实角色很多AI应用架构图会把大模型画成一个位于中心的“大脑”所有请求都直接打进模型。这是误导。模型在系统里的真实角色应该是一个“推理引擎”它擅长的是理解语义、归纳总结、生成内容、拆解任务但它不擅长稳定地存储事实、执行精确计算或保证事务一致性。你让模型去记用户余额它会一本正经地编一个数字出来你让模型去算价格它甚至会在同一段话里出现前后矛盾的结果。所以AI全栈架构的核心原则是能用代码和数据库确定做的事就别交给模型。举个例子电商场景里计算优惠金额、库存扣减、订单状态流转这些必须由业务代码做模型只负责理解用户意图、生成话术、抽出关键信息然后把抽取结果交给代码去执行。这个边界划清楚之后系统稳定性会提升一个量级。1.3 最常见的架构错误把业务规则写进Prompt我拆过不少“看起来能用但一上线就崩”的AI项目发现一个通病业务规则全在Prompt里。比如“如果用户是VIP且订单超过100元则提示可以免运费”“如果商品库存小于10要提示用户尽快下单”这些规则全塞在系统提示词里。结果就是提示词越来越长模型偶尔漏掉某条规则产品经理就让开发继续往Prompt里加话术直到Token长度爆掉。正确的做法是凡是可枚举、可判断的逻辑都抽到代码里做。模型只负责比较窄的一层任务——例如从用户消息中提取“是否询问运费”“有没有表达购买意愿”然后代码根据这些结构化结果决定走哪条分支。Prompt里放的是模型必需的背景知识和表达风格不是业务规则。你在评审代码的时候如果看到某条业务规则出现在字符串模板里就要警惕了。2. 技术选型实操模型、网关与开发框架怎么搭配2.1 模型选型按任务复杂度分梯队很多团队一上来就选最强的大模型仿佛模型越强应用就越强。实际不是这样。大模型的能力强但成本、延迟、合规风险也高。我现在的习惯是把任务分成几个梯队任务类型适合的模型梯队理由意图分类、实体抽取、格式化输出中小尺寸模型延迟低、成本低任务简单不需要太强推理客服问答、内容总结、RAG生成中高端通用模型需要理解复杂上下文但不需要极端推理代码生成、复杂推理、多步任务规划顶级大模型一步错步步错必须用最强推理能力语音转写、图片理解专门的多模态模型不要用文本模型硬扛这里有个容易忽略的点同一个应用里可以同时用多个模型没必要一锅端。例如我的一个知识库问答系统入口先用一个小模型判断用户意图、提取关键词然后只有真正需要长文生成时才调用大模型。这样整体成本能下降40%到60%响应速度也快很多。2.2 模型网关为什么值得在业务与模型之间加一层LiteLLM早期做AI应用团队通常是直接调模型厂商的SDKA厂商用一套SDKB厂商又有一套代码里写满了厂商特定的配置。换模型或做A/B测试时恨不得改半个月的代码。后来我开始在业务代码和模型之间加一层模型网关目前用得最多的是LiteLLM。LiteLLM做的事情很简单提供统一的OpenAI风格接口后面接不同厂商的模型——无论是云厂商的API还是自己用vLLM部署的开源模型。业务代码只认一个base_url模型切换、路由、成本统计、限流都可以在网关层配置。比如我们有一段代码原来是这么写的from openai import OpenAI client OpenAI(base_urlhttp://your-gateway:4000, api_keyfake-key) response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 你好}], )不管后端实际跑的是哪家模型业务代码都不变。你要做的只是改网关路由配置把gpt-4o映射到另一个模型上。这在做模型灰度、成本控制、灾备切换时特别有用。我强烈建议任何超过两个模型调用的项目都先把模型网关搭起来别等代码写完了再补。2.3 开发框架Spring AI、LangChain还是原生SDK这是团队选型时问得最多的问题。我的答案分场景如果团队是Java后端已经有很多Spring Boot服务直接上Spring AI。它把AI调用、提示词模板、结构化输出都整合进了Spring生态和事务、配置、监控打通学习成本对Java工程师很低。如果团队是Python技术栈且需要灵活做RAG、Agent编排LangChain可以用但不能无脑用。LangChain最大的问题是抽象层级太多出了问题很难排查。我建议只挑它里面成熟的部分用比如文档加载、文本分割、向量存储接口至于复杂的Agent链自己写比硬套框架更可控。如果应用逻辑简单只是调用聊天和补全直接用模型厂商的SDK就够了不要为了用框架而用框架。框架不是越重越好。AI技术迭代非常快今天的最佳实践三个月后可能过时。保持薄封装把可替换性留在模型网关那一层比什么都强。2.4 数据层向量库与业务数据库的边界RAG项目只要涉及资料检索几乎都要接向量库常见的有Milvus、pgvector、Qdrant、Chroma。但很多团队把向量库当成了“另存为”的数据库把原始文档、元数据、用户数据全部塞进去结果和业务数据库之间无法同步数据一致性变得一团糟。我的建议是向量库存的应该是“文档切块后的向量定位信息”原始业务数据仍然留在业务数据库里。向量库里记录document_id、chunk_id和对应的业务主键检索命中了某个切片之后再通过业务主键去业务数据库取完整的最新数据。这样权限控制、数据更新、事务一致性都还能沿用传统数据库的方案。向量库不是万能的它只解决“语义相似度检索”这一个问题。3. RAG与Agent从demo到可用系统的关键一跃3.1 RAG不是接一个向量库那么简单很多团队半天就能跑通一个RAG demo文档丢进去切块向量化检索拼接Prompt完成。但demo和可用系统之间差得很远。我见过最多的问题是“检索回了一大堆不相干内容模型反而被带偏了”。首先要做的是合理的文本切块。固定字数切块不叫方案那是暴力破解。我通常的做法是先按标题层级把文档切成语义段落每个段落再按滑动窗口切成块块大小控制在500到800个字符重叠100到200字符。切完之后必须人工抽查切片看看有没有把一个完整的意思断成两截。切块的质量直接决定检索质量这一步偷懒后来都要还的。其次要设计召回策略。只做向量召回不够遇到数字、编号、专业术语向量相似度往往不靠谱。我现在普遍采用“混合检索”向量召回Top20关键词召回Top20然后做重排把最终进入大模型的片段控制在3到5个。重排可以用Rerank模型也可以简单做一个基于关键词命中和位置得分的加权公式。重点不在于算法多高级而在于你能看到每个检索结果的得分方便调试。3.2 Agent编排把工具调用变成可观测流程Agent是AI全栈里最吸引人也最容易失控的部分。我的态度是能用确定工作流解决的问题就别让Agent自由发挥。比如填一个订单查询流程你完全可以写一个状态机读取用户意图之后走固定分支。Agent适合的是那种分支实在太多、预先无法穷举的场景。当你确实需要Agent时要注意把工具调用变成可观测的流程。我用的是很朴素的方案每次Agent调用工具前记录一条日志包含任务ID、当前步骤、调用工具名、传给工具的参数工具返回后再记录工具的返回摘要。这些日志聚合起来就是一次Agent执行的完整轨迹。排查问题时如果没有这些轨迹你根本不知道它是哪一步开始胡说的。我踩过的另一个坑是Agent循环。早期代码里没有设置最大迭代次数Agent在某个工具上报错后不断重试一次交互跑了几十轮Token费用蹭蹭涨用户那边还一直转圈。现在所有Agent循环都必须设置两个上限最大调用次数比如5次和最大耗时比如30秒。一旦超限立刻停止把当前状态返还给用户并说明“事情没办完但我会继续跟进”。3.3 提示词与流程的工程化管理提示词是代码资产不是文案。很多团队把提示词写在聊天框里试来试去最后不知道哪版在上线环境。我现在要求所有提示词都纳入版本管理和代码一起走Git提交每个Prompt都有明确的版本号、变更人和变更原因。页面模板也要做灰度。最常见的办法是我们把所有Prompt模板放到单独的配置文件里线上环境支持按用户ID或按比例路由到不同模板版本然后对比业务指标。比如客服助手先在10%的流量上试新话术观察用户满意度、转人工率、回答准确率再决定是否全量放开。这个过程如果靠开发改代码再发版速度太慢所以要在一开始就把模板和代码解耦。4. 前后端联调实战流式、会话与状态管理4.1 SSE流式输出的几个坑AI对话类应用几乎避不开流式输出因为用户等不了好几秒才看到第一个字。最常用的方案是SSEServer-Sent Events但这里面的细节坑很多。后端用FastAPI实现SSE并不难from fastapi import FastAPI, Request from fastapi.responses import StreamingResponse app FastAPI() async def event_stream(request: Request): async for chunk in llm_stream(request): yield fdata: {chunk}\n\n app.post(/chat) async def chat(request: Request): return StreamingResponse(event_stream(request), media_typetext/event-stream)前端用fetch读取流式响应时要注意浏览器对SSE连接数量的限制同一个域名同时只能开6个HTTP连接。如果你在页面上做了流式输出的同时还要轮询其他接口连接很容易被占满表现为“第二个对话打开后一直不输出”。另外一个坑是反向代理的缓冲。Nginx默认会对响应做缓冲流式内容会被攒在一起用户等半天看不到字。必须在Nginx里关掉缓冲加上proxy_buffering off;和X-Accel-Buffering: no才能真正做到逐字输出。还有前端在中断请求时后端流可能还在跑需要监听连接断开事件及时停止大模型调用避免白白消耗Token。4.2 上下文与Token预算管理多轮对话一定会碰到上下文爆炸的问题。把历史消息全部塞给大模型最开始还能忍聊到第20轮光历史就有上万Token既贵又慢模型还容易被早期信息干扰。我的方案是分层管理上下文短期记忆最近3到5轮消息原文完整保留中期记忆对前面的对话做周期性摘要生成一个简短的“对话进展概要”长期记忆从对话中抽取用户的关键信息比如偏好、待办事项存到业务库里。每次调用模型时按“系统提示词 长期关键词 中期摘要 最近几轮消息 当前问题”的顺序拼装。这个拼装顺序不是随意排的模型对离当前位置越近的内容越敏感所以当前问题必须放在最靠近的位置。实测下来这种方案能把单次调用的Token消耗减少一半以上同时对话体验几乎没有损失。4.3 前端体验从“等待”到“协作”AI应用的前端交互和传统表单提交有本质区别。用户在等模型回答的时候并不是无事可做他可能会继续输入文字可能想取消上一次请求也可能需要看到模型“正在检索资料”的过程。我建议至少做到三件事第一流式输出时必须支持“停止生成”按钮否则用户看着一段错误答案被慢慢打出来会很崩溃第二要有阶段状态提示比如“正在理解问题”“正在检索资料”“正在生成回答”让用户知道系统在干什么第三历史会话要支持折叠和续聊聊到一半刷新页面后应该能恢复上下文。这些看起来是体验细节但对于AI产品用户容忍度很低。传统网页加载慢一点用户可能等但AI回答一旦让人觉得“这是在胡扯”或者“怎么不动了”用户会立刻关掉页面。前端交互的稳定感比UI好看重要得多。5. 用评测集和回归测试兜住AI应用的质量底线5.1 为什么传统测试方法会失效传统后端测试可以用确定性断言输入A期待输出B比较结果。但大模型输出每次都有细微差别你不能断言“必须等于某个字符串”也不应该断言“必须包含某个关键词”因为这些都不稳定。我曾经犯过一个错误用一批历史问题测试新Prompt发现效果明显提升于是直接上线结果第二天用户反馈大量问题。原因是那批测试问题是我手工挑的集中在少数场景根本没覆盖真实用户的边界情况。AI应用必须建立专门的评测集而不是拿几个例子随便点点。5.2 搭建最小可用评测集评测集不需要一开始就很大但必须覆盖核心场景和边界情况。我起步的方式是从真实用户日志里挑200条问题按场景分类——例如“查订单”“问价格”“投诉”“闲聊”“多轮追问”“模糊问题”等每个场景至少20条。每条问题配上参考答案参考答案可以由产品经理和运营一起写不要求措辞完全一致但要有明确的判定标准。评测指标我一般分三个维度指标含义评测方式准确率回答内容是否正确人工打分或LLM对照参考答案打分相关性回答是否切题评估答案与问题的语义相关度毒性/安全是否出现违禁内容规则加模型审核每次Prompt模板有改动、模型版本有升级都先跑一遍这个评测集。如果准确率低于某个阈值不允许上线。这个流程听起来简单但它能拦住大部分“凭感觉觉得变好了”的不靠谱改动。5.3 LLM作为裁判与回归框架人工评测200条问题一次要花半天频率高了不现实。所以我现在引入了LLM-as-Judge用一个大模型去给另一个模型的回答打分。当然这也有偏差不能完全替代人工但它适合做快速回归。具体做法是给裁判模型一份评分标准例如“1分完全错误2分部分正确3分完全正确”并且要求它先输出评分理由再给分数。每周对同一批测试集跑一遍生成一份回归报告比较当前生产版本和候选版本的分数差异。如果候选版本得分低于生产版本2个百分点以上直接拒绝。这样做虽然不能保证所有问题都拦住但至少能拦住大多数明显退化的情况。6. 部署、监控与成本控制上线只是开始6.1 模型部署的三种方式与取舍AI应用部署与传统后端最大的不同是你必须先决定模型跑在哪。通常有三种选择部署方式优点缺点典型场景直接调用云厂商API速度快、维护少、模型最全成本随量线性增长、数据出域初期验证、对延迟不敏感的业务自建模型服务vLLM等单次成本低、数据可控GPU运维复杂、需要弹性伸缩稳定高并发、成本敏感混合模式灵活、成本与效果平衡架构复杂、需要路由策略大部分生产系统最终形态如果自建模型服务我强烈建议用vLLM它对推理做了很多优化吞吐量比原生Transformers高很多。部署时要注意设置合理的并发度和超时时间GPU显存不够会直接OOM服务不会自动恢复。监控要盯GPU利用率、显存占用、首token延迟、生成token速度这些指标每一项都直接影响用户体验。6.2 成本控制的第一道防线缓存、限流与路由策略AI应用的成本大头几乎都在模型调用上。我发现很多团队直到月底账单出来才惊呼“怎么花了这么多”其实成本控制应该从第一天就设计进去。第一层是缓存。相同的用户问题、相似的上下文在一天内经常会被重复问到。我在模型网关前面加了一层语义缓存把用户问题转成向量命中相似度超过阈值的直接返回缓存答案。这个方案对知识库类问答特别有效实测能减少30%到50%的模型调用。第二层是限流和熔断。每个用户每分钟最多调多少次每天最多多少Token都要在模型网关层配置好。不限流的结果是某个客户写了个脚本疯狂调用账单直接爆掉。第三层是路由策略。像我在模型选型一节说的简单任务走便宜模型难任务才走贵模型。网关配置里设置规则例如意图分类用haiku长文生成用opus成本能肉眼可见地降下来。6.3 可观测性让每一次推理都留着“病历”AI应用排查问题比传统应用困难得多因为你看不到模型“为什么这样回答”。如果连日志都没有出了问题就只能靠用户截图。我们现在有一个硬性要求每次模型调用必须记录以下几项内容——请求完整内容、响应完整内容、使用的模型名称和参数、Prompt模板版本、检索到的文档片段、Token消耗、响应耗时。这些记录聚合到一起就是一次推理的完整病历。出问题的时候我们可以回放用户当时看到的上下文复现模型到底是怎么得出这个答案的。我自己遇到过一个模型“失忆”的问题就是靠日志才发现是前端没有按照约定传历史消息导致模型每次都不知道之前聊了什么。没有完整日志这种问题根本无从查起。7. 团队协作与避坑清单技术之外的最后一公里7.1 产品经理、算法、测试与全栈工程师怎么配合AI项目的失败很多时候不是因为技术不行而是角色之间没法协作。传统项目里产品经理写需求文档后端定接口前端开发页面测试验证逻辑边界非常清晰。但AI项目里产品经理要定义的是“模型应该怎么理解用户”这个需求很难用传统的PRD写清楚需要产品和工程一起迭代Prompt。我给团队定的做事方式是产品经理负责准备评测用例和表述“想要的回答风格”全栈工程师负责把模型能力封装成接口算法或AI工程师负责调优提示词和Agent逻辑测试工程师负责维护评测集和回归流程。每个版本发布之前产品、研发、测试三方必须一起过一遍评测集而不是各看各的。7.2 我反复踩过的十个坑这十条是我近期项目里反复踩过、最后沉淀进团队规范里的经验Prompt改了但没记录版本上线后想回滚只能靠CTRLZ。向量化用的是大模型Embedding切块不对导致召回质量差还怪模型不行。流式接口没做超时控制用户关页面后模型还在跑Token白白烧掉。上下文管理直接丢全部历史聊了20轮后单次成本飙到起飞。评测集只有别人给的示例没有真实用户问题上线就被打脸。没有踩刹车机制Agent死循环把预算烧光。模型输出JSON没有容错解析少一个逗号整个服务报错。缓存没有失效策略用户资料更新了回答还是旧版。日志里不存请求原文出问题想复现都复现不了。一上来就接最强模型成本高延迟大后来换成分级路由体验反而更好。7.3 最后说点掏心窝的建议如果你现在刚开始做AI全栈我的建议是从一个窄场景切入不要一上来就做“所有问题的答案”。先解决一个用户痛点把模型、数据、评测、监控这条路跑通再考虑扩展。技术栈的选择上保持薄封装、多留接口、随时准备换模型这比选哪个框架更重要。AI全栈开发本质上不是“会调大模型”就行的它考验的是你能否把一个不确定的模型引擎镶嵌进一个确定性的业务系统里并让它稳定地创造价值。这条路没有银子弹但把这些基础实践做好至少能让你少走很多弯路。