Skip to content

AI 工程化 = 把 LLM 当成另一种"分布式组件" ​

解决什么问题:LLM 不确定性 = 工程化的最大挑战—— 把 LLM 当成"高延迟 + 不确定 + 昂贵的外部 API",用现有分布式系统方法应对。

业务问题 ​

真实场景 ​

场景 1:LLM 在生产环境的噩梦

上线一个 LLM 功能:
  - 周末:API 限流(429),用户全部失败
  - 周一:响应时间从 2s 涨到 30s
  - 周二:成本是预估的 5 倍
  - 周三:用户报告"AI 答非所问"
  - 周四:幻觉问题(编造信息)
  - 周五:prompt 被注入(用户输入"忽略之前的指令...")
  
问题:
  - LLM = 黑盒
  - LLM = 慢(秒级)
  - LLM = 贵(token 计费)
  - LLM = 不确定(同输入不同输出)
  - LLM = 可被攻击(prompt injection)

失败模式 ​

失败模式后果
无超时控制LLM 卡死整个请求
无重试机制瞬时错误 = 用户失败
无缓存重复查询浪费钱
无降级LLM 挂了 = 全挂
无成本控制月账单失控
无 Prompt 版本管理无法回滚
不处理幻觉输出错误信息

控制论视角 ​

Ch 4 §4.6:"可验证性" + Ch 7 §7.5:"非线性系统"

LLM = 不确定的非线性系统
  - 输入(prompt)
  - 控制律(参数)
  - 输出(completion)
  - 反馈(用户评分)
  
挑战:
  - 不可重复(同 prompt 不同输出)
  - 不可预测(成本/延迟/质量)
  - 不可完全验证(内容质量难量化)
  
方法:
  - 缓存层(确定性提升)
  - 重试层(容错)
  - 监控层(可观测)
  - 验证层(可验证)

核心概念 ​

LLM 4 关键属性 ​

1. 高延迟
   - 100ms - 10s
   - 比数据库慢 1000 倍
   - 用户体验需特殊设计
   
2. 不确定性
   - 同输入可能不同输出
   - 需要缓存 + 重试 + 验证
   
3. 成本敏感
   - 按 token 计费
   - 长 prompt = 贵
   - 需要成本控制
   
4. 不可完全验证
   - 内容质量难量化
   - 幻觉问题
   - 需要用户反馈 + LLM-as-judge

LLM 应用 3 模式 ​

模式 1:直接调用
  - 应用 → LLM API → 应用
  - 适合:低 QPS、可接受延迟
  - 挑战:超时、成本
  
模式 2:批处理
  - 累积请求 → 批量调用 → 分布式
  - 适合:异步、内容生成
  - 优势:成本优化 + 质量稳定
  
模式 3:缓存 + 重试
  - 缓存层 → LLM API → 验证层
  - 适合:高频、相似请求
  - 优势:成本 + 性能

Prompt Engineering 6 原则 ​

1. 明确角色(Role)
   "你是一位资深的 Python 工程师..."
   
2. 明确任务(Task)
   "请审查以下代码的 bug..."
   
3. 提供上下文(Context)
   - 相关代码
   - 业务背景
   - 示例
   
4. 指定格式(Format)
   "请以 JSON 格式返回..."
   "步骤 1/2/3..."
   
5. 提供示例(Few-shot)
   "例:输入 X → 输出 Y"
   
6. 约束条件(Constraints)
   "不超过 200 字"
   "不能编造 API"

RAG(Retrieval-Augmented Generation) ​

流程:
  1. 用户问题
  2. 向量搜索(找相关文档)
  3. 拼接 prompt(问题 + 文档)
  4. LLM 生成(基于文档)
  5. 返回答案
  
优势:
  - 基于事实(不幻觉)
  - 可更新(文档变更即可)
  - 可追溯(引用的文档)

Function Calling(Tool Use) ​

LLM 不直接执行 = 调用外部函数
  1. LLM 决定调用哪个函数
  2. 应用执行函数
  3. LLM 拿到结果
  4. LLM 决定下一步
  
优势:
  - LLM 不接触敏感数据
  - LLM 不能直接修改系统
  - 可控 + 可审计

工程实践 ​

实战 1:LLM 客户端设计 ​

python
class LLMClient:
    def __init__(self, api_key, timeout=30, max_retries=3):
        self.client = openai.Client(api_key=api_key, timeout=timeout)
        self.max_retries = max_retries
        self.cache = {}
    
    def complete(self, prompt, **kwargs):
        # 1. 缓存检查
        cache_key = hash((prompt, str(kwargs)))
        if cache_key in self.cache:
            return self.cache[cache_key]
        
        # 2. 重试
        for attempt in range(self.max_retries):
            try:
                response = self.client.complete(prompt=prompt, **kwargs)
                self.cache[cache_key] = response
                return response
            except (RateLimitError, TimeoutError):
                if attempt == self.max_retries - 1:
                    raise
                time.sleep(2 ** attempt)  # 指数退避
    
    def complete_with_validation(self, prompt, validator):
        # 调用 + 验证
        for _ in range(3):
            response = self.complete(prompt)
            if validator(response):
                return response
            # 否则重写 prompt 重试

