从零构建AI工程化:Prompt、数据管道与RAG落地实践
1. 从零构建AI工程的整体思路1.1 为什么需要“AI工程化”而不是“写脚本”很多朋友最早接触AI是从跑通一个开源模型或者调用一个大模型API开始的。Jupyter Notebook里写几行代码模型能回复就觉得已经会了。但真到了要做一个面向真实用户的产品你会发现事情完全不是这样。模型能跑通和系统能稳定跑一年中间隔着一整条“工程化”的鸿沟。我理解的AI工程化指的是把算法、数据、训练、推理、部署、监控、迭代这条链路用软件工程的方法管理起来。它处理的不只是“模型怎么调”还包括“数据从哪来”“用户请求怎么被路由”“回答质量怎么评估”“模型升级了怎么平滑切换”这些脏活累活。从零开始做AI工程说白了就是把这些环节一项项从无到有搭起来让AI能力真正变成产品的一部分而不是停留在演示阶段。过去做传统软件核心是“逻辑正确”——输入确定输出确定测试用例可以穷举。AI工程完全换了一套玩法模型的行为是概率性的同样的Prompt可能今天回答得漂亮明天就说得颠三倒四。你没法用常规的断言去做断言只能通过评估体系、数据回流、灰度发布这些手段来兜底。这就是为什么“会调模型”和“会做AI工程”是两种能力。1.2 从零开始的完整路线图如果只有一个人、一台机器要从零开始走完一个AI项目的完整周期我建议按下面这条路线推进定需求明确这个AI要解决什么问题输入是什么输出是什么错误了会有什么后果。这一步别着急写代码先把边界划清楚。攒数据哪怕是调用现成的大模型API也需要准备示例样本、评估集。数据这一步决定了项目的上限。选方案是直接用大模型API还是微调开源模型还是干脆训练一个小模型不同方案的成本、可控性、延迟差距很大。搭流程把“输入 → 处理 → 模型调用 → 输出校验”这条主链路用代码固化下来让我能重复跑。建评估准备一组测试用例每次改动后跑一遍用分数而不是“我感觉变好了”来驱动迭代。上部署封装成服务处理并发、超时、限流、日志让外部系统能稳定调用。做监控记录线上的输入输出质量沉淀badcase回到第一步去优化。这个闭环打通一次你才算是真正做过一个AI工程而不是仅仅跑通过一个模型。接下来我逐个模块拆开讲。2. 核心模块拆解Prompt、数据、Agent与工作流2.1 Prompt Engineering不是简单写话术很多人在这一步翻车。所谓Prompt Engineering不是会写“请你帮我总结一下这篇文章”就叫会了它其实是在没有权限修改模型参数的情况下通过输入文本的编排去控制模型行为的一套方法学。哪怕大模型的能力再强Prompt设计粗糙最后出来的结果质量也会非常不稳定。从工程角度看一份合格的Prompt应该包含五件套角色设定、任务目标、输入内容、输出格式约束、边界规则。角色设定是告诉模型“你是谁”任务目标是说明“你要做什么”输入内容是数据本身输出格式约束是强约束好消息结构边界规则是兜底比如“如果你不确定直接说不知道”。但比写Prompt更重要的是把Prompt纳入版本管理。Prompt会变不同的业务场景可能有不同的Prompt模板。我见过太多团队模型换一版、业务改一点Prompt就在代码里被随手改来改去最后线上是什么样根本没人说得清。实操中我习惯把每个场景的Prompt做成单独的配置文件带上版本号和生效时间发布新Prompt时走灰度。测试集里专门放几十条边界案例每次改Prompt都要重跑一遍对比前后效果。举个例子做客服问答时常见的一个坑是模型喜欢“脑补”。客户问“你们家有白色款吗”模型回答“我们有黑白两色可选”但仓库里其实只有黑色。此时Prompt里就要写清楚“只允许根据提供的商品信息回答信息中不存在的内容一律不许推测”。这种约束写不写效果差着十万八千里。2.2 数据管道AI工程的隐形地基模型是发动机数据才是燃料。从零开始做AI工程最容易被低估的就是数据环节。很多项目最开始只有一个想法手里没有结构化数据这时候最务实的方法是“手工构造种子数据”。比如要做一个文档问答系统就自己整理几十份典型文档配套人工写答案要做一个代码生成助手就找一批开源项目里的真实issue和对应merge记录。数据管道在设计时我坚持“一条主链路”原则原始数据 → 清洗 → 结构化 → 入库/向量化 → 样本标注 → 评估集。每一步都要有日志要能回溯。现实中数据异常的表现千奇百怪PDF解析出来乱码数据库字段全空用户输入里带一堆表情符号。没有管道日志排查起来像大海捞针。关于训练集、验证集、测试集的分割传统机器学习说要按比例切AI工程里更讲究按“时间”和数据来源切。用上个月的数据做测试集用更早的数据做训练集这样更能模拟模型在“未来数据”上的表现而不是在测试集上自欺欺人。数据量大之后还要考虑标签一致性问题两个标注员对同一条样本可能给出不同答案这个差异要提前定好仲裁规则。2.3 AI Agent与多AI协作从单点功能到复杂任务最近一年狂热的AI Agent本质上是在解决一个核心诉求让模型从“回答一句话”进化成“完成一件事”。单次模型调用只能做一次推理但真实任务往往是多步骤的——要查资料、要写代码、要调用工具、要根据中间结果决定下一步。Agent就是把这些步骤编排起来让模型自己决定执行路径。做Agent工程化我踩过最深的坑是“自由度陷阱”。一开始我给Agent配了十几个工具效果看起来很强但一上真实数据就乱了模型经常选错工具、传错参数。后来我总结出一个原则工具的入口参数越少越好意图越明确越好给模型的选择不是越多越好而是越少越好。多AI协作是另一种思路不试图让一个大模型干所有事而是拆成多个小模型每个负责一件事。比如一个做意图识别一个做实体抽取一个负责生成最终答案。两三个模型协同跑单个模型的表现要求就降下来了问题范围也变小了整体稳定性反而更高。当然代价是链路变长、排查变难。我一般只在有条件切割清晰的任务里这么干比如“先判断有没有相关文档有就检索总结没有就直接说不知道”这种串行流程。3. 实操过程构建一个可落地的AI问答系统3.1 需求定义与方案选型纸上谈兵够了我拿一个实际的项目举例做一个面向企业内部的知识库问答机器人。需求很朴素员工提问机器人基于企业文档回答不能编造要给出处。方案选型时其实摆在我面前有三条路直接把几十份文档全量塞进Prompt简单粗暴但受上下文窗口限制文档一多就塞不下。微调一个开源模型可控性高但需要准备大量问答对初期成本高。走RAG路线先检索后生成不训练模型靠“检索到的知识片段Prompt”来回答。我选了RAG原因是初期数据量和查询模式都还不固定RAG最容易迭代。模型先用开源的中文对话模型等检索效果稳健后再决定要不要换更大的底座。RAG唯一的隐患是检索如果召回错误文档答案必然跑偏所以后面我给它加了两道防线一道是“召回内容置信度检查”召回文档和问题相关性太低就拒绝回答另一道是“答案引用溯源”回答内容必须带上检索到的文档编号。3.2 最小可行版本落地先看目录结构。从零起步不要一上来就搞微服务一个清晰的单体项目足够度过前三个月ai-knowledge-bot/ ├── config/ # 存放每个场景的Prompt配置 ├── data/ # 原始文档、分割好的文本片段、向量索引 ├── src/ │ ├── ingestion/ # 文档加载、分割、向量化入库 │ ├── retrieval/ # 检索与召回 │ └── generation/ # 生成与校验 ├── eval/ # 测试用例和评估脚本 └── api/ # FastAPI 对外服务文档切分是容易出问题的环节。按固定字数切分最简单但会把一个完整知识点切得七零八落检索时反而召回不整段内容。实操里我建议尽量按文档结构切一个标题下的内容作为一个块同时保留“上下块”的关联引用。代码示例大致长这样import re def split_by_heading(text: str) - list[dict]: blocks [] current_title 文档开头 current_content [] for line in text.splitlines(): # 识别markdown标题作为切分边界 if re.match(r^#{1,4}\s, line): if current_content: blocks.append({ title: current_title, content: \n.join(current_content) }) current_title line.strip(# ).strip() current_content [line] else: current_content.append(line) if current_content: blocks.append({ title: current_title, content: \n.join(current_content) }) return blocks这块代码不复杂但要注意切分后每个块最好保留标题层级后续检索到片段时才能展示完整上下文用户看到答案不至于一头雾水。向量化入库这一步我直接用了常见的中文Embedding模型把每个文本块编码成向量存进向量数据库。索引建好之后第一次调试检索效果时我习惯先不看生成结果光看召回结果这是定位问题最快的路径。3.3 模型部署与服务化模型构建完成后部署是另一道坎。很多人直接把模型封装成FastAPI接口就算完事但真实场景下要处理的问题多得多请求排队、超时、并发控制、日志采集、模型热更新。我最常用的是把模型服务拆成两个独立进程一个常驻的推理进程负责加载模型并推理另一个API进程负责接收用户请求、做检索、组装Prompt、把请求发给推理进程。两个进程用本地HTTP通信这样推理进程崩溃了API进程可以做熔断和重试不至于整个服务挂掉。就RAG问答这种场景接口的超时设置有个经验值检索阶段控制在500毫秒以内模型生成阶段根据输出长度设10~30秒。线上部署时我还加了简单的关键词熔断一旦发现某个接口地址或者某个渠道的调用异常率超过阈值就自动切换备用Prompt模板减少用户可感知的故障时间。from fastapi import FastAPI import requests app FastAPI() app.post(/ask) def ask(query: str): # 1. 召回 docs retrieve(query) if not docs: return {answer: 抱歉知识库里没有找到相关资料。, sources: []} # 2. 组装 prompt prompt build_prompt(query, docs) # 3. 调用推理服务 resp requests.post(http://localhost:8001/generate, json{prompt: prompt}, timeout20) return {answer: resp.json()[text], sources: [d[title] for d in docs]}部署完不要急着宣布大功告成先做一轮压力测试。我自己常用最简单的并发脚本模拟50个用户同时提问观察响应时间、显存占用和错误率。这里有个很常见的问题首批请求特别慢因为模型加载和显存预热都在第一次调用时发生。解决方法是部署完容器之后先主动发几个空请求做预热再对外暴露流量。4. 常见问题与排查技巧实录4.1 效果不稳定今天好用明天抽风这是AI工程最让人头疼的问题。模型的输出带有随机性温度参数调低了只是减小随机不代表稳定。更麻烦的是如果你用的是大模型API底层模型可能已经被服务方悄悄更新了同样的Prompt和参数结果就是会变。排查套路要形成习惯。第一把“输入、Prompt、模型参数、输出”四件套完整打日志留足可回溯的信息。第二每次改动只动一个变量要么只调Prompt要么只换数据不要一次改三处否则出了问题根本不知道是哪个环节引起的。第三建立badcase库每次线上发现回答得不对就把这条case连同当时的检索结果一起存下来每周复盘一次你会很快发现高频问题集中在哪类输入上。4.2 模型幻觉与控制幻觉问题是生成式AI绕不开的老大难。所谓的幻觉就是模型一本正经地输出事实上不正确的内容。在知识库问答这个场景里我通常从三个层面去堵Prompt层明确写“只能用提供的资料回答资料里没有就回答不知道”。数据层检索阶段做相关性阈值过滤召回分数太低的文档直接丢弃不给模型看到“可能不相关”的内容。输出层要求模型在回答时标注引用来源后续做人工抽检时能快速判断回答是否忠实于原文。即便如此幻觉不能完全归零只能力争把概率降到可接受的范围。需要清醒的是如果业务场景对错误零容忍那就必须引入人工审核把AI当成辅助工具而不是最终决策者。4.3 评估与回归没有评估体系的AI工程就是瞎子摸象。我强烈建议从项目第一天就建一个迷你评估集哪怕只有三四十条问答对。每周往里面加新发现的badcase让评估集慢慢长大。每次改动模型、Prompt、检索策略都跑一遍评估集算准确率、召回率、或者更贴近业务的指标比如“回答是否包含出处”。顺便说一个很多人会忽略的点评估集的答案要由人来写而且要写“参考答案”不是“唯一答案”。开放域问答本身就存在多答并存的情况太死板的判定会误导调优方向。我后来用了一个折中方案人工写参考答案再用一个独立的评判模型给回答打分人工抽检打分质量。这个套路虽然不是100%准但至少比“目测效果不错”靠谱很多而且成本可控。4.4 测试开发与harness工程实践AI领域的测试开发和传统软件测试很不一样。传统测试断言的是“输出符合预期”但AI系统输出天然有浮动没法硬编码。我理解的harness就是给AI系统套上一个“测试缰绳”把那种浮动的行为纳入可重复的检查框架里。实操中我会做三层harness输入层校验查询是不是空是不是超长是不是包含了不该包含的字符。输出层校验回答里是否出现“我不知道”却能给出内容的矛盾引用来源是否真的存在回答长度是否超限。行为层校验同一问题连续问五次结果差异有多大换一种等价问法答案是否还能保持一致。这层工程的意义在于它让AI的输出从“不可控的文本”变成了“可被检查和约束的结果”。哪怕不能100%自动判定对错也能堵住大部分低级错误大幅减少线上事故。5. 一个人在AI工程里的经验与扩展方向5.1 从零开始我的真实体会踩过无数次坑之后我最想强调的不是某个技巧而是反馈闭环要快。AI工程里最怕的就是调一次参数要等几小时跑一次评估要手动整理半天结果这种节奏根本迭代不起来。我会花很多精力去优化这条反馈链路自动化评估脚本、随时可跑的测试集、结构化的日志。宁可减少做新功能的时间也要把反馈做快。还有一个反常识的经验前期要把步子放小。只做最简单的检索加Prompt调用就能支撑很多业务问题。等到量上来了再逐步把Agent、多模型协作这些复杂度引进来。过早引入复杂架构只会让你在排查问题时迷失方向。5.2 后续可以扩展的方向一个从零开始的项目跑通之后可以升级的空间其实很大。数据标注环节可以引入主动学习让最值得标注的样本优先进入人工标注检索环节可以做重排用粗排加精排替代简单的向量相似度模型环节可以尝试在开源底座上微调一个“业务专属模型”把常见表达方式固化进模型运维环节可以引入更完善的线上监控对回答质量做实时打分和告警。这些方向不是说一上来就要全做而是当你发现业务对质量、成本、速度有更高要求时慢慢按优先级去叠加。我自己就是这么一路走过来的每次只给系统加一个变量观察一段时间再决定下个方向。AI工程从零开始这件事从来不是为了追一个“AI工程师”的头衔而是把不确定的模型行为打磨成确定可用的产品能力。这个过程不会太轻松但每一步走扎实了后面就会越来越顺。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →