☰
从零搭建AI工程能力:推理引擎、上下文管理与缓存评测实战
2026/10/1 11:46:40 网站建设 项目流程

1. 从零搭建AI工程能力:为什么我劝你别一上来就调包

这两年AI应用开发的门槛肉眼可见地在降低,随便拉个框架、调个API就能跑出一个能对话的Demo。但我带过的新人里,十个有八个在遇到"模型输出不稳定""推理延迟飙高""上下文一长就崩"这类问题时,完全不知道从哪下手。根子就在于——大家跳过了"从零理解AI工程"这一步,直接站在了工具链的最顶层。

ai-engineering-from-scratch这个方向,说白了就是把AI应用从"能跑"到"跑得稳、跑得省、跑得可维护"这条路上,那些被框架封装掉的底层环节,自己动手重新走一遍。它适合三类人:一是刚转行做AI应用、只会调API的开发者;二是想搞清楚推理服务内部到底发生了什么的后端工程师;三是需要给团队搭建AI基础设施、但不想被某个框架绑死的技术负责人。

我自己走过这条路,也踩过不少坑。这篇文章不讲虚的,就把我从零搭一套AI工程能力时,真正需要理解的几个核心模块——推理引擎、上下文管理、缓存策略、评测体系——拆开揉碎讲一遍。每个环节我都会说清楚"为什么这么设计""参数怎么算""实际会遇到什么问题",你照着做能少走至少半年的弯路。

2. 整体设计思路:为什么"从零"比"调包"更值钱

2.1 先搞清楚AI工程到底在工程什么

很多人把AI工程等同于"写Prompt"或者"调模型API",这是最大的误解。一个能上生产的AI应用,本质上是一个带概率输出的分布式系统,它和传统后端系统最大的区别在于:输入输出都是不确定的,而且计算成本极高。

这就带来三个传统工程里不存在的核心问题:

  • 不确定性管理:同样的输入,模型可能给出不同输出。你得设计重试、校验、降级策略。
  • 成本控制:每次推理都是真金白银。Token消耗、GPU占用、并发排队,每一项都要精打细算。
  • 质量评测:传统系统测的是"对不对",AI系统测的是"好不好",而"好"是个连续谱,需要一套评测体系来量化。

ai-engineering-from-scratch的核心思路,就是把这三个问题当成一等公民来对待,而不是等出了问题再打补丁。我见过太多项目,前期Demo跑得飞快,一上量就各种崩,就是因为这三个问题从来没被认真设计过。

2.2 分层架构:把"模型"当成一个可替换的零件

从零搭建时,我建议采用清晰的分层架构,而不是把所有逻辑塞在一个文件里。我的分层是这样的:

层级职责关键设计点
接入层请求路由、鉴权、限流与模型无关,可独立扩展
编排层Prompt组装、上下文管理、工具调用业务逻辑核心,最需要测试
推理层模型调用、批处理、重试可替换,支持多模型路由
缓存层语义缓存、结果缓存成本控制的关键
评测层离线评测、在线监控质量保障的闭环

这么分层的最大好处是:模型是可以随时换的。今天用A模型,明天B模型降价了想换,你只需要改推理层的适配器,编排层和评测层完全不用动。我见过把模型调用散落在各处的项目,换个模型要改几十个文件,那才叫痛苦。

2.3 技术选型:别被"最新最强"绑架

选型这块我的原则很朴素:优先选你能读懂源码的、社区活跃的、能本地跑起来的。具体来说:

  • 推理引擎:如果只是调云端API,那选型意义不大;但如果要自部署,我建议从支持连续批处理(continuous batching)的引擎入手,这是吞吐量的分水岭。
  • 向量检索:小规模(百万级以下)用内存索引就够,别一上来就上分布式向量库,运维成本远大于收益。
  • 编排框架:能用代码写清楚的就别用框架,框架的抽象泄漏在调试时是灾难。我个人的做法是先用纯代码实现,等模式稳定了再考虑抽象。

提示:选型时一定要问自己一个问题——"如果这个组件明天停止维护,我迁移的成本有多大?" 答案超过一周的,就要慎重。

3. 核心模块拆解:推理、上下文、缓存、评测

3.1 推理引擎:吞吐量和延迟的平衡术

推理层是整个系统的心脏。从零理解它,你需要搞明白两个核心指标:首Token延迟(TTFT)和每Token输出时间(TPOT)。用户感知到的"快",主要取决于TTFT;而整体吞吐量,取决于批处理效率。

连续批处理(continuous batching)是绕不开的概念。传统批处理要等一个批次里所有请求都生成完才能处理下一批,而连续批处理允许新请求随时插入、完成的请求随时退出。实测下来,在并发场景下吞吐量能提升3到8倍,具体取决于请求长度的分布。

如果你要自部署,关键参数是max_batch_size和max_num_seqs。这两个值不是越大越好:

  • max_batch_size过大,单次前向计算显存占用飙升,容易OOM;
  • 过小则GPU利用率上不去,成本浪费。

