
ai-engineering-from-scratch翻译过来就是从零开始做 AI 工程。这个项目名字看着像一门课程实际上代表了过去一年我反复验证的一条完整路径从拿到一个大模型到把它变成真正能落地、能扛住真实业务流量的应用系统。很多朋友刚接触时都会问同一个问题大模型这么强直接调用 API 不就行了为什么还需要专门的工程答案是模型能给你一段高质量文字但给不了你一个稳定、可控、可维护的产品。这中间的差距就是 AI 工程要补的课。这篇文章我结合自己的实操经历把从零搭建 AI 应用的核心环节完整拆一遍提示词工程怎么做、RAG 检索增强怎么落地、Agent 智能体怎么编排、测试和评测体系怎么搭以及最常踩的坑怎么排。适合三类人看想转行做 AI 应用开发的工程师、正在带团队做 AI 项目的负责人以及想独立用 AI 做产品的开发者。读完你至少能搭出一条数据准备 → 检索 → 生成 → 评测 → 迭代的完整链路而不是只停留在调用一下模型 API的玩具阶段。1. 项目概述与整体思路解构1.1 从零到底零在哪里先说清楚一个概念AI 工程里的从零不等于自己训练大模型也不是从线性代数开始补课。你不需要自己从零实现 Transformer也不需要去优化损失函数这些工作由模型训练团队和开源社区完成了。这里的零指的是你手上除了一个大模型的 API 或开源模型权重之外什么都没有没有现成的业务流程、没有数据管线、没有评测集、没有可复用的工程骨架。你要做的是在这个零的基础上把模型能力变成产品能力。这个定位非常重要因为它决定了你整个学习路径的重心。我刚带团队时很多成员的第一反应是去读论文、复现模型结构结果一个月过去连一个能跑的 demo 都没有。后来我强制大家把时间放到下游任务上设计提示词、清理数据、搭检索链路、做效果评测。一周之后每个人的手里都有了一个可以演示的版本。方向对了进度就快方向错了努力全是沉没成本。从零到一的路线图我建议按顺序走五步第一掌握提示词工程这是最基础也是最容易立竿见影的能力第二学会用框架和工具编排模型调用把单次问答变成可复用服务第三引入外挂知识库也就是 RAG这是目前 AI 应用落地最主流的形态第四升级到 Agent 智能体让模型具备规划任务和调用工具的能力第五搭建评测与监控体系让系统可度量、可回归、可持续迭代。这五步覆盖了当前几乎所有 AI 应用的核心骨架。1.2 先搞工程还是先搞算法这是几乎所有新人都会纠结的问题我的答案非常明确先搞工程。80% 的业务场景根本不需要你动模型参数你需要解决的是数据怎么进来、结果怎么出去、质量怎么保证、成本怎么控制。这些全是工程问题。只有当你发现现成模型在特定任务上怎么调都达不到效果时才需要考虑微调或蒸馏而那已经是第二个阶段的事了。工程思维和算法思维有一个本质区别算法思维追求理论上更优工程思维追求系统上可行。举个例子我在做文档问答时算法同事建议用更复杂的语义切分模型来切分长文档说理论上能提升召回率。但我评估了一下那个模型的推理耗时会让整个接口的响应时间增加三倍而且个别长文档的切分边界并不稳定。最后我用的是固定大小 重叠窗口 标题层级拼接的工程方案效果接近成本低了一个数量级。这就是工程和算法的分野你要的不是最好的模型而是最合适的系统。当然完全不碰算法也不行。我所说的先搞工程是让你把工程基线先跑通然后再在关键节点上补充算法知识比如嵌入模型是什么、向量相似度怎么算、重排Rerank为什么能提升精度。这些知识不用深到推导公式但必须理解原理否则出了问题你连排查方向都没有。1.3 不同背景的人怎么切入AI 工程有个特点它不像传统后端那样要求统一的语言和技术栈所以不同背景的人切入路径差别很大。有 Web 后端经验的工程师最容易上手。你的优势在于服务架构、接口设计、数据库、部署运维这些基本功可以直接迁移。你要补的只有两块一是理解模型的输入输出方式和能力边界二是学会写提示词和设计检索链路。我通常建议这类人直接把项目做成一个带 API 的服务用 FastAPI 包一层前端或业务系统来调用这样最能发挥你的优势。数据分析师或测试工程师转型也别慌。你对数据质量的敏感度是很大的优势因为 AI 应用的质量问题本质上都是数据问题。你可以先往AI 测试开发方向走帮团队搭建评测集、设计回归测试、分析 bad case。这个岗位在当前市场非常稀缺很多团队不缺写代码的人缺的是能说清楚模型效果到底好不好、哪里不好、为什么不好的人。完全零基础的朋友我给的建议是不要先啃编程先白嫖各种 AI 产品建立直觉。去用各种大模型产品观察它们在什么场景下好用、什么场景下胡说八道然后尝试用自然语言写提示词控制它们的输出。有了直觉之后再从 Python 语法开始学 Flask、学爬取数据、学调用 API。你不需要成为一个资深程序员但你需要成为那个最会指挥 AI 干活的人。2. 核心技术栈与工具选型解析2.1 AI 应用的最小技术栈我一直反对一上来就堆技术栈。很多教程张口就是 LangChain、LangGraph、Dify、FastGPT把架构图画得天花乱坠结果新手全在学框架学完还是不会自己解决实际问题。我的做法是先用最朴素的代码打通一条最小链路再根据痛点引入框架。一条 AI 应用的最小链路长这样用户请求进来你的服务把请求拼接成提示词或调用 Agent 框架发送给大模型云端 API 或本地部署模型拿到输出后再经过解析、校验、后处理返回给用户。如果涉及知识库问答中间再加一条向量化 → 检索 → 重排的路径。所有技术栈都是在为这条链路服务。具体到选型我分成四层说。模型层云端闭源 API 适合追求效果和上线速度的场景国内可用的大模型服务很多开源模型则可以用 Ollama 一键本地跑起来或者用 vLLM 做高性能部署。框架层我的建议是新手先别用 LangChain先手写两次调用逻辑理解提示词拼接和函数调用的本质然后再拿框架简化重复劳动。数据层小项目用 Chroma 或 FAISS 就够了数据量大、并发高再上 Milvus 或 pgvector。服务层首选 FastAPI自带异步支持和接口文档写起来快。2.2 Prompt Engineering 提示工程的价值与边界提示词工程是所有人都绕不开的第一课但它也是最容易被误解的一课。它不是简单的把话说清楚而是利用模型的训练特征来约束它的行为空间。我觉得有一个类比特别准确提示词不是咒语而是给一个什么都懂一点但有点爱自由发挥的实习生写的任务说明书。说明书越清晰实习生的发挥越可控。一份高质量的提示词至少要包含五个要素角色设定、任务描述、约束条件、示例输出、输出格式。角色设定告诉模型你是谁、站在什么立场任务描述告诉它你要干什么约束条件告诉它什么不能干示例输出给它一个参考模板输出格式则方便你做程序解析。我自己的模板通常长这样开头定义角色和背景中间列任务清单并编号然后用注意不要...写约束最后给一个 JSON 格式的输出样例。提示词也有边界。它约束的是模型的输出风格和内容倾向无法改变模型内部的知识边界。你让模型回答一个它从没见过的产品参数它唯一能做的就是编一个看起来合理的答案。所以遇到这类需求不要死磕提示词而是要给它外挂资料也就是下一步要说的 RAG。提示词工程管行为知识外挂管内容两者配合才是完整方案。2.3 从单模型调用到 Agent 智能体Agent 是这两年 AI 工程里最火也最容易做虚的概念。我把 Agent 的本质讲穿它就是一个能自己做决定调用什么工具的大模型循环。传统开发里流程是你写死的用户说 A程序就执行 A。Agent 不一样模型分析用户的指令自己决定先调哪个工具、根据工具返回结果再决定下一步做什么。这个能力在业务自动化、多步骤任务处理上价值很大。但 Agent 最怕的就是失控。模型在一个多步骤任务里可能会反复调用同一个工具停不下来也可能会在工具返回的结果不理想时自作聪明地编一个结果。所以工程上必须给 Agent 加约束这就是我常说的Harness Engineering直译过来是缰绳工程——像给马套缰绳一样给 Agent 划定活动范围和行动边界。具体做法包括限制工具列表的数量和精度给每个工具写清楚描述和参数规范设置最大迭代步数超了就强制结束关键节点要求模型输出中间推理过程方便回溯对工具返回结果做校验异常时直接中断而不是让模型硬编。没有这层约束Agent 只能在 demo 里炫技上不了线。多 Agent 协作是另一个容易翻车的地方。我的经验是能用一个 Agent 解决的绝对不要拆成两个。Agent 之间互相传递信息时格式不统一、上下文丢失、决策冲突都是高频问题。如果确实要拆那就明确分工一个主控 Agent 负责理解任务、拆解步骤、汇总结果若干子 Agent 负责具体执行。消息格式统一用结构化 JSON每个 Agent 只读它需要的字段尽量避免所有 Agent 共享全部上下文这种设计。2.4 AI 测试开发没有评测体系就别谈迭代我觉得整个 AI 工程里最被低估的环节就是测试和评测。传统软件测试测的是输出是否符合预期而 AI 应用的输出是概率性的同一个问题问两次答案可能字面上完全不同。这就意味着你无法用简单的断言来验证功能你必须建立一套基于数据集和指标的评测体系。我管这套工作叫AI 测试开发它包含三个层面。第一层是构建评测集也就是一批有标准答案或答案判据的问题来源可以是历史真实用户问题、业务专家标注、模型生成后人工修正第二层是定义评测方式可以用规则匹配关键信息、可以用语义相似度打分、也可以让另一个模型当裁判LLM-as-judge第三层是把评测跑在 CI 里每次修改提示词或调整检索参数都自动跑一遍全量回归用分数对比来判断改动是变好了还是变差了。评测体系最忌讳的是自嗨。我见过很多团队自己写了 20 条测试题每次改完代码跑一遍分数涨了就觉得效果变好了。但实际上那 20 条题跟真实用户问的问题根本不是一回事。正确的做法是从真实用户日志里抽样覆盖高频问题和困难问题让业务方参与标注满意 / 不满意 / 错误然后每个月基于线上 bad case 滚动扩充评测集。评测集就是 AI 应用的地基地基歪了楼越高越危险。3. 实操记录从零搭一个企业知识库问答系统3.1 场景定义为什么第一个项目选 RAG前两部分讲的都是概念接下来的实操部分我用一个最经典的场景来串联企业内部文档问答系统。为什么第一个项目选这个因为它完整覆盖了 AI 工程的各个核心环节且业务价值非常清晰。文档散落在各个地方Word、PDF、企业Wiki员工查一个政策要翻半天而大模型天生擅长把零散信息组织成通顺的答案只是不知道你公司内部的内容所以我们必须给它外挂一个资料库这就是 RAG 的本质。RAG 的全称是检索增强生成Retrieval-Augmented Generation思路就三步先把你的文档切块、向量化存进向量数据库用户提问时把问题也向量化去库里找最相似的若干文本块把这些文本块和问题一起塞给模型让它基于这些资料作答。这套方案最大的好处是不用训练模型知识可以随时增删改答案可溯源。它是目前 AI 应用落地最成熟的技术路线没有之一。在开始之前我建议你先问自己一个问题我要做的这个系统核心 KPI 是什么对知识库问答来说KPI 通常不是回答得多通顺而是能不能找到正确的那份文档、能不能基于它给出准确答案。这个判断会影响你之后所有的设计决策。3.2 数据准备文档清洗与切分策略很多人把 RAG 的重心放在模型和检索上但实际跑下来你会发现数据准备才是决定效果上限的那一步。脏数据进脏数据出模型再强也救不回来。我拿一个真实项目举例客户发来几百份企业制度文档格式极其混乱有扫描 PDF、有表格嵌套的 Word、有带页眉页脚的网页导出件。我的处理流程是分四步先用工具把 PDF 转为文本或 Markdown检查乱码然后做清洗把页眉页脚、重复的目录、无意义的换行符全部去掉接着按文档原有的标题层级切分保留章节目录信息作为元数据最后把文本切成一个个信息块每块控制在 300 到 500 个 token 左右块与块之间留 50 到 100 个 token 的重叠。重叠的目的是防止一个完整语义被从中间切断。切分这个环节很多人直接用固定长度硬切效果一塌糊涂。更好的做法是语义优先、长度兜底优先按 Markdown 标题、段落、列表来切切出来的块如果太长再按句号或换行符二次切分。每块文本记得附上来源文档、页码或章节路径等元数据这样以后才能做答案溯源。这块没有银弹需要根据你文档的实际情况反复调。3.3 嵌入模型与向量检索选型文本切好之后下一步是把它们变成向量。这里要先解释一下什么叫嵌入简单说就是把一段文字变成一串固定长度的数字让语义相近的文字在数字空间里距离更近。比如公司年假政策和工作满一年可以休几天这两句话字面上完全不像但嵌入向量会很靠近这样你用后者去检索就能召回前者。嵌入模型的选择直接影响检索质量。我现在的经验是中文场景优先用国产开源嵌入模型比如 BGE 系列效果在中文语义上表现很好本地部署免费且没有数据外泄风险英文或混合场景可以选 OpenAI 的 text-embedding-3 系列。向量维度不是越大越好很多场景 768 维已经够用维度太高会带来存储和检索成本的上升。选嵌入模型时注意固定版本因为换模型等于整个向量库重建代价很大。向量数据库这块我的选型逻辑是分阶段。第一个版本我用 FAISS因为它只是一个库嵌入在服务进程里部署简单项目只有几万条数据时完全够用。数据量到了百万级、需要多人同时检索、需要持久化和权限管理时再迁移到 Milvus 或 pgvector。不要一开始就追求分布式架构当前阶段能用够用比高大上重要。3.4 检索与生成链路从裸召回到底装进提示词向量检索是最常用的召回方式但实际项目里纯向量检索会在两个地方出问题一是专有名词和精确代码比如报销流程编号 FY-2024-03语义上很难找到相近表述向量召回效果差二是用户问题太口语化跟文档里书面语风格差距大。解决办法是引入混合检索同时跑向量相似度和 BM25 关键词匹配然后把两路结果合并排序。BM25 是传统搜索引擎的核心算法擅长精确匹配与向量检索互补性很强。召回之后再上一个重排模型Rerank是见效最快的提升手段。原理不复杂向量检索先粗召回 50 条候选重排模型再对这 50 条逐一精读评估它们跟用户问题的相关性只保留 Top 3 到 Top 5 传给大模型。这个环节会让最终答案质量上一个台阶因为它把接近的问题变成了精确的上下文。代价是多了几十毫秒延迟但值得。然后是组提示词。RAG 的提示词跟普通问答不太一样必须明确告诉模型下面这些资料来自企业内部文档只基于这些资料回答资料里没有的就直接说不知道不要编造每条答案最后标注资料来源格式是[来源文档名-章节]。这一步很关键它既减少幻觉又让答案变得可信。拼装时我会把多段资料用 XML 标签包起来方便模型区分不同来源也方便后续解析。3.5 从脚本到服务完整工程代码示例理论讲完上实战代码。下面是我常用的一个最小可运行版本用 Python 实现依赖只用了 FastAPI、OpenAI SDK 和一个本地向量库。这里我故意不用重量级框架目的是让你看清每一步在干什么。import os from fastapi import FastAPI from pydantic import BaseModel import chromadb from openai import OpenAI app FastAPI() # 初始化向量库本地持久化 client chromadb.PersistentClient(path./kb_store) collection client.get_or_create_collection(docs) # 初始化大模型客户端 llm OpenAI( base_urlos.getenv(LLM_BASE_URL, http://localhost:8000/v1), api_keyos.getenv(LLM_API_KEY, local), ) class AskRequest(BaseModel): question: str def retrieve(question: str, top_k: int 5): 向量检索 关键词检索合并这里简化用向量检索 results collection.query( query_texts[question], n_resultstop_k, include[documents, metadatas], ) return results[documents][0], results[metadatas][0] def build_prompt(question: str, docs: list, metas: list): context \n\n.join( fdoc\n{doc}\n来源{meta.get(source, 未知)}\n/doc for doc, meta in zip(docs, metas) ) return f你是一位企业内部知识库助手。请只基于下面提供的资料回答问题。 资料中不存在的信息请明确回答资料中未找到相关内容严禁编造。 资料 {context} 用户问题{question} 要求 1. 答案准确、简洁、条理清晰。 2. 回答末尾列出引用来源格式为[来源文件名-章节]。 app.post(/ask) def ask(req: AskRequest): docs, metas retrieve(req.question) prompt build_prompt(req.question, docs, metas) resp llm.chat.completions.create( modelos.getenv(LLM_MODEL, qwen), messages[{role: user, content: prompt}], temperature0.1, ) return {answer: resp.choices[0].message.content, sources: metas}这段代码有三个值得注意的细节。第一temperature0.1知识库问答是确定性问题场景温度必须设低减少模型自由发挥第二提示词里要求模型在资料缺失时说明这是对抗幻觉的关键设计第三检索结果的元数据直接返回给前端前端可以展示引用来源用户能点进去核对原文信任感完全不一样。上线之前还有三件事必须做一是加接口鉴权和限流防止被别人白嫖算力二是记录每次提问和回答的日志这是后续分析和优化的数据基础三是加基础监控比如响应时间、检索失败率、空答率空答率突然升高往往意味着检索链路出了问题。4. 常见问题与排查技巧实录4.1 答案质量不达标先调什么这是出场率最高的问题。答案是质量很差是调提示词、换模型还是加数据我的排查顺序是固定套路按优先级来第一先查检索。拿用户的原始问题去跑检索看召回回来的 Top 5 到底是不是相关内容。如果召回的前几条根本不相关那模型答得再差也怪不到它头上——巧妇难为无米之炊。检索质量排查方向包括问题是不是太口语化导致向量偏了是不是专有名词没召回候选数是否太少重排模型有没有误杀。第二再查数据。看召回的文本块本身内容是否完整是否被切断了上下文有没有关键信息在下一块里。比如合同条款经常跨页切分时按页切那模型永远看不到完整条款。这种问题调提示词是无效的必须回头改切分策略。第三查提示词。确认约束条件是否写清楚了资料缺失时是否要求模型承认不知道输出格式是否会被模型随意改变。第四才轮到换模型。说实话我用过的大小模型不少在同等条件下GPT-4o 系列、Claude 系列和国内几个头部模型在知识问答任务上的差距远没有想象中大。先把前三步走完效果基本都能拉到及格线以上。4.2 上下文太长、成本失控怎么办AI 应用的成本大头基本都在模型 token 消耗上而且很多人以为只有输出才花钱其实输入 token 才是花钱大户。一个典型知识问答请求检索回来的资料可能就有两千 token加上系统提示词、历史对话、候选资料去重重排后塞进去单次请求消耗轻松上万 token。访问量一起来账单立刻爆炸。我的成本控制三板斧第一板斧是瘦身系统提示词精炼到 500 token 以内历史对话只保留最近两轮更早的做摘要检索回来的资料只保留与问题最相关的 Top 3不是 Top 5让重排模型把最精的筛出来。第二板斧是缓存对高频问题做语义相似度匹配命中缓存直接返回历史答案省掉模型调用费用。第三板斧是限额给每个用户每天设置调用次数上限并对超长输入做截断保护防止被恶意刷量。还有一个容易被忽略的技巧把知识库内容的结构化摘要存一份。比如用户问报销流程你不必把整个 1000 页制度手册都检索进来可以先把流程标题 摘要 原文位置作为一个检索入口命中后再按需加载细节。这种先摘要后详情的设计能把单次请求的 token 消耗降低 50% 以上。4.3 检索不到相关内容怎么办这个问题比答案质量差更隐蔽因为用户看到的不是答错了而是模型在硬编——资料库里根本没有的流程模型也能绘声绘色地描述出来。排查时首先要做的是确认资料库的覆盖面用户问的事务文档里到底有没有写很多项目上线后才发现核心业务流程根本没有发文资料库本身就是不完整的。遇到这种情况不是调技术是去推动业务部门补资料。技术侧的排查方向有三个。一是检查问题 rewrite 是否缺失。用户问去年年底发的那个关于加班补贴的通知直接拿这句话去检索大概率召回失败。正确做法是先用一个轻量模型把问题改写为标准查询加班补贴通知甚至拆成多个关键词组合再分别检索合并结果。二是检查嵌入模型对专业术语的识别。有些场景需要自定义一个同义词词典把简称、缩写、俗称都映射到标准术语上检索前做一层替换。三是检查检索结果排序。如果相关内容能召回但排在第 20 位那需要提高候选数并强化重排而不是简单加大 top_k否则噪声也会同时进来。4.4 评测怎么做才不算自嗨我在前面强调过评测的重要性这里给出一套具体可执行的方案你直接照着搭就行。第一步从用户真实日志里抽 100 条问题覆盖高频问题、疑难问题各半。第二步给每道题标注满意答案要点可以是关键词集合也可以是一段参考答案。日常维护时如果答案命中了要点就是通过。第三步三档打分好、及格、差。好是关键信息全对且引用正确及格是信息部分缺失但不致命差是答非所问或关键信息错误。第四步每轮迭代后跑一次全量评测对比好和差的比例变化。我把这个指标简称为好评率每次改动必须让好评率不降才会合入。还有两个进阶技巧值得用。一是模型打分LLM-as-judge让一个更强的模型当裁判把问题和回答发给它让它按你定的标准打分。用下来标准要写细相关性、完整性、引用准确度、语言通顺度每一项单独打分否则裁判模型只会给出一句模糊的整体不错。二是建立 bad case 复盘机制每次发现一个典型错误立即把它加入评测集并修正答案要点保证同样的错误不会第二次蒙混过关。这样你的评测集会越来越难系统也会越来越稳。4.5 多 Agent 协作时的互踩与防呆如果你已经开始尝试多 Agent 架构一定会遇到两个作用互相打架的经典场景主控 Agent A 让资料 Agent B 搜索数据B 返回一个表格主控 Agent 没看懂表格自作主张改写了一段然后业务 Agent C 又基于改写后的内容做了错误判断。最后用户收到一个逻辑断裂的回答而你根本不知道是哪一环出了问题。我处理这类问题的经验是四件事同时做。第一每个 Agent 只给它必要的上下文禁止共享全部历史避免信息污染。第二Agent 之间的消息全部走结构化 JSON定义好固定字段例如{task: search_docs, query: ..., max_results: 5}主控 Agent 拿到这个结构后直接解析而不是靠自然语言理解。第三给每个 Agent 设置权限边界和最大执行步数工具失败或超时就直接返回错误不要允许 Agent 自己编造工具结果。第四整条链路打完整日志每个 Agent 的输入、输出、耗时全部记录排查问题时按时间线回放。做到这四条多 Agent 协作才具备可维护性否则就是一场大型赌局。还有一个小技巧设计 Agent 时先把它的工具清单 触发条件写成一个表比如某个 Agent 专门负责文档检索只有当问题里出现制度、流程、规定这类词时才触发。这个表既是给模型的系统提示词也是给你的架构文档一举两得。5. 从零到一最后想说的话整套流程走下来我最深的体会是AI 工程从零到一真正的瓶颈从来不是模型能力而是你能不能把模型装进一个靠谱的产品容器里。提示词工程管行为RAG 管知识Agent 管流程评测管质量四件事环环相扣缺一个都会在线上暴露问题。如果让我给刚开始的人一个建议我会说先别追求架构上的大全也不要急着上多 Agent就从一条最简洁的 RAG 链路开始用你自己的业务数据跑通然后疯狂问问题把暴露出来的 case 一个个修掉。等你修到 50 个问题时你对 AI 工程的理解会比读十本教程都深。这不算什么魔法它就是朴素的工程实践——每次踩坑都记录下来把它变成评测集里的一道题让系统在这个坑上永远不再跌倒。最后再分享一个小技巧给知识库问答系统加一个这个回答有帮助吗的反馈按钮用户的一次点击胜过你离线猜测一万次。把用户反馈和实际回答一起存下来每周抽一次 bad case 分析你的系统就会以肉眼可见的速度变好。这个投入产出比是我做 AI 工程以来遇到过最高的。