实战 2:成本控制 ​

策略:
  - Token 计数(输入 + 输出)
  - 成本预算(每用户/每请求)
  - 模型选择(按需用便宜模型)
  - Prompt 压缩(去除冗余)
  - 缓存(高频查询)
  - 批处理(异步任务)
  
监控:
  - 日成本 vs 预算
  - 单请求平均成本
  - 模型使用分布

实战 3:可观测性 ​

必须记录:
  - Prompt(输入)
  - Completion(输出)
  - Token 数(输入 + 输出)
  - 延迟
  - 成本
  - 用户反馈(点赞/点踩)
  - 错误率
  - 重试率
  
工具:
  - LangSmith(LangChain)
  - Helicone
  - 自建(结构化日志)

实战 4:幻觉处理 ​

策略 1:基于事实的 Prompt
  - 提供完整上下文
  - "如果不知道就说不知道"
  
策略 2:RAG(检索增强)
  - LLM 基于检索到的文档回答
  - 不基于"训练数据"
  
策略 3:Self-Consistency
  - 多次采样
  - 选择最一致的答案
  
策略 4:验证层
  - LLM 输出后用规则验证
  - 不通过则重试
  
策略 5:人工审核
  - 关键场景必须人工
  - 90% 自动化 + 10% 人工

实战 5:Prompt 版本管理 ​

原则:
  - Prompt 和代码一样需要版本管理
  - 每次变更 = 一次 commit
  - 可回滚
  - 可对比(A/B)
  
工具:
  - PromptLayer
  - 自建(Git + 数据库)
  
记录:
  - 版本号
  - 变更说明
  - 评估结果

反模式 vs 正模式 ​

反模式正模式
直接信任 LLM 输出验证 + 人工审核
不设超时严格超时
不计成本Token 监控 + 预算
Prompt 写在代码里Prompt 版本管理
无降级方案多层降级
不处理幻觉验证层 + RAG

性能指标 ​

指标衡量健康值
响应时间p99 延迟< 10s
成本/请求平均成本业务决定
成功率有效响应比例> 99%
用户满意度反馈评分> 4/5
幻觉率编造信息比例< 5%
缓存命中率缓存命中比例> 30%

边界判断 ​

何时用 LLM ​

  • 内容生成
  • 自然语言理解
  • 复杂决策辅助
  • 用户体验提升

何时不用 ​

  • 高频低延迟(数据库 + 缓存更好)
  • 强一致需求(数据库事务)
  • 成本敏感
  • 必须确定性输出

何时用 RAG ​

  • 基于事实的问题
  • 知识库查询
  • 文档摘要

何时用 Fine-tuning ​

  • 特定领域语言风格
  • 大批量类似任务
  • 通用模型效果差

与 L 层对位 ​

与四源对位 ​

主题cyberneticsIDDDEvent-DrivenSE@G
不确定性Ch 7 §7.5 非线性—Ch 6 确定性—
缓存层Ch 4 §4.6 反馈—Ch 7 状态物化Ch 18 构建
成本控制Ch 9 §9.4 最优——Ch 7 衡量
Prompt 管理—Ch 2 通用语言—Ch 8 风格
用户反馈Ch 4 §4.6 反馈环路—Ch 14 监控Ch 9 CR

关键洞察 ​

  1. LLM = 分布式系统组件——用现有方法应对不确定性。
  2. 缓存是性能 + 成本的关键——30%+ 命中率省一半钱。
  3. 验证层是必须的——不能信任 LLM 输出。
  4. Prompt 是新代码——版本管理 + 评审。
  5. 降级方案不可少——LLM 挂了系统不能挂。
  6. 与 cybernetics 同构:Ch 7 §7.5 非线性系统 = LLM;Ch 4 §4.6 反馈 = 用户评分。

阅读路径 ​

新手:
  1. LLM 4 关键属性(理解挑战)
  2. Prompt 6 原则(基础)
  
深入:
  3. RAG + Function Calling(架构)
  4. 成本控制 + 可观测性(运营)
  
实战:
  5. 客户端设计(重试/缓存/验证)
  6. 幻觉处理(验证层)

与用户哲学的对位 ​

用户的"AI 协作学习哲学"(与 AI 协作学习更高层方法论)与本主题直接呼应—— 本主题是把 LLM 作为组件集成到系统,用户哲学是把 LLM 作为协作伙伴用于学习。

二者不冲突:作为组件时强调工程化,作为伙伴时强调方法论。

相关链接 ​

从名家方法论与工程化思路中蒸馏出自己的工程体系。