我的经验算法是:先用显存容量反推最大批大小,再根据P99延迟要求往下调。比如一张24G显存的卡,跑7B模型(FP16约14G权重),留给KV Cache的显存大概8G,按每个序列平均2K上下文估算,能同时容纳的序列数大概在30到50之间。这个数就是你的max_num_seqs上限,实际设置时留20%余量。

3.2 上下文管理:长对话不崩的关键

上下文一长就崩,是新手最常遇到的问题。根子在于KV Cache随上下文线性增长,而显存是有限的。从零做上下文管理,核心是三件事:

第一,滑动窗口加摘要。不要傻乎乎地把所有历史都塞进去。我的做法是保留最近N轮完整对话,更早的用模型压缩成一段摘要。N的取值看任务,客服场景5到8轮足够,代码助手可能要保留完整文件上下文。

第二,Token预算分配。给系统提示、历史对话、检索内容、用户输入各分配一个预算上限,超了就按优先级裁剪。这个预算要动态调整,比如检索内容相关度高时多给检索、少给历史。

第三,位置编码的处理。很多模型对超出训练长度的上下文外推能力很差,硬塞长文本会导致"中间遗忘"。如果必须处理超长文本,要么用支持长上下文的模型,要么做分段处理再聚合。

注意:上下文不是越长越好。实测中,把无关历史塞进去反而会降低输出质量,因为模型注意力被稀释了。宁可精准检索,不要暴力堆砌。

3.3 缓存策略:省钱的命脉

AI应用的成本大头在推理,而推理成本的大头在重复计算。缓存做得好,成本能降一半以上。缓存分三层:

精确缓存:输入完全一致时直接返回。实现简单,用哈希做key就行。命中率在客服、FAQ类场景能到30%以上。

语义缓存:输入语义相似时复用结果。需要向量检索加相似度阈值。这里有个坑——阈值设太高命中率低,设太低会返回不相关答案。我的经验是先用0.92起步,根据badcase调整。

前缀缓存:相同系统提示和前缀的请求,复用KV Cache。这个在自部署场景收益巨大,尤其是系统提示很长的时候。主流推理引擎都支持,开启后TTFT能降50%以上。

缓存类型实现复杂度典型命中率主要收益
精确缓存低20%-40%成本、延迟
语义缓存中15%-35%成本、延迟
前缀缓存低(引擎支持)60%+首Token延迟

3.4 评测体系:没有评测就没有迭代

这是最容易被忽略、但最重要的一环。没有评测,你改一个Prompt、换一个模型,根本不知道是变好了还是变坏了。从零搭评测,我建议分两步走:

离线评测:准备一个覆盖核心场景的测试集,每个case标注期望输出或评分标准。每次改动跑一遍,看指标变化。指标不要只看准确率,还要看格式合规率、拒答率、平均长度等。

在线监控:生产环境采样,人工抽检加自动指标。重点关注用户反馈(点赞点踩)、重试率、异常输出率。这些信号比离线指标更真实。

评测集的建设是个持续过程。我的做法是:每次发现一个badcase,就把它加进评测集。半年下来,评测集就成了项目的护城河。

4. 实操落地:从零到一搭建的完整流程

4.1 环境准备与最小可运行版本

第一步不是搭架构,而是跑通一个最小闭环。我的建议是先写一个纯Python脚本,实现"读输入→组装Prompt→调模型→输出结果"这条链路,不引入任何框架。

# 最小推理闭环示例 import time def generate(prompt, model_client, max_retries=3): for attempt in range(max_retries): try: start = time.time() response = model_client.chat(prompt) latency = time.time() - start # 记录关键指标 log_metrics(ttft=response.ttft, latency=latency, tokens=response.usage) return response.text except RateLimitError: time.sleep(2 ** attempt) # 指数退避 except Exception as e: if attempt == max_retries - 1: raise return None

这个脚本虽然简单,但包含了三个关键设计:重试机制、指标记录、异常分类处理。很多人的Demo里这三样都没有,一上生产就抓瞎。

环境准备上,我建议用虚拟环境隔离依赖,把模型客户端、向量库、评测工具分开管理。配置文件用YAML或环境变量,别硬编码密钥和模型名。

4.2 编排层的实现要点

编排层是业务逻辑的核心,也是最需要测试的地方。我的实现原则是:把Prompt组装做成纯函数,输入是结构化的上下文对象,输出是最终的Prompt字符串。这样测试起来非常方便,给定输入就能断言输出。

上下文对象我一般设计成这样的结构:

class Context: system_prompt: str history: list[Message] # 历史对话 retrieved: list[Document] # 检索到的文档 user_input: str budget: TokenBudget # 各部分的token预算

组装时按预算裁剪,优先级是:系统提示 > 用户输入 > 检索内容 > 历史对话。裁剪历史时从最旧的开始丢,但保留第一轮(通常包含关键设定)。

