构建生成式AI平台
Building A Generative AI Platform — Chip Huyen
📄 huyenchip.com 📅 2024-07-25 ✍️ Chip Huyen 📖 《AI Engineering》作者

🎯 核心结论

一句话概括

本文系统性地阐述了企业部署生成式AI应用的通用平台架构,从最简单的"查询→模型→响应"开始,逐步添加上下文增强(RAG)、安全防护(Guardrails)、路由网关(Router/Gateway)、缓存优化(Cache)、复杂逻辑与写操作(Write Actions),以及贯穿始终的可观测性(Observability)和编排(Orchestration)。

平台演进五步法

  1. 增强上下文:RAG、Text-to-SQL、Web Search、Query Rewriting
  2. 安全防护:输入防护(PII检测、越狱防护)+ 输出防护(质量评估、失败管理)
  3. 路由与网关:Intent Classifier 路由到不同模型,Gateway 统一接入与管控
  4. 缓存优化:Prompt Cache、Exact Cache、Semantic Cache
  5. 复杂逻辑与写操作:循环、条件分支、Agentic 工作流、写操作(邮件发送、订单下单)

🏗️ 架构全景

┌─────────────────────────────────────────────────────────────────────┐ │ 生成式AI平台架构 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 用户查询 ──► [输入防护] ──► [查询改写] ──► [上下文构建/RAG] │ │ │ │ │ │ │ │ ▼ ▼ │ │ │ [缓存系统] [检索: Term/向量/混合] │ │ │ │ │ │ │ │ └──────────────┘ │ │ │ │ │ │ │ ▼ │ │ │ [模型路由] │ │ │ ┌─────────┐ │ │ │ │Intent │──► 专业模型A │ │ │ │Classifier│──► 专业模型B │ │ │ └─────────┘──► 通用模型 │ │ │ │ │ │ │ ▼ │ │ │ [模型网关] │ │ │ ┌─────────┐ │ │ │ │OpenAI │ │ │ │ │Anthropic│ │ │ │ │自托管 │ │ │ │ └─────────┘ │ │ │ │ │ │ │ ▼ │ │ │ [模型API] │ │ │ (生成 + 评分) │ │ │ │ │ │ │ ▼ │ │ │ [输出防护] │ │ │ ├─ 质量评估 │ │ │ ├─ 毒性检测 │ │ │ ├─ 幻觉检测 │ │ │ └─ 失败重试/降级 │ │ │ │ │ │ ▼ ▼ │ │ [流式输出] ◄──────────────────── [响应缓存] ◄── [写操作/Agent] │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 可观测性: Logs + Traces + Metrics │ │ │ │ 编排器: LangChain / LlamaIndex / Flowise │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘

📚 Step 1:增强上下文(Context Construction)

核心思想

上下文构建对于基础模型,等价于特征工程对于传统机器学习。给模型提供越相关的上下文信息,模型越不需要依赖不可靠的内部知识,从而减少幻觉。

RAG(检索增强生成)

RAG = 生成器(语言模型)+ 检索器(从外部源获取信息)

检索方式 技术 优缺点
词项检索 关键词搜索、BM25、Elasticsearch 更快更便宜,开箱即用,强大基线
嵌入检索 BERT、Sentence-Transformers、OpenAI Embedding + FAISS/ScaNN/HNSW 计算昂贵,但可随时间优化超越词项检索
混合检索 词项检索获取候选 → 向量检索重排序 生产环境常用,兼顾效率与精度

💡 上下文重排序 vs 搜索重排序的区别

在搜索中,排名(第1还是第5)至关重要。但在上下文重排序中,只要文档被包含进来,顺序的影响相对较小(虽然模型对开头和结尾的文档理解更好——"Lost in the middle"效应)。

结构化数据 RAG:Text-to-SQL

  1. Text-to-SQL:根据用户查询和表结构,生成 SQL 查询
  2. SQL 执行:执行生成的 SQL
  3. 生成响应:基于 SQL 结果和原始查询生成回答

Agentic RAG

将词项检索、嵌入检索、SQL 执行、Web 搜索等都视为模型可以调用的动作(Action)。模型根据查询决定调用哪些动作来增强上下文。

查询改写(Query Rewriting)

用户:When was the last time John Doe bought something from us? AI:John last bought a Fruity Fedora hat from us two weeks ago, on January 3, 2030. 用户:How about Emily Doe?
→ 需要改写为 "When was the last time Emily Doe bought something from us?"

查询改写通常由另一个 AI 模型完成,使用类似 "Given the following conversation, rewrite the last user input to reflect what the user is actually asking" 的提示。

🛡️ Step 2:安全防护(Guardrails)

输入防护(Input Guardrails)

风险一:敏感信息泄露到外部 API

⚠️ 典型案例

三星员工将公司专有信息输入 ChatGPT,导致机密泄露。2023年5月三星禁止员工使用 ChatGPT。

解决方案:使用 PII 检测工具自动识别敏感数据:

发现敏感信息后:要么阻断整个查询,要么脱敏处理(如将手机号替换为 [PHONE NUMBER],响应后再通过可逆字典还原)。

风险二:模型越狱(Jailbreaking)

解决方案

输出防护(Output Guardrails)

失败模式 检测方法 处理策略
空响应 直接检查 重试 X 次
格式错误 Regex/JSON/Python 验证器 重试,或使用约束采样(guidance/outlines/instructor)
毒性内容 毒性检测工具 阻断或人工审核
幻觉 SelfCheckGPT、SAFE 提供充足上下文 + CoT 提示
敏感信息泄露 与输入相同的 PII 检测工具 阻断,不训练敏感数据
品牌风险 关键词监控 + 情感分析 阻断、人工审核、AI 情感检测
一般性质量差 AI Judge(通用模型或专门评分器) 重试或转人工

失败管理策略

🔄 重试逻辑

空响应/格式错误时重试 X 次。缺点是延迟和成本翻倍。

⚡ 并行调用

同时发送 2 个相同查询,取更好的结果。延迟不变,成本 2x。

👤 人工兜底

含特定关键词转人工,或情感分析检测到用户愤怒时转人工。

⚠️ 流式输出的防护难题

流式输出(Stream Completion)模式下,token 实时推送给用户,系统难以在输出完成前评估其安全性。不安全的响应可能在防护系统判定前就已展示给用户

🚦 Step 3:模型路由与网关

Router(路由器)

核心功能:Intent Classification

根据用户意图将查询路由到不同的处理路径:

  • 重置密码 → 跳转到密码重置页面
  • 账单纠错 → 转人工客服
  • 技术故障排查 → 路由到专门微调的故障排查模型

💡 路由器的额外价值

  • 成本优化:简单查询路由到便宜模型,复杂查询才用昂贵模型
  • 避免范围外对话:识别越界查询,用 stock response 礼貌拒绝,不浪费 API 调用
  • Next-Action Prediction:决定下一步动作(如请求澄清)

Gateway(网关)

网关是组织与不同模型交互的统一中间层

功能 说明
统一接口 OpenAI、Google、自托管模型用同一套 API 调用
访问控制 不直接暴露组织 API Key,集中管控
成本管理 监控和限制 API 调用,防止滥用
故障降级 主 API 不可用时路由到备用模型/重试
负载均衡 分发请求到多个模型实例
日志与分析 请求/响应流经网关,天然可记录

现有网关工具:Portkey、MLflow AI Gateway、WealthSimple's llm-gateway、TrueFoundry、Kong、Cloudflare

💾 Step 4:缓存优化(Cache)

"Cache is perhaps the most underrated component of an AI platform."
—— Eugene Yan

Prompt Cache(提示缓存)

核心机制

许多查询共享相同的系统提示(System Prompt)。Prompt Cache 存储这些重叠段,只处理一次。

效果:如果系统提示 1000 tokens,每天 100 万次调用,可节省约 10 亿 tokens/天的处理。

商业实现:Google Gemini API 的 Context Cache(2024年6月),缓存输入 token 打 75 折,但需支付缓存存储费($1/百万tokens/小时)。

Exact Cache(精确缓存)

完全相同的查询直接返回缓存结果。适用于:

实现:内存存储(Redis)或数据库(PostgreSQL),配合 LRU/LFU/FIFO 淘汰策略。

Semantic Cache(语义缓存)

✅ 原理

查询 "What's the capital of Vietnam?" 和 "What's the capital city of Vietnam?" 语义相同,可复用答案 "Hanoi"。

⚠️ 挑战

  • 依赖高质量嵌入
  • 向量搜索本身耗时耗算力
  • 相似度阈值难以设定
  • 误判风险高(返回错误缓存)

实现:嵌入模型生成查询向量 → 向量数据库搜索最近邻 → 相似度超过阈值则返回缓存结果。

⚠️ 什么不该缓存?

  • 用户特定查询:"我的最近订单状态" 不太可能被其他用户复用
  • 时间敏感查询:"今天天气如何"

可用小型分类器预测查询是否值得缓存。

🤖 Step 5:复杂逻辑与写操作

复杂逻辑(Complex Logic)

模型输出可以条件性地传递给另一个模型,或反馈给同一个模型作为下一步输入,形成循环和条件分支。

查询:"Plan a weekend itinerary for Paris."
模型生成活动列表 → 每个活动再详细规划 → 迭代直到完整行程

写操作(Write Actions)

从"只读"到"读写"的跃迁

读操作:检索文档、查询数据库、搜索网页

写操作:发送邮件、下订单、更新数据库、调用 API

