
1. 为什么现在要聊 AI Native 架构过去两年我参与过三个从零起步的 AI 项目也接手过两个“传统系统硬塞大模型”的改造工程。这两类项目的体感差异非常大前者像在平整地基上盖楼后者像在已经装修好的房子里改承重墙。AI Native 架构这个词被说烂了但真正落地时很多团队做的其实只是“AI-Added”——在原有业务流末尾挂一个模型接口然后祈祷它别出错。我理解的 AI Native核心不是“用了大模型”而是系统的控制流、数据流、状态管理都围绕模型的概率性输出重新设计。传统后端假设函数调用是确定性的输入 A 必然得到 B超时就是失败异常可以重试。但模型调用不是这样——同样的输入可能得到不同输出延迟波动大还可能“一本正经地胡说”。如果架构不为此做专门设计后面会踩无数坑。这篇文章适合三类人正在规划 AI 原生应用的架构师、需要把大模型能力接入现有系统的后端工程师、以及想搞清楚“AI Native 到底和普通架构差在哪”的技术负责人。我会从整体设计思路讲到具体落地细节包括我实际踩过的坑和验证过的方案尽量给到可以直接抄作业的程度。2. 整体架构设计与核心思路拆解2.1 从“确定性编排”转向“概率性编排”传统微服务架构里编排层做的是确定性路由订单服务调用库存服务库存不够就返回失败逻辑清晰。但 AI Native 系统里编排层面对的是一个概率性组件。同一个 prompt模型可能返回三种不同格式的 JSON可能把字段名写错也可能在应该返回空的时候返回一段解释性文字。所以第一件事是把模型调用当成不可靠的远程服务来对待而不是当成一个本地函数。这意味着每次调用都要有输出校验层不能直接把模型返回透传给下游要有降级路径模型不可用或输出不合格时系统仍能给出合理响应要有重试与修正机制但重试策略和普通 HTTP 重试完全不同我试过一个很典型的场景让模型从用户自然语言里抽取“出发地、目的地、时间”三个字段。最初直接解析 JSON线上大概 8% 的请求会失败——有的是 JSON 格式错误有的是字段缺失有的是模型把“明天”理解成了具体日期但格式不对。后来加了一层结构化输出约束 校验重试失败率降到 0.5% 以下。这个后面会详细讲。2.2 分层设计把“不确定”关进笼子我的经验是AI Native 系统应该分成四层每层的职责边界要非常清楚层级职责确定性要求接入层鉴权、限流、请求预处理完全确定编排层任务分解、模型调度、状态管理逻辑确定但需处理概率输出模型层推理调用、prompt 管理、输出解析概率性需封装数据层向量检索、缓存、持久化完全确定关键原则是不确定性只能存在于模型层内部不能泄漏到编排层以上。也就是说编排层拿到的应该是经过校验和标准化的结果而不是原始模型输出。这个边界如果守不住后面每个下游服务都要处理各种脏数据维护成本会爆炸。2.3 为什么不用“大模型包打天下”有些团队一开始想得很美把所有逻辑都写进 prompt让模型自己决定调什么工具、走什么流程。我实测下来这种做法在 demo 阶段很惊艳但上生产后问题很多不可观测模型为什么走了这条分支不知道。不可测试同样的输入今天通过明天失败单元测试没法写。成本失控一个简单查询也走完整推理链token 消耗是结构化编排的 5-10 倍。所以我的建议是能用确定性代码做的决策绝不交给模型。模型只负责它真正擅长的事——理解自然语言、生成内容、在模糊场景下做判断。流程控制、权限校验、数据转换这些老老实实写代码。3. 核心细节解析与实操要点3.1 Prompt 管理与版本控制Prompt 是 AI Native 系统里的“核心配置”但很多团队把它硬编码在代码里改一次要发版。我踩过的坑是线上效果不好想回滚 prompt结果发现旧版本没保存只能凭记忆重写。正确的做法是把 prompt 当成一等公民来管理每个 prompt 有唯一 ID 和版本号变更走配置中心或数据库支持热更新每次模型调用记录使用的 prompt 版本方便归因重要 prompt 变更前做 A/B 测试我现在的习惯是prompt 文件用 YAML 管理包含模板、变量定义、输出格式约束和示例。这样非工程同学也能参与调整不用每次都找开发改代码。3.2 结构化输出的三种实现路径让模型稳定输出结构化数据我试过三种方案各有适用场景方案一Prompt 约束 正则解析。在 prompt 里明确要求“只返回 JSON不要任何解释”然后用正则提取。优点是简单缺点是模型偶尔不听话尤其是小模型。方案二Function Calling / Tool Use。利用模型原生的工具调用能力把输出 schema 定义成工具参数。这是目前最稳的方式主流模型都支持。缺点是灵活性稍差复杂嵌套结构表达起来麻烦。方案三输出后校验 自动重试。不管用哪种方式拿到输出都用 JSON Schema 校验一遍不合格就把错误信息塞回 prompt 让模型修正最多重试 2 次。这是兜底必须有。我现在的标准配置是方案二为主方案三兜底方案一作为降级。实测在主流模型上结构化输出成功率能到 99% 以上。3.3 状态管理与上下文窗口多轮对话场景下上下文管理是个大问题。全量塞进去 token 爆炸截断又丢信息。我的做法是分层记忆短期记忆最近 N 轮对话原文直接进 context中期记忆较早的对话做摘要压缩后保留长期记忆关键事实抽取后存向量库按需检索这里有个细节摘要本身也要调模型会增加延迟和成本。所以我会设置阈值——对话轮次少于 10 轮时不摘要超过后才触发。摘要用便宜的小模型做主推理用大模型成本能降不少。注意上下文截断时不要简单按 token 数切要把完整的对话轮次作为单位否则会出现“用户问了一半、助手答了一半”的诡异上下文模型容易困惑。3.4 缓存策略省钱的關鍵模型调用贵能缓存就缓存。但 AI 场景的缓存和普通缓存不一样精确缓存相同 prompt 相同参数直接返回上次结果。适合固定查询。语义缓存用向量相似度判断两个请求是否“意思一样”命中就复用。适合客服、问答类场景。分段缓存把 prompt 拆成“固定前缀 可变后缀”固定部分的结果可以复用。这个需要模型支持 prompt caching。我实测语义缓存能把重复请求的响应时间从 2 秒降到 50 毫秒成本降 60% 以上。但要注意设置相似度阈值太高会命中不相关结果太低等于没缓存。一般 0.92-0.95 比较合适具体要看业务。4. 实操过程与核心环节实现4.1 环境准备与基础依赖假设从零开始搭一个 AI Native 后端我的技术选型是这样的# 核心依赖Python 生态为例 pip install fastapi uvicorn # Web 框架 pip install openai anthropic # 模型 SDK pip install pydantic # 数据校验 pip install redis # 缓存 pip install qdrant-client # 向量库 pip install tenacity # 重试选 FastAPI 是因为它原生支持 Pydantic而 Pydantic 正好可以用来做模型输出的 schema 校验一举两得。向量库选 Qdrant 是因为它部署简单单机就能跑小规模场景够用。4.2 模型调用封装层实现这是整个系统最核心的部分。我的封装层大概长这样from pydantic import BaseModel, ValidationError from tenacity import retry, stop_after_attempt, wait_exponential class ExtractionResult(BaseModel): origin: str destination: str depart_time: str retry(stopstop_after_attempt(3), waitwait_exponential(multiplier1, max10)) def extract_with_retry(user_input: str) - ExtractionResult: raw call_model(build_prompt(user_input)) try: return ExtractionResult.model_validate_json(raw) except ValidationError as e: # 把错误信息塞回 prompt让模型自我修正 raw call_model(build_correction_prompt(user_input, raw, str(e))) return ExtractionResult.model_validate_json(raw)这里有几个关键点重试用指数退避因为模型限流时立刻重试大概率还是失败修正 prompt 要包含原始输出和错误信息模型看到具体哪里错了修正成功率更高最多重试 2-3 次再多就是浪费钱不如直接降级4.3 编排层的状态机设计编排层我用状态机来管理多步任务。比如一个“帮我订机票”的请求会经历意图识别 → 信息抽取 → 缺失字段追问 → 确认 → 执行。每一步的输出都是下一步的输入任何一步失败都要有明确的处理路径。class TaskState(Enum): INTENT intent EXTRACT extract CLARIFY clarify CONFIRM confirm EXECUTE execute FAILED failed def advance(state: TaskState, context: dict) - TaskState: if state TaskState.INTENT: return TaskState.EXTRACT if context[intent] book else TaskState.FAILED if state TaskState.EXTRACT: missing find_missing_fields(context) return TaskState.CLARIFY if missing else TaskState.CONFIRM # ... 以此类推状态机的好处是每一步都可观测、可测试、可回放。出问题时能精确定位到是哪一步、哪个 prompt、哪个模型版本导致的。4.4 可观测性建设AI 系统的可观测性和传统系统差别很大。除了常规的 QPS、延迟、错误率还要监控Token 消耗按模型、按接口、按用户维度统计输出质量校验失败率、重试率、降级率Prompt 效果不同版本的通过率对比成本实时计算每次调用的费用我用 OpenTelemetry 做链路追踪每次模型调用作为一个 span把 prompt 版本、模型名、token 数、耗时都打进去。这样排查问题时能直接看到“这个请求为什么慢”——是模型本身慢还是重试了还是向量检索拖后腿。实操心得日志里不要记录完整的 prompt 和输出涉及用户隐私而且量太大。记录 hash 和关键字段即可需要时再按 ID 捞取。5. 常见问题与排查技巧实录5.1 模型输出不稳定怎么办这是最高频的问题。我的排查顺序是看 temperature如果设成 0.7 以上输出波动大是正常的。结构化抽取类任务建议 0-0.2。看 prompt 是否有歧义让同事读一遍如果人都不确定该输出什么模型更不确定。看是否触发了重试重试率高说明首次成功率低要优化 prompt 或换模型。看模型版本有些模型小版本更新会改变输出风格锁定版本号。5.2 延迟太高怎么优化模型调用延迟通常占整个请求的 70% 以上。优化手段按性价比排序手段延迟降幅成本适用场景语义缓存80%低重复请求多流式输出首字延迟降 60%低对话类小模型替代50%低简单任务并行调用取决于任务中多步独立Prompt 精简10-30%低所有场景我一般先上缓存和流式这两个改动小见效快。小模型替代要谨慎得先验证效果不掉。5.3 成本失控的排查清单有次月底看账单吓了一跳排查后发现是某个接口的重试逻辑写错了失败后无限重试。所以成本监控一定要做实时告警。常见成本黑洞重试没有上限上下文没有截断越聊越长缓存没命中但每次都查向量库日志把完整 prompt 存下来存储成本比推理还高5.4 常见问题速查表现象可能原因排查方向输出格式错误率高prompt 约束不够 / 模型能力不足加 schema 校验、换模型响应时间波动大模型侧负载 / 重试看 span 详情、限流成本突然上涨重试风暴 / 上下文膨胀查重试率、token 统计效果时好时坏prompt 版本混乱 / 模型更新锁定版本、A/B 对比缓存命中率低阈值设置不当 / 请求差异大调阈值、看样本6. 我踩过的几个真实坑第一个坑是过度依赖模型做决策。早期我把“是否需要追问用户”也交给模型判断结果模型有时候觉得信息够了就直接执行有时候又反复追问。后来改成用代码判断必填字段是否齐全模型只负责抽取稳定性立刻上来了。第二个坑是忽略冷启动。向量库刚建时数据少语义缓存命中率极低延迟和成本都没降下来。后来做了预热把高频请求提前灌进去效果才体现。第三个坑是prompt 里的示例太多。我一度以为示例越多效果越好结果 prompt 长到 3000 token延迟高、成本高效果反而下降——模型被示例带偏了。后来精简到 2-3 个高质量示例效果更好。最后一个体会是AI Native 架构的难点不在模型本身而在如何围绕模型的不确定性构建一套可靠的工程体系。模型能力会不断进步但这套工程方法论是通用的。把校验、重试、降级、可观测这些基础设施做扎实换什么模型都能快速接入。