工具调用(function calling)也在这层处理。我的经验是:工具描述要写得像给新人看的文档,参数说明清楚、给例子、说明什么时候用。工具数量控制在10个以内,太多模型会选错。

4.3 缓存层的落地细节

缓存层落地时,key的设计是关键。精确缓存的key不能只用用户输入,还要包含模型名、温度参数、系统提示版本。否则改了系统提示,缓存还返回旧结果,那就出大事了。

语义缓存的实现,我建议用两阶段:先用向量检索找候选,再用一个轻量模型或规则判断是否真的等价。纯靠向量相似度会有误判,尤其是"帮我查A"和"帮我查B"这种,向量可能很近但答案完全不同。

前缀缓存的开启,取决于推理引擎。自部署时记得把系统提示放在最前面且保持稳定,这样前缀命中率才高。如果系统提示里带了时间戳之类的动态内容,前缀缓存就废了。

提示:缓存一定要有失效机制。模型更新、知识库更新时,要能批量清理相关缓存。我一般给缓存加个版本号,版本变了自动失效。

4.4 评测流程的自动化

评测要自动化才有意义。我的做法是写一个评测脚本,输入是评测集文件,输出是各项指标的报表。每次代码合并前跑一遍,指标下降就阻断合并。

评测集格式我一般用JSONL,每行一个case:

{"id": "case_001", "input": "...", "expected": "...", "tags": ["faq", "chinese"]}

评分方式分两种:有标准答案的用精确匹配或相似度;没有标准答案的用模型打分(LLM-as-judge),但要固定打分模型和Prompt,保证可比性。

评测指标我重点关注这几个:准确率、格式合规率、平均延迟、平均Token消耗。前两个看质量,后两个看成本。四个指标一起看,才能判断一次改动是"提质增效"还是"拆东墙补西墙"。

5. 常见问题与排查技巧实录

5.1 输出不稳定怎么办

这是最高频的问题。排查思路按顺序来:

  1. 先看温度参数。温度大于0.7时输出波动大是正常的,业务需要稳定就调到0.1到0.3。
  2. 再看Prompt是否有歧义。同一个问题换个说法答案就变,说明Prompt约束不够。加上明确的输出格式要求和边界条件。
  3. 最后看模型本身。有些模型在特定任务上就是不稳定,换模型或加few-shot示例。

我的经验是,80%的"不稳定"其实是Prompt问题,不是模型问题。与其频繁换模型,不如把Prompt打磨到位。

5.2 延迟突然飙高怎么排查

延迟问题要分段定位。我在代码里会给每个阶段打点:检索耗时、Prompt组装耗时、模型推理耗时、后处理耗时。哪段涨了一眼就能看出来。

常见原因和对策:

现象可能原因对策
TTFT高但TPOT正常排队严重或前缀缓存失效扩容、检查前缀稳定性
TPOT高输出太长或批处理效率低限制max_tokens、调批参数
检索耗时高索引未加载或数据量涨了检查索引、加缓存
整体都高下游依赖慢加超时、降级策略

5.3 成本失控怎么止血

成本失控通常有三个来源:重复推理、超长上下文、无效重试。止血顺序:

先上精确缓存,这是最快见效的。再检查上下文预算,把不必要的历史和检索内容砍掉。最后看重试逻辑,是不是失败后无脑重试导致成本翻倍。重试一定要有次数上限和退避策略。

我踩过的一个坑是:流式输出中途失败后重试,导致用户看到重复内容。后来改成流式失败不重试,直接返回错误让用户重发,反而体验更好。

5.4 评测指标好看但线上效果差

这是典型的评测集和真实分布不一致。评测集是你自己造的,真实用户的问题千奇百怪。解决办法是持续从线上采样,把真实case补充进评测集。另外,评测时要注意数据泄漏——如果评测集里的问题和训练数据或Prompt示例高度相似,指标会虚高。

我的做法是维护两个评测集:一个是"核心集",覆盖必须做对的场景,指标要求严格;一个是"探索集",收集线上真实case,指标作为参考。两个集一起看,才能既保底线又看趋势。

6. 我在这条路上踩过的几个坑

第一个坑是过早抽象。一开始就想搞一套通用框架,结果业务还没跑通,框架先把自己绕进去了。后来我改成"先写三遍重复代码,再抽象",反而清晰很多。

第二个坑是忽视可观测性。早期只记了个总延迟,出问题完全不知道哪慢。后来给每个环节都加了打点,排查效率提升十倍不止。AI系统的可观测性比传统系统更重要,因为不确定性更高。

第三个坑是评测集造假。为了让指标好看,专挑简单case放进评测集,结果线上被真实用户教做人。评测集必须诚实,宁可难看,不要虚假繁荣。

最后一个体会是:AI工程的核心竞争力不在模型,而在工程。模型大家都能用,但谁能把不确定性管好、把成本控住、把质量评准,谁就能做出真正能上生产的东西。这条路没有捷径,但每一步都算数。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询