价值:可自动化完整工作流——研究潜在客户 → 找到联系方式 → 起草邮件 → 发送 → 读取回复 → 跟进 → 提取订单 → 更新数据库。

⚠️ 写操作的安全风险

  • Prompt Injection:攻击者操纵提示让 AI 执行有害操作
  • 数据泄露:AI 被诱骗泄露内部数据库隐私信息
  • 数据破坏:写权限被利用来篡改数据

防护:敏感操作需人工审批;不给 AI 直接执行 DELETE/UPDATE SQL 的权限。

🔭 可观测性(Observability)

三大支柱

支柱 内容 关键指标/实践
Metrics(指标) 系统状态 + 模型性能 吞吐量、内存、GPU利用率、准确率、毒性率、幻觉率
Logs(日志) 记录一切 配置、查询、输出、中间输出、组件起止时间、崩溃信息
Traces(追踪) 请求完整执行路径 用户查询→检索文档→最终提示→模型生成→每步耗时和成本

模型性能指标

指标类型 具体指标 用途
延迟 TTFT、TBT、TPS、TPOT、Total Latency 用户体验
长度 查询长度、上下文长度、响应长度 成本估算、异常检测
成本 查询数、输入/输出 token 量 预算控制
RAG 质量 Context Relevance、Context Precision 检索效果
失败率 超时率、空响应率、格式错误率 系统健康

💡 手动检查生产数据的价值

"Developers' perceptions of what constitutes good and bad outputs change as they interact with more data, allowing them to both rewrite their prompts to increase the chance of good responses and update their evaluation pipeline to catch bad responses."

—— Shankar et al., 2024

🔗 编排(Orchestration)

编排器的两个核心功能

1. 组件定义

告诉编排器系统使用哪些组件:

  • 模型(生成、路由、评分)
  • 数据库(检索数据源)
  • 动作(系统可执行的操作)

2. 链式编排(Chaining)

定义从接收查询到完成任务的步骤序列:

  1. 处理原始查询
  2. 检索相关数据
  3. 组合成模型期望格式的提示
  4. 模型生成响应
  5. 评估响应质量
  6. 质量好则返回用户,否则转人工

选择编排器的三个维度

维度 考量
集成与扩展性 是否支持已有/未来可能采用的组件?不支持时扩展难度如何?
复杂管道支持 是否支持分支、并行处理、错误处理?
易用性与性能 API 是否直观?文档是否完善?是否引入隐藏延迟?能否随流量扩展?

主流编排工具:LangChain、LlamaIndex、Flowise、Langflow、Haystack

⚠️ 先不用编排器

"While it's tempting to jump straight to an orchestration tool when starting a project, start building your application without one first. Any external tool brings added complexity. An orchestrator can abstract away critical details of how your system works, making it hard to understand and debug your system."

⚖️ 关键权衡(Tradeoffs)

权衡 选项A 选项B 建议
可靠性 vs 延迟 多层 Guardrails(安全但慢) 无 Guardrails(快但风险高) 大多数团队选择增加 Guardrails,风险成本 > 延迟成本
自托管 vs 第三方API 自托管(数据不外流,但需自建所有防护) 第三方API(有现成防护,但数据外送) 根据数据敏感度选择
流式 vs 非流式 流式(用户体验好,但难以做输出防护) 非流式(可完整评估后返回,但等待时间长) 用户体验优先时选流式,安全优先时选非流式
并行 vs 串行重试 并行调用2次取最好(延迟不变,成本2x) 失败后再重试(成本可能不增加,但延迟翻倍) 延迟敏感场景选并行

📝 总结

从简单到复杂的演进路径

阶段0: [用户查询] ──► [模型API] ──► [响应用户] │ ▼ 阶段1: + [上下文构建] = RAG / Text-to-SQL / Web搜索 / 查询改写 │ ▼ 阶段2: + [输入防护] = PII检测 + 越狱防护 + [输出防护] = 质量评估 + 失败管理 │ ▼ 阶段3: + [模型路由] = Intent分类 → 不同模型 + [模型网关] = 统一接入 + 访问控制 + 故障降级 │ ▼ 阶段4: + [Prompt缓存] + [精确缓存] + [语义缓存] │ ▼ 阶段5: + [复杂逻辑] = 循环、条件分支、Agentic工作流 + [写操作] = 邮件、下单、更新数据库 │ ▼ 全程: [可观测性] Logs + Traces + Metrics [编排器] LangChain / LlamaIndex

核心原则

  • 从简单开始:不要一上来就用编排器
  • 按需添加:每个组件都可以跳过,如果系统没有它也能工作
  • 评估贯穿始终:每个阶段都需要评估
  • 组件边界是流动的:网关可以做防护,缓存可以放在多个位置
  • 可观测性优先:从一开始就集成,而非事后补救