做 AI 工程这几年,我最大的感触是:很多人把“让模型跑起来”和“把 AI 做成产品”混为一谈。调通一个 API、跑通一个 demo,离真正的 AI 工程还差着十万八千里。所谓 ai-engineering-from-scratch,就是抛开那些花哨的框架和包装,从最底层开始问自己一个问题:我真的知道这套 AI 系统是怎么被设计、构建、测试和上线的吗?这篇文章是我自己从零搭建 AI 能力的完整复盘,覆盖 prompt engineering、Agent 架构、评测体系、测试开发这些核心环节,写给那些想系统入局 AI 工程、而不是只会套模板调接口的人。
我会尽量少讲虚的,多讲我在实际项目里验证过的东西:哪些方案真的能落地,哪些环节最容易翻车,为什么 AI 工程不能照搬传统软件工程的套路。读完之后你能得到一套可以照着复现的思路,而不是一堆概念名词。
1. 先想清楚:AI Engineering 到底在解决什么问题
1.1 从"调接口"到"工程化"的关键转变
我见过太多团队,第一天接上大模型 API,第二天就觉得自己已经"AI 化了"。结果上线第一周就出问题:用户输入稍微绕一点,回答就开始胡说;并发一高,成本直接失控;换个模型版本,之前调好的效果全部作废。说白了,调用模型只是一个起点,AI Engineering 关注的是模型之外那一整套系统。
传统软件工程的核心是确定性:输入固定,逻辑固定,输出可预期。但 AI 系统的核心组件——大模型——是一个概率系统。同一个 prompt 跑十次,结果可能不完全一样;稍微改几个字,输出风格就变。这就导致一个根本性的转变:你没法用"测试用例全部通过"来定义质量,你要定义的是"在什么分布范围内表现良好"。
所以 AI 工程不是"会写 Python + 会调 OpenAI SDK"这么简单。它至少包含几层能力:第一层是模型能力的使用,包括 prompt 设计、上下文管理、工具调用;第二层是应用架构,包括 Agent 编排、记忆机制、多模型协作;第三层是质量保障,包括评测集建设、自动化测试、线上监控;第四层是成本和稳定性治理。四层缺了任何一层,你做的都只是一个 demo,不是一个工程。
1.2 为什么传统软件工程的思路不能直接搬
很多人觉得,我都有多年后端开发经验了,做 AI 不就多学一个 API 吗?实际落地之后你会发现,最大的挑战不是技术,而是思维方式。
传统开发里,bug 是确定性的错误,可以定位、可以修复、可以写回归测试。AI 系统里的"bug"往往是一种倾向性偏差——它不是每次都错,而是在某些输入分布下表现差。你说它错了,它有时候又能答对。这种问题没法靠"修一行代码"解决,只能靠调整数据分布、优化 prompt、增加约束机制来缓解。
还有一个容易被忽略的点:传统软件的复杂度主要在代码逻辑,AI 系统的复杂度主要在数据配置。模型的权重是黑盒,你能控制的只有输入组织方式、评测方式和交互流程。所以 AI 工程里,"配置"和"数据"的地位跟"代码"一样重要。我见过不少团队把大量精力花在调模型参数上,却连一份像样的评测集都没有,这属于典型的力气用错了地方。
提示:判断一个团队是不是真的在做 AI 工程,就看两件事——有没有成体系的评测集,有没有线上效果监控。两者都没有的,基本还停留在"调接口"阶段。
2. 从零起步:技术选型与基础架构搭建
2.1 模型选型:通用大模型与专用方案的取舍
从零开始做 AI 工程,第一道选择题就是用哪个模型。这个决定几乎影响后面所有环节,值得多花点时间。
市面上的选项大致分三类。第一类是商用大模型 API,优点是好坏可控、迭代不用自己管,缺点是成本会随调用量线性增长,而且数据要过第三方。第二类是开源模型自己部署,比如 Llama、Qwen 系列,优点是没有调用成本、数据不出内网,缺点是需要 GPU 资源和运维能力,效果调优的难度也更高。第三类是针对特定场景的专用模型或微调模型,适合瓶颈明确、数据量充足的场景。
我的建议是,除非有硬性的数据合规要求,否则起步阶段直接用商用 API 是最优解。为什么?因为你真正要验证的不是模型能力,而是产品和场景是否成立。用开源模型从头折腾部署和调优,消耗的时间成本足够你迭代好几个产品版本了。等到业务跑通、数据积累够了,再做模型层的替换或者私有化,那时候你才有足够的评测集来判断新模型到底行不行。
模型选型还有个容易被忽略的维度:不是所有任务都需要最强模型。我做过一个客服问答系统,90% 的问题比较简单,用轻量模型就能答好,只有 10% 的复杂问题需要大模型。如果一律用最强模型,成本是前一种方案的五六倍。合理做法是做模型路由:先让轻量模型处理大部分请求,拿不准的再升级到强模型。这一层工程优化,往往比你在 prompt 上抠半天效果还明显。
2.2 基础设施三件套:API 层、向量库、可观测系统
确定模型之后,基础架构其实比很多人想象的简单。我习惯分成三块:模型访问层、知识检索层、可观测层。
模型访问层要做的事是统一封装:不管底层用哪家模型,对外提供一致的接口规范。这一点特别重要,因为模型的厂商和版本是会换的。我在一个项目里就吃过亏:先用了厂商 A 的模型,代码里到处是厂商 A 特定的参数写法,后来换成厂商 B,改了整整两天。统一封装之后,换模型只改一个适配文件。
知识检索层是 RAG(检索增强生成)系统的基础。最早的 AI 应用都是"裸奔"的,直接把用户问题丢给模型。但涉及到私有知识或者时效性内容时,纯靠模型内部知识根本不够。RAG 的思路是:把文档切块、向量化、存进向量数据库,用户提问时先检索相关内容,再喂给模型生成答案。这套流程看着简单,实际坑非常多——切块大小、检索策略、排序逻辑都会直接影响效果,后面我会专门展开。
可观测层最容易被新手忽略。传统开发有日志、监控、链路追踪,AI 系统一样需要。而且 AI 系统多一个必须记录的东西:prompt 和模型输出。不记录下来,线上出了问题你连复现都无从下手。我在每个项目里都会要求,所有模型调用的输入输出必须落库,这是排查问题的底线。
2.3 入门技术栈参考
如果你正准备从零搭一套 AI 工程骨架,我给你列一个我实际用下来比较顺手的组合:
| 环节 | 常用选择 | 我的使用说明 |
|---|---|---|
| 开发语言 | Python / TypeScript | Python 生态最全,TypeScript 适合胶水层和前端联动 |
| 模型调用框架 | LangChain / LlamaIndex / 自研封装 | 框架可以帮助起步,但不能被框架绑死 |
| 向量数据库 | Milvus / Chroma / Qdrant | 数据量大用 Milvus,小项目直接 Chroma 起步 |
| Prompt 管理 | 代码仓库 + 版本管理 | 别用数据库存 prompt,要跟代码走 |
| 评测工具 | 自建脚本 / PromptFoo | 早期自建足够,后期可以引入框架 |
| 可观测 | Langfuse / 自建日志表 | 记录模型调用输入输出和耗时 |
注意:框架只是拐杖。我见过太多人用 LangChain 写了几千行抽象代码,结果一个简单的 prompt 调用被包了三层,出了问题都找不到日志。我的习惯是:框架用来快速验证,核心链路自己写。
3. Prompt Engineering:AI 工程的第一堂必修课
3.1 一个好 Prompt 的结构化写法
Prompt Engineering 是被讨论最多、也最容易被低估的一环。说它被低估,是因为很多人觉得"就是写段话嘛"。实际上,prompt 的好坏直接决定了模型能力的上限表现,而且它是 AI 工程里投入产出比最高的优化点。
我在团队里推行的是结构化 prompt 写法,核心要素有五个:角色设定、任务描述、输出约束、示例引导、边界声明。
角色设定不是花架子。让模型"你是一名资深法律顾问"跟直接问问题,效果差距很大,因为角色会激活不同的知识分布和表达风格。
任务描述要具体到"步骤级"。我常举一个例子:与其说"帮我分析这段文本的情感",不如说"请先判断文本整体情感倾向(正面/中性/负面),然后找出表达该情感的关键句子,引用原文,最后用不多于50个字解释你的判断依据"。任务拆得越细,模型的行为越可控。
输出约束是工程性最强的一部分。要 JSON 就必须告诉它严格的 JSON 结构,要长度限制就必须明确说"不超过200字",要格式就必须给出格式模板。模型不会主动猜你的心思,它只会按你给的信息最大化得分。这套逻辑跟数据库表结构设计很像——约束越清晰,数据质量越高。
示例引导(few-shot)是成本最高的优化手段。给两个好的示例,往往比在 prompt 里多写两百字描述更管用。示例最好是真实业务数据,而且要覆盖边界情况。比如做一个分类任务,你给的正例全是典型样本,模型就学不会怎么处理模糊样本。
3.2 上下文窗口管理:容易被忽略的隐蔽工程
很多人以为 prompt 写得越长越详细越好,这是大坑。模型有上下文窗口限制,而且窗口被无关信息占满之后,跟任务相关的注意力会被稀释,效果反而变差。这个现象行业内叫"Lost in the Middle",意思说模型对长上下文中间部分的信息记忆最差。
实际工程里,上下文管理要考虑三块内容怎么分地盘:系统提示词占多少、检索到的参考资料占多少、历史对话占多少。我的经验是,系统提示词控制在 1000 字以内,只放最重要的规则;参考资料要经过压缩,不是把整篇文章塞进去,而是只保留跟当前问题相关的段落;历史对话要设置滑动窗口,超过一定轮数就做摘要存储。
处理长对话时,我常用"摘要 + 窗口"的策略:每隔几轮对话,让模型把之前的对话生成一段摘要,存起来;下次请求时,把摘要加上最近几轮完整对话一起提交。这样既能保留背景信息,又不会让窗口无限膨胀。这个方案实现起来不复杂,但对对话类产品的体验提升非常明显。
3.3 Prompts 也要版本管理和测试
prompt 是代码,是产品逻辑的一部分,那它就应该有版本管理。我们团队现在的做法是:所有 prompt 以模板文件的形式放在代码仓库里,用 git 管理变更。prompt 改了之后必须跑一遍评测集,通过才能合入。这个流程一开始执行很难,因为大家嫌麻烦,但执行几个月后你会意识到它的价值——没有版本管理的 prompt 就是一个无人维护的黑洞,你不知道现在的效果是哪个版本产生的。
prompt 的评测跟代码测试不太一样。代码测试是断言输出等于预期值,prompt 评测是判断输出质量。我的做法分两级:第一级是硬性规则检查,用正则或字符串匹配校验关键信息是否存在、格式是否符合要求;第二级是语义评估,把模型输出和参考答案一起发给一个评估模型,让它打分或者判断好坏。两级结合,基本能覆盖大多数场景。
4. Agent 架构:从单一模型到复杂协作系统
4.1 Agent 的核心组成和设计思路
如果说 prompt engineering 是让模型回答得更准,那 Agent 工程就是让模型"做事情"。所谓 Agent,简单理解就是让大模型具备感知、决策、行动的能力:它能理解目标、决定下一步干什么、调用工具、观察结果、调整策略,直到完成整个任务。
Agent 的核心组件其实不难理解,主要是三块:大脑(大模型)、手(工具调用能力)、记忆(短期上下文和长期存储)。工程上真正难的是怎么把它们可靠地组织起来。
我自己做 Agent 系统的经验是,先把"确定性"和"智能性"分开。确定性的流程,比如固定步骤的审批、固定格式的调用,用代码硬写;不确定的决策,比如"这一步该用什么工具、下一步做什么",交给模型。很多人犯的错是让模型去处理所有事情,包括那些本来用两行代码就能搞定的逻辑,结果模型发挥不稳定,整个系统跟着飘。
工具调用是 Agent 工程的核心机制。现在主流模型都支持 function calling,也就是让模型输出一个结构化指令,指明要调用哪个函数、传什么参数,然后你的代码执行这个函数并把结果返回给模型。设计工具接口时要特别注意两点:工具的说明要写得足够清楚,包括什么时候用、参数含义、返回值结构;工具的粒度要适中,太大模型不好控制,太小则调用次数过多、既慢又有累计错误风险。
4.2 多 Agent 协作的几种实战模式
单 Agent 做不了太复杂的任务,这是我在实践中得到的结论。复杂任务要么拆成多步,要么拆成多角色。多 Agent 协作的常见模式有几种。
第一种是编排模式,一个主 Agent 负责理解用户需求,把任务拆解后分发给子 Agent,最后汇总结果。这种模式适合内容生成类任务,比如写行业报告:一个 Agent 做资料收集,一个 Agent 做数据分析,一个 Agent 负责撰写,一个 Agent 负责校对。
第二种是流水线模式,任务按固定顺序经过多个 Agent 处理。比如客服工单系统:先由分类 Agent 判断工单类型,然后由处理 Agent 给出解决方案,最后由质检 Agent 审核答案。这种模式的可控性强,每个环节都能单独评测和优化。
第三种是会商模式,多个 Agent 扮演不同角色对一个问题进行讨论,最终得出共识。这种模式适合需要多角度分析的场景,比如技术方案评审,让一个 Agent 扮演架构师、一个扮演运维、一个扮演安全专家,分别提意见。
多 Agent 协作的难点不在"把多个 Agent 串起来",而在怎么保证协作的效率和稳定性。每多一个 Agent,就多一层错误累积的可能。我的建议是:能用单 Agent 解决的就别上多 Agent;多 Agent 架构里,每个子 Agent 都要有独立的评测指标,否则你根本不知道是哪个环节拖累了整条链路。另外,不要所有消息都靠模型转发,Agent 之间的中间结果可以走结构化数据,只在需要语义判断时才调用模型。
4.3 Harness:把 Agent 关进可控制的笼子里
我这两年深有体会的一个概念是 harness——你可能在 AI 工程社区听到过它的名字,包括 "harness engineering" 的提法。这个词直译是"马具",在 Agent 工程里,它指的是把模型行为约束在一个可编程、可观测、可干预的框架内。
为什么需要 harness?因为大模型天然是不可控的。你问它一件任务,它有无数种方式去执行。如果没有约束,它可能调用错误的工具、按照错误的方式解析数据、甚至陷入循环出不来。harness 的思路就是给 Agent 套上一层工程骨架:规定好思考格式(比如必须输出结构化的"当前状态-下一步动作")、规定好可用工具集合、规定好输出格式和终止条件。
我做一个数据查询 Agent 的时候就深刻体会到了没有 harness 的恐怖。模型为了回答一个"上季度销售额"的问题,把数据库所有表都扫了一遍,调用了几十个函数,耗时好几分钟,最后还是答错了。加上 harness 之后,我先限定它能用的查询接口,强制它先输出查询计划再做执行,每一步都记录日志,超过 5 步主动终止并降级。结果任务成功率和响应时间都大幅改善。
用业内的话说,Agent 的能力是模型给的,但 Agent 的可靠性是 harness 给的。工程的重点不应该放在期待模型更聪明,而应该放在怎么约束和引导模型,让它的不稳定性被控制住。
5. 让 AI 系统可测试、可评估、可上线
5.1 评测集建设:先定义"好"再谈优化
AI 工程最核心的质量保障手段是评测集。没有评测集,你做的所有优化都是盲人摸象——你觉得 prompt 改好了,可能只是碰巧手上几个测试样例表现好,换个输入就露馅。
评测集的建设思路跟写单元测试很像,但有它自己的特点。我习惯把评测集分成几个层次:核心功能集,覆盖产品最主要的使用场景,保证基本盘不出错;边界情况集,覆盖模糊输入、空输入、超长输入、对抗性输入,专门用来测模型的防御能力;回归集,记录历史上修过的 bug,防止问题复发。
评测集的规模和标注质量比想象中更重要。我见过有人用几百条样例做评测就觉得自己覆盖得很全面,实际效果极不稳定。我的经验是,起步阶段至少准备 100-200 条高质量的标注数据,并且随着线上运行不断补充"真实用户输入"。这个数字看着不多,但标注要精细——每一条都要明确期望答案和评分标准。这不是一次性的工作,而是一个持续演进的资产。
评测执行也有讲究。早期可以用人工评,但到了后期,一定要引入自动化评估。常见的做法是用一个强模型当裁判,给模型输出打分。这里有个细节:裁判模型本身也可能有偏见,所以打分标准要写清楚,最好结合具体场景,比如"回答是否包含关键事实""是否给出明确行动建议"这种可判别的标准,而不是模糊的"回答质量好坏"。
5.2 AI 测试开发:自动化测试在智能系统里的应用
传统测试开发的经验在 AI 工程里不是没用,而是要升级。接口、单元、集成测试照样要做,但多了一层模型输出的测试。
这个场景业内也经常叫 AI 测试开发,核心逻辑是构建一套自动化测试流水线,在模型更新、prompt 修改、代码变更之后,自动跑评测集,输出质量报告。链路的重点是"变更必测"。
我实际落地的一套流程是这样的:代码仓库里放评测集和测试脚本,每次 prompt 模板或代码有变更,CI 流水线自动触发评估任务,把变更前后的结果对比,输出一份过拟合率(原有效果被破坏的比例)和改进率。比例不达标就不允许合并。这个流程虽然粗暴,但非常有效,它强制团队养成"每次改动都验证效果"的习惯。
自动化模型测试有个比较棘手的问题:模型输出不稳定。同样的输入和 prompt,今天跑和明天跑结果可能略有不同。所以 AI 测试不能只看一次结果,我一般每个用例跑 3-5 次,取多数结果来判断是否通过。这是一个详细但必要的细节,避免你被"输出不稳定导致的假性失败/成功"干扰判断。
5.3 上线之后的监控、反馈与迭代闭环
模型上线不是终点,是另一个起点。传统系统上线后监控的是错误率、延迟、负载;AI 系统除此之外,还要监控语义层面的质量指标。
线上监控我分成几个维度。第一个是硬指标:调用量、响应时间、Token 消耗、成本。Token 消耗尤其要关注,成本跟流量是线性关系,一个 prompt 设计不好,成本能翻好几倍。第二个是软指标:用户反馈,包括用户主动点踩、投诉、对话中断率。第三个是抽检指标:定期从线上日志里抽样,人工或者用模型评估回答质量,形成一个质量趋势线。
闭环迭代是 AI 工程是否成熟的分水岭。线上每天会积攒成千上万条真实用户输入,这些都是天然的评测数据。我要求团队每周从线上数据中挑出表现不好的案例,分析原因(是 prompt 问题、是知识缺失、还是检索不到相关内容),补进评测集,再针对性优化。这个轮子转起来之后,系统的效果会持续改善;转不起来的,效果就只能靠运气。
6. 常见问题与排查技巧实录
6.1 高频问题速查表
把这两三年遇到的典型问题整理成一份速查表,希望能帮你少踩一些我踩过的坑。
| 症状 | 常见原因 | 排查方法 |
|---|---|---|
| 回答时好时坏 | prompt 约束不够、模型版本不稳定 | 跑多次评测,检查 prompt 是否足够具体 |
| 回答偏长/偏短 | 输出约束缺失或无效 | 明确长度限制,用示例规范格式 |
| 回答与事实不符 | 知识时效性问题、检索遗漏 | 引入 RAG,对关键事实做验证 |
| 调用超时 | 一次生成太长、工具循环太多 | 限制 max_tokens、设置工具调用步数上限 |
| 成本飙升 | 上下文过大、模型选择不合理 | 做上下文压缩、启用模型路由 |
| 上线正常但一周后效果变化 | 模型方更新了底层版本 | 关注模型版本公告,维护固定版本或快速适配 |
| 检索内容不相关 | 切块策略不合理、检索匹配逻辑太简单 | 调整分块大小、引入重排序(rerank),补充召回策略 |
| 对话多轮后跑偏 | 历史管理缺失 | 做滑动窗口 + 历史摘要策略 |
6.2 我踩过的几个坑和避坑建议
第一个坑是过分迷信 prompt 万能论。早期我做智能客服,效果不好,第一时间就认为是 prompt 写得不够好,来回折腾角色设定和语气。后来才发现很多问题出在知识检索——模型根本没拿到正确的信息。做 AI 工程一定不要局限于一个环节,要系统诊断整条链路:是输入问题、检索问题、模型问题还是输出解析问题,逐步排查。
第二个坑是忽略输出解析的脆弱性。模型输出格式稍微变化,你的解析代码就崩。后来我学乖了,所有模型输出一律要求结构化格式,而且解析逻辑要写得宽容,兼容可能的格式偏差。实在无法保证时就用模型二次修正,把输出清洗一遍。
第三个坑是低估成本管理的价值。一个项目上线后我仔细核算过,发现每个月花在模型上的费用里,30% 都是无效消耗——比如把整份文档塞进上下文、反复调用大模型做简单的文本格式化。后来我们做了严格的 token 审计,把该省的都省下来,成本降了 40%。成本管理不是财务的事,是 AI 工程的核心工作之一。
第四个坑是数据隐私合规意识不足。处理用户数据时涉及敏感信息,一定要做脱敏和授权检查,尤其在使用第三方模型时,要明确数据边界。我在做企业项目时,凡是涉及客户核心数据的场景,一律用私有化部署或本地模型,这个红线不能碰。
6.3 思维模式的最后一点建议
从零开始做 AI 工程,最重要的不是学会某个具体工具,而是建立一套以"评测-迭代-监控"为核心的工程循环。模型本身会越来越强,工具会不断更新,但你建立的那套质量保障和数据闭环体系,才是真正跟随你的能力。
我个人在实际操作中的体会是,AI 工程跟传统软件工程最大的区别在于耐心。传统项目是部署上线就基本结束了,AI 项目恰好相反,部署上线之后真正的优化才刚开始。如果你接受了这个设定,把心态从"做成"调整成"持续做好",那些枯燥的评测、监控、迭代工作就不再是负担,而是系统效果越做越稳的底气来源。
有一点我想额外强调:在这个领域里,被裁减掉的风险永远高于被夸大低估的错误——宁可用最朴素的方案把质量做扎实,也不要盲目追逐最新框架让自己陷入失控。根据我的经验,那些能长期稳定运行的 AI 系统,往往不是用了最酷技术的,而是评测和监控做得最扎实的。希望这篇复盘能帮你少走点弯路。