仓库名叫 ai-engineering-from-scratch很直白就是从零开始搞AI工程。我最早建这个仓库的时候预想难度最大的应该是模型选型、算法调参这些真做起来才发现都不是。真正难的是完成一次认知切换——从“我写的代码每一步做什么我都知道”切换到“我设计的系统里有概率性组件我得为不确定性兜底”。这篇文章想做的就是把这条从零到能交付的路径完整展开。适合三类人看从传统前后端转过来做AI应用开发的工程师、算法工程师想补工程化短板的、以及正在搭AI研发流程的技术负责人。内容不堆数学推导更多是实际项目里的选型逻辑、踩坑记录和可以直接复用的方案。1. 先纠正一个误区AI工程不是“写提示词”1.1 提示词只是模型层的入口不是系统本身“AI工程师等于很会写提示词”这句话流传太广了但我见过不少团队真的信了以后把全部精力押在调Prompt上结果是线上效果时好时坏问谁都说不出为什么。真实项目里提示词只是整个系统的一小块输入接口。模型输出不稳定你要处理重试和校验上下文窗口有限你要设计检索和摘要策略要接入业务数据你得做切分、向量化、召回要控制成本你得统计Token消耗并设置缓存。换句话说提示词解决的是“怎么把话说清楚”AI工程解决的是“怎么让一个会随机发挥的组件稳定地待在系统里干活”。你大概率不会只跟一个模型打交道GPT系列、Claude系列、开源模型都要接不同模型的提示词风格还不一样。所以在我自己的工作流里提示词是当代码管理的版本化、可测试、参数化而不是随手复制一段话改几个字就用。1.2 AI原生应用的本质给不确定性上约束传统软件开发的假设是“输入确定、逻辑确定、输出确定”单元测试写起来很舒服。AI应用不是这样同样的提问模型今天和明天答的可能不同这就是概率性组件。你没法穷举所有输入也没法对生成结果做精确断言。我自己的理解AI工程的核心是围绕“感知—决策—行动—反馈”这条控制回路做工程落地。感知阶段系统拿到用户问题后要检索知识、拉取工具结果决策阶段模型基于已有信息推理行动阶段模型调用外部工具或生成内容反馈阶段系统评测本次输出质量并沉淀数据。这个循环在国外实践里被称作Loop Engineering本质上就是把大模型嵌进一个可重复、可观测、可干预的循环里。与之配套的还有一个词Harness Engineering直译是“马具工程”。意思是给模型套上约束装置让它在安全边界内发挥能力。评测集是约束结构化输出是约束护栏提示词是约束工具权限边界也是约束。没有这一层模型再聪明也只是一匹脱缰的马。我后面讲的所有章节回头看其实都是在这条回路上的不同位置加约束。2. 从零搭建AI工程的地基四层架构与选型不管做什么方向的AI应用我建议先把地基分成四层数据工程、模型抽象、Agent编排、评估反馈。这四层缺一层后面都会补得很痛苦。2.1 第一层数据工程决定系统智能上限很多人以为模型是智能上限实际在RAG这类应用里数据质量才是。模型再强检索出来是错的它也答不对。数据工程第一步是清洗把PDF页眉页脚、表格乱码、重复段落全部处理掉第二步是切分把长文档切成适合检索的单元。切分这块坑最多。切太短语义不完整模型缺少上下文切太长噪声太多召回精度下降。我在中英混合文档上常用的参数是chunk_size512个token左右overlap50个token。重叠窗口的意义是避免一句话恰好被拦腰截断让相邻chunk之间互相补足。另外元数据一定不能省每个chunk都要记录来源文档、所属章节、更新时间后面过滤和引用溯源全靠它。2.2 第二层模型抽象别让业务绑死单一模型接模型时我最忌讳的事是业务代码里到处直接调某一家API。模型更新换代太快价格和效果经常变化客户还可能要求私有化部署换开源模型。我的做法是定义一个统一接口把“发请求—重试—解析—校验”全部收敛到一个模块里上层业务只跟自己的接口打交道。这个模块内部要处理几件事超时设置不同模型响应速度差异很大重试策略限流和网络抖动时退避重试降级路由主模型挂了自动切备用模型还有语义缓存把用户问题的向量和回答存起来近似问题来了直接命中缓存省成本又降延迟。这套东西其实不复杂但能帮你躲掉后面绝大多数的被动重构。2.3 第三层Agent编排让模型学会用工具Agent不是新概念但真正把它做好考验的是编排工程的细节。第一是工具注册每个工具要有清晰的名称描述、入参Schema、权限边界。模型是拿描述来“理解”工具该不该用的描述含糊它就会乱调。第二是循环控制必须设置最大迭代轮数防止模型在一个失败的工具调用上反复打转。第三是结果校验工具返回的内容要先过一遍格式检查再决定要不要放进模型上下文。更复杂的项目会涉及多Agent协作我用过的模式有几种主管-执行式一个Agent拆任务分发给多个执行Agent评审制生成内容后由另一个Agent审查打分并行投票式多个Agent独立给出结果再交叉验证。每种都有适用场景后面第五节我会讲对应的坑。2.4 第四层评估反馈AI工程里的“测试金字塔”传统软件有单元测试、集成测试、端到端测试的测试金字塔AI工程也需要一套自己的评测体系。最底层是离线评测集一批固定的黄金问题和期望答案每次改动代码或Prompt都跑一遍看分数是涨是跌中间层是针对特定模块的评测比如单独测试检索器召回率最上层是在线监控用真实流量的代理指标评估系统健康度。没有这层评估地基你会陷入我见过最普遍的死循环感觉效果不对改了一段Prompt好像好了一点又改了另一段结果更差了回滚又舍不得最后整个系统变成没人敢碰的“玄学”。有了评测集每次改动都是一次有结论的实验。3. 一个可复现的从零路径用RAG搭一个知识问答系统理论讲完直接给一条我反复验证过的路径。拿最常见的RAG检索增强生成知识问答系统举例这套流程换个领域照样能用比如企业内部知识库、专利辅助检索、AI旅游导览、产品客服问答。3.1 数据准备切分与向量化第一步是准备知识库。假设你手头有几十份产品文档先把格式统一转成Markdown或纯文本去掉页眉页脚表格尽量转成描述性文本。然后按标题结构切分优先保持语义完整再按token数控制长度。我给上面的“512/50”参数一个解释在中文场景下512个token大约对应350到400个汉字作为检索单元既能表达完整观点又不至于包含太多干扰信息overlap设置为50是让相邻单元有上下文衔接避免关键句被拦腰截断。切分完成后做向量化。选择Embedding模型时要看两个指标检索效果和向量维度。开源方案里我常用BGE系列闭源方案可以用市场主流的text-embedding系列。维度高不代表更好维度越高存储和计算成本越高关键还是在你自己的数据集上跑召回评测。向量化之后存进向量数据库每条记录除了向量还要带上文档ID、章节路径、更新时间这些元数据后面做过滤和引用会非常省事。3.2 检索设计召回不能只靠向量只看向量检索是新手最容易犯的错。向量擅长捕捉语义相似但遇到专有名词、型号编码、精确术语就抓瞎。比如用户搜“A100显卡参数”如果知识库里写的是“NVIDIA A100 Tensor Core GPU”语义向量能匹配上但如果文档里全是缩写和编号向量召回效果就会明显下降。我现在的标准做法是混合检索BM25词法检索和向量检索并行跑各自召回一批候选合并去重之后再交给Reranker重排序。Reranker是轻量级的交叉编码器能对候选文档和用户问题做精细的相关性打分。这个阶段只用在小集合上一般从几百条中挑出最相关的4到6条成本可控效果提升却很明显。最后再按元数据过滤掉过期文档、非目标来源的内容。整个召回链路我用下面这张表概括阶段方法输入规模输出规模作用候选召回BM25 向量检索全量知识库50~100条快速缩小范围保证查全率精排Reranker交叉编码50~100条4~6条提升精度过滤无关内容业务过滤元数据条件过滤4~6条最终引用保证时效性和来源合规3.3 生成把检索结果交给模型的正确姿势检索有了下一步就是拼Prompt。很多人的第一反应是把所有检索结果全塞进去这是错的。模型上下文太长时会产生“lost in the middle”现象——中间段的信息很容易被忽略。我通常只保留精排后最相关的几条每条截断到合理长度还要在System Prompt里明确给出引用规则。一个我反复打磨的System Prompt结构包含四块角色定义、任务说明、引用规则、兜底策略。引用规则要写清楚“只能依据提供的参考内容回答引用时标注来源编号参考内容没有答案则明确回答不知道”。最后再加一段结果格式要求比如输出JSON格式包含answer字段和citations字段便于前端直接渲染成带引用的答案卡片。还有一种情况容易被忽略用户问题明显超出知识库范围时模型容易开始编。所以要强制兜底策略“不知道就说不知道”不是一句空话它需要写进Prompt也要靠评测集去验证。3.4 评测集让每次改动都可见路径最后一步是建评测集。我从真实用户日志里抽问题再补充一些构造的边界情况目标凑到30到80条黄金问题。覆盖几类可以直接命中知识库的问题、需要多段信息拼接的多跳问题、知识库里不存在的拒答问题、以及带时间有效性要求的时效问题。每个问题配一份参考答案以及该命中哪几条参考文档的标注。跑评测时我关注的指标有三个检索命中率也就是预标注的参考文档是否出现在最终引用里回答忠实度答案里的关键信息是否都能在引用片段中找到依据格式合规率输出JSON是否可解析。这套评测集每次代码改动、每次换模型、每次调Prompt都要跑一遍分数有变化就能定位原因。4. 守住工程质量AI测试开发与稳定性设计评测集是基础但工程化落地还需要一套完整的测试和稳定性体系。我所在的团队现在把AI测试开发当成单独的能力建设因为传统测试方法论在这里确实失效了。4.1 为AI系统写测试断言不再是“精确等于”传统单元测试断言返回值等于预期值AI系统做不到也不该这么做。我现在给AI系统写测试分三层。第一层是规则断言检查输出是否包含关键实体、是否满足JSON格式、是否包含引用标记这类硬约束最可靠。第二层是语义断言用向量相似度判断生成内容是否贴近参考答案需要设定阈值用的时候要小心阈值漂移差一点效果就变了。第三层是模型裁判用一个更强的模型给生成的答案打分、审查是否跑题。对抗样本在AI测试里尤其重要。知识问答系统要测诱导性问题、多轮对话陷阱、无意义输入、超长问题、隐含偏见问题这些是传统业务测试不会覆盖的。我建议把这类样本也沉淀进评测集在CI流水线里设置冒烟评测关卡代码合入前自动跑跑不过就不让合。4.2 可观测性没有Trace就无从谈调优AI系统的调用链路比传统接口长一个请求要经过检索、重排、生成、工具调用多个环节。哪一段慢了、哪一段烧了太多Token、哪一次重试是因为限流这些问题必须靠链路追踪回答。我在关键节点都打了日志用唯一的request_id串起整条链路记录每段耗时、Token消耗、命中的文档ID、模型的返回内容。成本监控是另一块不能省的事。大模型API按Token计费Prompt和Completion的价格通常不同要分别统计。我见过测试阶段每个请求几千Token上线后量大成本失控的情况。我的做法是给单次请求设置Token消耗警戒线超出就告警同时在网关层加语义缓存和降级策略。缓存命中率这个指标很直观有时候同样的用户问题反复问配上缓存能把系统成本降一半以上。4.3 多Agent协作与工具调用的可靠性Agent系统真正上线麻烦集中在工具调用环节。模型生成的工具调用参数不是百分百合规的必须先做Schema校验不合格就要求模型重新生成或者由代码纠错修补。工具执行要设计成幂等的——模型重试同一次工具调用不能产生重复扣款、重复发消息这类副作用。超时和重试策略也要做全局控制模型API超时重试一次就够了连续失败就快速降级到备用模型不能无限重试拖垮整个请求。多Agent协作里每个Agent的输出都要有一个“验收人”。我常用的做法是执行Agent产出结果后评审Agent按预设标准打分低于阈值就打回超过重试次数直接转人工处理。这个设计很笨但对稳定性的保障非常关键尤其在生成合同、代码、医疗建议这类高风险场景宁可慢一点也要把审计链路留全。5. 踩坑记录五个让我返工最狠的问题5.1 只调Prompt不建评测越调越乱这个坑我踩得最早。那会儿团队里有个项目线上回答质量时好时坏大家每天改Prompt改完感觉好一点第二天又被打回原形。整整两周没有一个人能说清楚到底是哪次改动带来正向收益。后来我把线上收集到的失败案例沉淀成二十条评测用例把历史Prompt版本跑了个分才发现大部分改动其实在小样本上表现都差不多真正起正向作用的是某一次引用规则的调整。从那以后我给自己立了条规矩没有评测集的Prompt改动一律不允许上线。5.2 盲目更换Embedding模型导致检索漂移有一阵子看到新出的Embedding模型效果评测不错我就直接换了当时只抽查了几个样例觉得还行。结果线上检索召回率明显下降用户开始反馈答非所问。复盘才发现新模型的向量分布根本不同原来设定的相似度阈值完全失效了有些本来该召回的内容被阈值挡在外面。那次返工让我意识到Embedding模型不是越新越好换模型必须全量重跑召回评测集同时重新标定相似度阈值不能只看一两个单点效果。5.3 Agent循环不设上限Token烧穿做Agent自动化任务时我第一次没设最大迭代轮数想着让它多试几次总能成功。结果模型在一个获取数据的工具上反复失败每次失败后又换一种说法再次调用一轮任务烧掉了预估成本十几倍的Token。那之后我在Agent编排层强制加了几个参数最大迭代轮数、单轮Token预算、总成本告警线。模型一旦达到上限就停止尝试转入人工处理或切换更简单的后备策略。这个设计放在今天看是常识但我确实是烧过钱才长记性的。5.4 上下文塞满模型越塞越笨RAG系统早期版本我把检索到的相关片段尽可能多地塞给模型最多一次给了二十多个片段。结果模型的回答质量反而下降经常引用错误片段还会漏掉最关键的信息。这就是我前面说的“lost in the middle”效应模型对长上下文的首尾注意力强、中间容易被忽略。解决办法是严格限制引用片段数量精排后只保留4到6条每条还要做截断让输入上下文保持在一个舒适的区间内。5.5 离线评测与线上效果脱节评测集做到后来离线分数越来越高线上用户却照样投诉。原因在于我的黄金问题是从早期日志里抽的越往后越偏理想化跟真实流量分布越来越不像。迎合这套题目的系统自然会对真实复杂问题无感。后来改成定期从线上日志中按比例抽样自动生成候选评测问题加上人工标注和审核保证黄金集持续贴近真实场景。同时增加动态review机制每周轮流抽检线上回答质量把新发现的badcase补进评测集。如果只让我给一条建议那就是从第一天开始把评测这件事当成系统的正式组件来对待。AI工程从零开始的时候一切都很新鲜模型能力会给你很多惊喜但工程的复杂度一定会追上来。早一点建评测集、早一点做可观测性、早一点给Agent上缰绳后面返工的代价就越小。这个仓库里我还会持续加入更多模块的实测记录包括多模态场景、可编程工作流、Agent自进化试验每一篇都是这套框架在不同场景下的具体补全。