AI工程从零开始:从RAG到Agent的完整实践指南
发布时间:2026/10/4 12:51:45 作者:尧图编辑部 阅读量:1,286

去年年初我把自己的学习计划命名为 ai-engineering-from-scratch那时候我对大模型的理解还停留在能调通API就算会用。后来真正从零开始搭出第一个可交付的AI应用我才意识到这个短语和大多数教程里教的内容根本不是一回事。它不是让你从Transformer论文推公式开始而是让你在一个充满不确定性的系统里学会用工程手段把模型能力变成稳定可靠的产品能力。如果你现在正准备进入AI工程这个方向或者已经跑过几个demo但总觉得哪里不对这篇文章应该能帮你省下不少时间。我会把我实际走过的路径、踩过的坑以及现在每天都在用的方法按真实顺序讲一遍。1. 为什么我把这个专题命名为 ai-engineering-from-scratch1.1 大多数人学AI的常见误区我从零开始学这件事时第一个误区就是AI工程 学会调用大模型。模型API给一个输入返回一个输出好像没什么工程好做。可等我真正要做一个能上线的功能时问题全冒出来了用户问的是同一个问题模型今天回答和明天回答不一样资料库里明明有答案检索没召回上下文塞太多模型读到一半就开始乱编prompt一改老场景又挂了。这些都不是模型单独能解决的需要有人在模型外面搭一套系统把数据、上下文、工具、评估、监控全部串起来。这套系统才是AI工程真正要工程的东西。第二个误区是反过来的觉得一定要先把机器学习、深度学习理论啃完才能开始。我见过很多人买了三本数学书学了一个月导数API一行没写最后彻底放弃。实际上如果你不是要训练自己的基座模型大多数日常AI应用开发并不需要手推反向传播。你需要的是足够用、能理解问题的数学直觉而不是研究级别的推导能力。1.2 AI工程到底在工程什么我给自己的定义是AI工程是把一个模型变成一个产品功能所需的全部工程活动。它至少包含五层缺一层后面都会出事模型层选型、API调用、微调、本地部署。这是大多数教程讲的部分。编排层提示词、检索、工具调用、Agent循环。这是把模型能力组合成任务能力的地方。数据层文档处理、知识库构建、评测集维护、数据闭环。评估层测试用例、自动评测、回归分析、线上监控。产品层成本、延迟、幻觉处理、用户交互兜底。我后来看到新出现的harness engineering这个词觉得它特别贴切。Harness直译是马具放在AI工程里就是把模型这匹马和实际业务这辆车连接起来的整套装置。光有马不够缰绳、鞍具、路径、刹车全都要有人设计。提示词只是其中一根缰绳Agent循环是让马按照路线跑评测集则是判断跑偏没有的仪表盘。所以这个专题的from-scratch我理解的真正含义是不依赖现成的Demo模板从需求出发一层一层把模型周边的装置搭起来。2. 从零开始的地基我没啃完数学书但守住了三条底线2.1 三块必要不充分的知识我复盘后总结真正需要的地基知识其实就三块每一块都不深但都不能缺。第一块是Python工程能力。不是会写for循环就行而是会写函数、类、类型注解会用虚拟环境管理依赖会写简单的单元测试会读别人的项目代码。AI工程大量的工作是在接各种SDK、处理数据、写prompt调用逻辑Python不熟后面每一步都慢。第二块是大模型API的基本机制。你知道token怎么数、上下文窗口怎么算、temperature/ top_p这些参数到底影响什么、为什么同一个prompt每次结果不同、为什么套话会降低输出质量。这些知识不来自论文来自反复读文档和使用时留心观察。我甚至建议你把API返回的usage字段每次打出来时间久了你对成本会非常敏感。第三块是向量和概率的直觉。你不一定需要手算矩阵乘法但需要理解embedding相似度的含义理解模型输出是概率采样这件事意味着结果天然有随机性。我看到很多人一开始就把模型输出当成数据库查询结果这是后面大量问题的心智根源。2.2 开发环境和工具链的第一次打磨从零开始环境别搞复杂但几个原则要一开始就建立起来所有代码和prompt都用Git管理。Prompt不是聊天记录是代码。API密钥走环境变量或密钥管理不要写死在代码里。先用Jupyter做实验但项目一上规模就把实验代码整理成包别让所有东西堆在一个notebook里。本地向量库选一个轻量的起步比如Chroma或sqlite-vss。数据量没到百万级不需要一上来就上重型的分布式检索系统。我第一次搭环境时犯的错误是装了一堆看似高级的工具向量数据库、编排框架、监控平台全装完一周过去了连一个完整的问题都没回答成功。后来我把所有框架全卸了用Python 一个向量库 一个模型API两天就把最小闭环跑通了。工具是给问题服务的不是用来壮胆的。2.3 关于会不会过时的焦虑做AI工程很容易焦虑因为工具一个月一变上个月学的编排框架这个月就有新替代品。我的感受是把火力和时间投在不变的层上。不变的是数据怎么处理、上下文怎么组织、评测怎么设计、Agent循环怎么控制、成本和延迟怎么平衡。这些方法论比任何具体框架都耐用。框架只是这些方法论的一种包装换一个包装核心还在。3. 第一个端到端项目用RAG做一个读过你文档的客服机器人3.1 为什么第一个项目选RAG我见过很多人第一个项目是做一个聊天机器人但这个选择不够好。纯聊天没有任何数据依赖没有检索没有评测跑通一个demo和一个网页聊天框差不多学不到工程细节。RAG检索增强生成是更好的起点。它强迫你处理真实数据文档怎么拆分、怎么存储、怎么检索、怎么把检索结果填进prompt、怎么防止模型编造。这些能力在后面的Agent项目里全都要用而且RAG本身也是当前大量落地应用的核心架构。为什么不选微调第一是成本和周期问题第二是业务知识更新频繁。RAG像考试时允许开卷让模型边查资料边回答问题微调像让模型把所有知识背下来背完还可能记错。第一个项目用RAG能让你更快看到数据质量影响答案质量这条最关键的工程链路。3.2 最小闭环分几步我当时用20篇产品文档做试点目标很简单能让机器人根据这些文档回答问题并且每个答案注明出处。核心步骤只有六步收集文档清洗格式去掉页眉页脚和重复内容。按语义切块每块控制在300到800个token之间块之间留一点重叠。调用embedding API把每块转成向量存入向量库。用户提问时把问题也转成向量检索最相关的top3到top5块。把检索到的块拼进prompt要求模型只能依据这些块回答。输出答案时一并返回引用来源。核心代码并不复杂但每一步都有讲究。比如切块按固定字符切会切断语义我后来改成按标题层级和段落边界切命中率立刻高了一截。比如检索只取top1容易漏top10又可能引入噪声最后我定在top3并加一个相似度阈值低于阈值的就不给模型。代码大概长这样from openai import OpenAI client OpenAI() def answer_with_context(question: str, hits: list[dict]) - str: context \n\n.join( f[{i1}] {hit[text]} for i, hit in enumerate(hits) ) resp client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: ( 你是一个客服助手。只能依据给定资料回答问题。 如果资料里没有答案必须直接说‘资料中未找到相关信息’禁止编造。 )}, {role: user, content: f资料\n{context}\n\n问题{question}} ] ) return resp.choices[0].message.content这个阶段先别急着做UI别急着换更好的模型。先手动收集10个真实问题逐个看回答质量把失败原因分两类一类是检索没找到相关内容另一类是找到但模型没用对。这两类问题的解法完全不同分不清就没法改进。3.3 第一次跑通后我做了什么第一次跑通时我挺兴奋但冷静下来后只做了一件事整理坏案例。我把10个问题里答错的3个拎出来逐个看是召回错了还是prompt约束不够。后来我把这些坏案例慢慢积累成一个问题-预期行为清单这就是评测集的雏形。这个习惯救了我无数次因为后面每次调整prompt或切块方式我都会先跑这几十个用例避免按了葫芦起了瓢。第一个RAG项目我做了两周代码量不大但让我建立了一个非常重要的工作习惯任何改动先跑一遍历史用例再说感觉好不好。这个习惯直接沿用到了现在做Agent项目它比任何高端工具都管用。4. 提示词工程和Agent编排从聊天框到AI能力单元4.1 提示词工程不是写漂亮话很多人以为提示词工程是把需求描述得更文学化其实不是。提示词是程序的一部分和代码一样需要结构、约束和版本管理。一个能上线的system prompt我通常会包含这几部分角色和任务边界、输入数据说明、处理流程、输出格式、禁区列表、以及一个或两个few-shot示例。少一个后面都可能出现奇怪的失败。举个例子同样是让模型写客服回复普通prompt可能是请专业地回复用户。我实际用的更接近这样system_prompt 你是一个客服质检助手。你的任务是根据用户问题生成一份回复草案。 处理流程 1. 先检查给定资料中是否有可支持答案的内容。 2. 有则基于资料生成回复并列出引用编号。 3. 没有则回复必须包含「资料中未找到相关信息」。 4. 禁止在回复中出现资料之外的具体数据。 输出格式严格JSON {reply: 回复内容, citations: [编号]} 这一版prompt看起来不漂亮但稳定。因为每句话都在限制模型的自由发挥空间。调试prompt时我建议只改一个变量改完立刻跑评测集别同时改好几个地方否则出了问题你根本不知道是哪句话引起的。4.2 让Agent学会调用工具的真相Agent类和纯问答的本质区别是模型不再只输出文字而是在一个循环里决定调用哪些工具、根据工具结果继续推理。很多人一开始让Agent自由发挥结果模型一直在瞎调用、循环不终止、token烧得飞快。这是典型的编排没做好。我学到的核心方法是把Agent理解成受控的循环而不是有意识的助手。它的每一步都来自明确约束给每个工具写清楚的名称和参数说明别让模型猜。限制工具调用的最大次数防死循环。每次工具返回后把结果压缩成摘要再喂回模型避免上下文无限膨胀。关键决策点设置人工确认例如删除、转账这类操作不能只靠模型判断。所谓harness engineering做的就是这个事。模型还是那个模型但外面套了工具schema、上下文策略、护栏规则整套装置决定了Agent在真实场景中是靠谱还是失控。4.3 多AI协作与Loop从单次生成到循环任务我最近一年花时间最多的方向是把多个AI任务组合成一个工作流业内有人叫loop engineering我理解它就是设计循环迭代的工程方法。比如写一个周报系统不是让模型一次生成完。先让规划Agent拆出本周重点工作再让执行Agent逐项写进展然后让检查Agent找与输入日志不一致的地方最后根据检查结果让Agent重写一遍。这就是一个plan-do-check-refine的循环。多AI协作也不是把一堆Agent丢在一起开大会。我实践下来每个Agent必须有一份独立的prompt、独立的输入输出结构、明确的验收标准。否则多个Agent互相改来改去最后输出质量反而比单个Agent更差。协作的关键不是数量是接口清晰。我现在已经不太关注某个模型本身多强更关注这个模型被放在一个什么样的循环和装置里。强的模型配一个混乱的循环结果可能远不如普通模型配一个严谨的循环。5. AI应用的测试和评估把看起来行变成可回归5.1 为什么AI测试与传统测试不一样传统测试是确定性的同一个输入预期输出是固定的。AI测试不一样输入一样模型输出可能每次都不一样。所以你不能写答案必须等于某句话而要写答案必须包含某个事实答案必须引用正确的来源答案不能包含某个禁区词。我把测试分成三层单元测试测数据切块函数、检索函数、prompt模板是否按预期填充。集成测试测完整链路输入一个问题是否能返回带引用的答案。质量评估用评测集跑批量数据统计准确率、召回率、格式合规率。前两层是传统工程手段第三层才是AI工程特有的。少了第三层你只能靠肉眼抽查一改prompt心里就发虚。5.2 评测集怎么建、怎么长评测集是AI工程里最重要也最容易被忽视的资产。我一开始只有20条现在每个线上项目至少有几百条。来源不是凭空写的而是从真实用户日志里挑出来的。真实场景里的问题往往是最复杂的人工拍脑袋编的问题是测不出系统弱点的。评测维度要根据业务定我常用的是下面几种维度说明通过标准示例事实准确性是否与资料一致含3个工作日完整度关键信息是否齐全含退款条件和到账时间引用正确性引用的来源是否支持答案来源编号在检索结果内拒答能力资料不足时是否不知道装知道含未找到格式合规是否按约定JSON/结构化输出JSON可解析且字段完整评测执行也不能只靠一个模型自问自答。我用的组合是可规则判断的用规则比如关键字、JSON解析、引用来源比对主观的质量判断用另一个强模型做裁判再加少量人工抽检。用规则的目的是可复现用模型裁判的目的是高效覆盖。5.3 线上监控不是可选项模型一旦上线离线评测和线上真实效果经常出现差异。我遇到过评测集表现很好上线后被用户连续投诉的情况。原因是线上问题分布和评测集不一样。所以线上必须记录用户问题、最终回答、引用来源、模型参数、token消耗、耗时、用户反馈。这些日志是下一轮评测集扩充的原料也是定位问题的第一现场。没有日志AI应用就像一台没有仪表盘的飞机出事了只能瞎猜。还有一个习惯任何模型版本升级前先拿旧版本和候选版本在同一个评测集上对比跑一轮用表格列出每个维度的得分差异。这比看模型官方发布的benchmark有用得多因为你关心的是你的业务场景不是通用能力。6. 我踩过的五个坑和对应的处理方式6.1 一改Prompt全回归没人知道变好变坏我早期改prompt完全靠感觉今天觉得这样说更顺就改了结果第二天用户反馈变差。后来才意识到我根本没有一个客观的基线。处理方式每次改动前先跑一次评测集记录基线得分改完再跑一次看每个维度差异。哪怕这次改动只影响一个用例也要确认其他用例没有掉分。效果不能量化就不要上生产。6.2 上下文塞得越满效果反而越差有一段时间我为了让模型回答准确把检索到的所有内容全部放进上下文甚至到了上万token。结果反而是模型会忽略中间的细节只抓住开头和结尾的内容。这是模型注意力机制的天然行为不是偶然。处理方式控制输入数量宁可少给只给必要的同时做rerank把最相关的排到最前面。上下文不是仓库是工作台工作台上只放当前任务要用的材料。6.3 评测集泄漏我犯过一个很隐蔽的错误用优化prompt时反复调整的那些问题做评测结果评测集越来越配合我的prompt看起来准确率很高换一批新问题就大幅下降。这就是评测集泄漏系统过拟合到了测试题上。处理方式把评测集分成开发集和留出集。开发集可以反复用来调试留出集只在关键节点跑一次。新增的线上问题持续补充进评测集但每次补充后重新做一次数据切分避免调试参考过深。6.4 把模型能力当成应用能力很多时候一个功能demo很惊艳是因为模型本身强不是你的工程做得好。比如你给模型很多背景信息它能猜得八九不离十但真正上生产没有清晰的数据管线和兜底逻辑照样一团糟。处理方式每次评估产品能力都区分换一个普通模型还能这么稳定吗如果不行说明你该把逻辑放到系统里而不是依赖模型临场发挥。检索侧要优化prompt侧要约束输出侧要校验哪一层都不该偷懒。6.5 成本与性能的账没提前算Agent项目最容易让成本失控。一个循环里多次调用模型一次用户请求可能消耗几千甚至上万token成本是普通问答的几倍。我第一次做Agent调试时一天烧掉的API费用让我直接愣住了。处理方式在代码里埋点记录每次请求的token数和耗时简单任务用便宜小模型复杂任务才用好模型对结果做缓存重复问题不要重复计算。AI应用的成本不是一个技术指标是一个需要一开始就设计入口的架构约束。7. 从这里继续往前走AI Native研发范式的实践感触7.1 AI Native研发到底在说什么当我真正把上面这套方法跑顺之后再回头看AI Native研发这个词才有了体感。它不只是用AI写代码而是把整个研发过程里的知识、经验、过程都转化成AI可以参与的结构化资产。传统研发经验存在于人脑和文档里AI Native研发经验固化在提示词、评估集、Agent流程里。我改一个检索逻辑不再只靠代码测试还要看评估集的变化我写一个功能不再只自己Review还会让另一个模型从测试和文档角度Review。人定方向、定约束AI负责大量重复和可能的盲区扫描。这种范式下最核心的能力不是写提示词而是设计评估标准和流程闭环。评估标准不清AI做得越多偏得越远。7.2 我现在的工作流人定基线AI跑量现在我最常用的工作流是这样的我先自己写一版核心prompt和代码骨架跑通一个最小例子确认方向没问题然后把测试生成、用例补充、文档撰写、代码Review这些环节交给不同的AI角色去做。每个AI角色在我的流程里是有边界的协作者不是全能助手。比如接一个新的数据源时我会让一个AI角色负责读文档、列字段、生成数据清洗建议另一个AI角色负责审查清洗逻辑里有没有边界遗漏我自己只做最终决策和跑评测集验证。多个AI协作要真的起作用前提是每个人都清楚自己的输入和输出格式这不正是我之前在Agent编排里练出来的吗在实际项目里我也常把这类开发Agent集成到IDE里让它直接处理代码改动。像CodeBuddy这类工具本质就是一个被harness住的工程Agent你给它任务边界和上下文它去读代码、改代码、补测试你负责约束和审核。用它的过程本身就是一次harness engineering实践。7.3 给后来者的三条建议如果只能留三条我会留这三句。第一第一个项目不要大但一定要端到端。从数据清洗到检索到生成到评测一个环节都不能跳。跑通一个短闭环比刷十遍教程都管用。第二把评测集当银行账户越早开始越早吃利息。哪怕只有20条用例也比没有强。后面每次改动都知道有没有变差这种安全感只有做过的人能体会。第三接受随机性用系统对抗随机性。模型输出不稳定是常态你要做的是用检索、约束、校验、重试、监控把它兜住而不是每次出了问题就怀疑自己选错了模型。兜底设计得越稳模型的真实能力才越能发挥出来。从零开始学AI工程真正难的从来不是某个API怎么调而是面对不确定性时你愿意花多少心思搭一套能长期运转的系统。这条路没有捷径但每一步都能复用走得并不亏。