说实话,第一次看到“ai-engineering-from-scratch”这个项目名时,我脑子里最先浮现的不是某条提示词,而是过去一年多带着团队从一个“能跑通的Notebook”走到“敢让客户直接使用”的线上AI系统的全过程。很多人以为大模型时代的工程起点是写Prompt,终点是效果还不错。但真正把一个AI想法变成稳定、可评估、可维护的工程,中间隔着大量没人写进PPT的细节:数据从哪来、结果怎么验、模型升级后会不会退步、成本涨上去谁来兜底。这篇文章想聊的就是我理解的AI Engineering——从零开始,到底该先想清楚什么,先动手做什么,以及哪些坑几乎人人都会踩一遍。
这个内容适合所有人看:后端工程师想转型做AI应用,产品经理想搞明白团队该招什么人,算法工程师想把模型真正部署上线,独立开发者想低成本跑通第一个Agent。不同基础的人都能在这篇文章里找到自己的切入点。
1. 先分清两类事:大模型应用开发与AI工程的本质差异
1.1 为什么很多“惊艳Demo”最终死在工程细节上
我见过太多项目死在同一个环节:第一天,模型回答惊艳全场;第二周,领导要求上线;第二个月,用户开始反馈“有时候抽风”;第三个月,项目被悄悄降级。问题从来不在模型本身,而在模型之外的那些“普通工程问题”。
一个只跑通一次的Notebook,和一个每天被调用上千次的线上服务,需求完全不同。前者只需要回答一次正确,后者要求每次回答都稳定、可复现、出错时有兜底、效果退步时能报警。你拿起ChatGPT的页面觉得问答很顺畅,但等到自己接API时,会发现下面有一整层没人替你操心的事:输入校验、上下文管理、超时重试、白名单过滤、成本控制、日志追踪……这些全都属于AI工程的范畴。
我自己的经历也一样。早期做一个文档问答系统,模型在测试集上准确率高达95%,我以为稳了,结果一上线就露馅。用户上传的文档格式五花八门,有扫描件、有表格、有乱排版的PDF,预处理脚本连续崩了三回;用户问法稍复杂,模型就开始把上下文里不相干的公司名当成答案输出;还有一次某位用户上传了一份大文件,单次请求的Token费用直接让人心疼了一整天。那段时间我最大的感受是:模型负责“聪明”,工程负责“可靠”,而用户最终买的不是聪明,是可靠。
1.2 AI工程横跨的四层结构:模型、应用、数据与平台
做久了你会发现,AI工程从来不是单点问题,而是四层结构的联动。
第一层是模型层,包括模型选型、微调、量化、提示词优化。第二层是应用层,包括业务逻辑、Agent编排、工具调用、记忆管理。第三层是数据层,包括知识库切片、评估集构建、用户反馈回流、数据清洗。第四层是平台层,包括部署、监控、日志、权限、成本与安全。
很多从零开始的团队只看到了第一层,觉得选个好模型就成功了。实际上,越往上走,越往底层走,工作量越大。甚至可以说,当模型能力已经够用的情况下,真正的差异化都发生在应用层、数据层和平台层。用一句话总结:模型决定一个系统的能力上限,工程决定它能不能稳定达到这个上限。
1.3 适合读这篇文章的人
- 后端工程师:你已经熟练掌握了接口、数据库、部署,现在想接入大模型能力,但不知道从哪里切入。
- 产品经理或项目负责人:你需要判断一个AI需求是“做个Demo”还是“做成产品”,两者投入差距可能是十倍。
- 算法工程师:你想把自己训练的模型或调好的Prompt真正部署出去,但对工程侧的成本、监控、回归体系还不够熟悉。
- 独立开发者/自由职业者:你想用AI做点小工具或自动化流程,但不想一上来就被各种Agent框架绕晕。
如果你属于其中任何一类,我觉得这篇东西能帮你少走三个月弯路。
2. 从0到1的切入顺序:先选场景,再定架构,最后才写代码
2.1 场景选择的三个刹车阀:别选开放度太高、别选单次任务太重、别选误判代价太大
刚开始接触AI工程的人最容易犯的错误,是看到什么火就做什么。比如“我要做一个通用AI助手”——这个场景的开放度太高,用户问什么都有可能,系统需要处理的知识面和价值观冲突是无限的,一个人没有足够资源和数据根本撑不起来。
我的建议是给场景踩三脚刹车,缺一不可。第一,任务边界必须清晰,输入输出要有明确的契约。比如“客户留言分类”就比“帮助客户解决任何问题”好实现得多。第二,单次任务不能太沉重,不要让模型在一轮交互里完成一个需要二三十步推理的复杂任务,至少第一版不要。第三,误判代价必须可控。AI出错后带来的后果如果是灾难性的,那么即使技术再诱人,第一版也建议在旁边加一个“人工确认”的开关。
我自己做的第一个AI工程实践项目,是一个内部工单分类器。输入是工单描述,输出是几个预定义的分类和优先级。场景窄、任务轻、误判最多被同事纠正一下,非常合适练手。后来我才慢慢加到自动回复、知识检索、Agent协作这些复杂环节。
2.2 把任务拆成“可验收的颗粒度”
进入实现之前,我会先做任务拆解。不是拆技术模块,而是拆业务步骤。举个例子,假设你想做一个“自动生成招聘JD”的工具,如果直接对模型说“帮我写一份Java工程师JD”,输出会很泛。但如果你把任务拆成四步:第一步,收集岗位基本信息;第二步,生成职责列表;第三步,生成任职资格;第四步,组合成完整JD并做格式校验。每一步都有明确输入和输出,每一步都能单独验收。
这种拆法有两个好处。第一,中间任何一步出错,你都知道错在哪里,而不是面对一整段坏掉的输出发呆。第二,你可以在业务规则的层面给每个步骤加约束,比如职责不超过六条、任职资格必须包含学历要求、薪资范围不能为空。这些约束写进业务代码,比写进提示词更可靠。记住一句话:凡是能用代码确定的,就不要让模型自由发挥。
2.3 什么样的需求真正需要Agent框架
现在Agent概念非常火,但很多需求根本用不着Agent。我的判断标准很简单:流程是固定的,用固定Pipeline;流程需要动态决策才用Agent。所谓动态决策,就是下一步做什么取决于当前这一步的结果,无法事先写成死逻辑。比如你要让系统先搜索资料、再判断资料是否充足、不足的话换关键词重新搜索,这类循环决策才需要Agent。
如果流程是“第一步取数据,第二步交给模型,第三步格式化输出”,那就老老实实写代码编排,不要硬套LangChain或其它框架。项目的维护成本和模型输出的不确定性已经够多了,现代工程里的框架依赖能少一个是一个。
2.4 第一版架构越简单越好:先跑通,再优化
我见过不少项目,第一版就设计成微服务网格加消息队列加向量数据库集群,结果两个月过去了,核心链路还没有完整跑通过一次。正确的做法是,第一版用最简单的单体结构:一个API入口,一段调度代码,一个模型接口,一个结果存储。所有模块先串起来,打上日志,跑通一条主流程。等流量和复杂度真的上来了,再谈拆分、再谈队列、再谈分布式。
这条原则怎么强调都不为过。AI工程本身就比传统后端多了一层不确定性,如果底层架构再不稳定,出了问题根本分不清是模型的问题还是代码的问题。我之前就有一次,排查一个响应超时的Bug,花了一个下午,最后发现是消息队列消费被一条脏数据阻塞了。这种问题放在单体结构里,一分钟就能定位。
3. 整条工程链路上,真正要做的四件事:约束、拆解、记忆与调用
3.1 提示词的本质是“约束契约”,不是“话术技巧”
英文社区现在有个词叫harness engineering,翻译过来就是给模型套缰绳。我越来越认同这个思路:提示词工程的真正目标不是让模型“发挥更多创意”,而是让模型的输出在既定范围内保持稳定。
一套好的生产级提示词,应该像一份契约,至少包含五个要素:角色定位、任务目标、输入格式、输出约束、边界条件。输出约束尤其重要,包括输出格式是JSON还是Markdown、字段名是什么、不能输出哪些内容、信息不足时该说什么。边界条件则是告诉模型“如果你不知道,就承认不知道”,这句话能救回大量幻觉问题。
我在实际项目里习惯把提示词模板放在单独的文件里,用版本号管理起来。每次上线新功能,只改提示词文件,不改调用代码,这样后面出了问题还能快速回退。记住一个原则:提示词应该像代码一样被审查、被测试、被记录变更。它是什么时候改的、为什么改、影响面有多大,都要有迹可循。
3.2 Agent的循环机制:Plan-Act-Observe与人工兜底
真正做Agent时,第一步要理解的不只是“怎么调用模型”,而是循环机制。一个标准Agent循环是Plan(计划)—Act(行动)—Observe(观察)—重复,直到满足终止条件。工程上要处理的核心问题有三个:循环的终止条件是什么?循环超过最大次数怎么办?同一步被重复执行了怎么办?
我在一个自动信息查询Agent里遇到的坑非常典型:Agent需要调用搜索工具查资料,但某次搜索出的页面内容不完整,它就把同一句query原封不动提交了七八次,白白烧掉大量Token。后来我在循环里加了去重逻辑:每一步行动之前,先检查这个动作是否已经执行过,如果执行过且结果相同,就强制切换策略,而不是重试同一路径。同时设置全球最大轮数,到点强制结束,转入人工。
另外,我需要强调人工兜底。生产环境里的Agent必须设计“人在回路上”的节点,尤其是涉及对外发送消息、修改数据、付款这类高风险动作时,Agent只能做“草稿”和“建议”,最终由人点击确认。这不是不信任模型,而是工程上对责任边界的必要保护。
3.3 记忆不是装“存档”,而是工程上的状态管理
Agent领域聊“记忆”时,大家第一个想到的是向量数据库。但我在工程里更愿意把记忆看作状态管理,分三种来设计。
短期记忆,就是当前对话上下文,直接放在内存或请求结构里,控制长度,超出就截断或摘要。长期记忆,是跨会话的用户偏好、历史结论,适合存结构化数据库,按用户维度查询。语义记忆,才是向量检索,适合把文档切片向量化后做相似召回。
这三者的优先级很清楚:能用结构化字段表示的,不要丢给向量库;能用规则算出来的,不要让模型“记着”。我在一个客服助手项目里,最开始时把所有历史对话都塞进向量库里,每次请求召回几千个字丢给模型,效果好了一点点,成本翻了好几倍。后来我把用户ID、会员等级、订单状态这类信息单独建表,走普通SQL查询,向量库里只留真正需要语义匹配的FAQ片段,成本立刻降下来两成多,效果反而更稳定。
3.4 工具调用的权限边界与失败恢复
让模型调用工具之前,先想清楚两个问题:它能调用哪些工具?工具返回异常时系统该怎么办?权限边界的原则是最小够用:一个只负责查询天气的Agent,就不应该拥有查询用户手机号的权限。工具层要做双层校验,第一层在请求进入时校验资质,第二层在模型声明要调用某个工具时再次校验。防止提示词注入导致模型“骗”系统去执行高危操作。
失败恢复同样关键。工具调用一定会失败,网络超时、参数格式错误、返回数据解析失败,这些都是常态。在生产级代码里,我会给每个工具调用包一层超时控制、重试策略和异常捕获,并给模型一个标准化的错误格式,让它能读懂并决定下一步是重新尝试、换一种方式还是直接告诉用户“暂时查不到”。如果模型连续失败三次,就停止循环并把上下文保留下来,转交人工跟进。
3.5 多AI协作的两种实用形态
多AI协作是现在讨论比较多的方向,我的观点是:协作是手段,不是目的。在实际工程中,两种形态比较实用。
第一种是流水线模式,A模型负责生成初稿,B模型负责检查并返回修改意见,A根据意见修改。这种模式适合“写文章—查错—改写”的场景,好处是分工明确。第二种是主持人加执行者模式,一个调度模型负责理解任务、拆解子任务、分发给多个领域子Agent执行,最后汇总结果。这种模式适合“用户提一个跨领域问题,需要不同知识库组装答案”的场景。
但我要泼一点冷水:多数多AI协作项目失败,不是模型能力不够,而是状态管理失控。各个模型都要共享同一份上下文,上下文一长,大模型就会互相干扰、遗忘甚至“篡改”信息。工程上的解法是,各模型尽量使用结构化协议通信,比如执行者只返回固定JSON,不要返回长篇自由文本;主持人只读取结构化结果,不要看到原始上下文。把对话空间缩小,错误率会显著下降。
4. 从Demo走向生产的四道关:评估、成本、可观测性与回归
4.1 没有评估体系的LLM应用,就是没上保险的汽车
我见过太多AI项目只有一个模糊的目标:“效果差不多就行”。这句话在Demo阶段没问题,但到了生产环境,项目负责人说不清“好”的定义,就无法验收,无法迭代,更无法防止模型悄悄变坏。
我的建议是,项目启动时就要定义离线评估集。不需要很大,三五百条真实需求就够第一版用。每条样本包含输入、预期行为关键词、判定规则。比如客服场景,可以标注“该提问是否被正确识别为退款意图”,“回答里是否包含退款政策链接”,“回答中是否出现敏感承诺”。这些判定规则越具体,评估越靠谱。
上线后还要定义在线指标:首响耗时、调用成功率、用户反馈率、人工升级率、单次成本。我习惯用一张表把这些指标钉起来,每次迭代对比,谁动了数字谁负责解释。
4.2 成本拆分:输入、输出、缓存、重试与模型路由
大模型应用的成本极容易被低估,因为单价看着不贵,但日积月累非常可观。计算单次调用成本,基本公式是:输入Token数×输入单价加上输出Token数×输出单价。如果你的系统还有重试逻辑,还要乘以重试次数。
控制成本有四个实用抓手。第一是精简上下文,只把任务相关的信息塞给模型,而不是把整个聊天记录全送进去。第二是做缓存,对重复度高的请求直接命中缓存,不进模型。第三是模型路由,简单任务走小模型或快模型,复杂任务才用大模型;比如意图识别这种任务,不需要每次都动用顶尖推理模型。第四是控制输出长度,不需要长回答的场景就限制max_tokens,防止模型废话连篇。这四个抓手同时上,成本通常能降到原来的三分之一到一半。
4.3 可观测性:把“黑盒”变成“灰盒”
传统后端可以通过日志和链路追踪快速定位问题,但AI应用多了一层模型判断的不可控,所以观测体系要再多记两类信息:模型相关和业务相关。
工程上每个请求都要生成一个trace_id,贯穿入口、模型调用、工具调用、结果输出全过程。日志里要记录prompt的版本号、使用的模型名、温度参数、输入Token数、输出Token数、耗时、模型的原始返回值,以及业务侧的最终返回结果。一旦用户反馈有问题,一枚trace_id就能还原整条链路。
我自己会把模型的每次输出都简单打标,比如“命中关键词库”“经规则校验通过”“存在幻觉嫌疑,触发人工复核”。这些标记看起来粗糙,却能在模型升级或提示词修改时,迅速看出异常行为在哪个环节爆发。
4.4 回归测试与灰度上线的日常操作
大模型应用非常容易“好了这个、坏了那个”,今天把回答改得更活泼了,明天它就把注意事项忘了。所以每次修改Prompt或切换模型,都要走一遍回归测试。我称之为“黄金数据集每日巡检”,把核心场景的输入全跑一遍,比对关键行为是否正确。
更严谨一些的团队,会做灰度发布:新Prompt或新模型先切给5%到10%的流量,跑两天,对比在线指标和历史数据。如果准确率和成本都正常,再逐步扩大到全量。如果异常,立刻回退到旧版本。这条流程不需要很重的平台支撑,一个开关加几张对比表就能实现。
我团队里一次模型升级事故,就是靠这个机制兜住的。新模型在离线评估集上各项指标都更好,我轻声放到灰度链路里之后,发现有一类特定问题的回答风格突变,用户社区开始出现抱怨帖。靠灰度对比及时发现,回退后影响面很小,事后分析才发现是模型安全对齐策略不同导致的风格漂移。
5. 踩过的那些生产地雷:选型陷阱、版本污染、幻觉失控与安全红线
5.1 模型选型里的锚定效应与换型成本
不少团队一上来就选当前榜单上最强的模型,理由是“反正能力强,总能满足需求”。这个想法的代价通常要等到月底账单和用户投诉时才会看清。在实际业务里,强模型未必比“够用模型”强在业务指标上,但成本通常是后者的十倍以上。
我建议做一次模型基准测试:把黄金评估集合跑到不同模型上,比准确率、忠实率、单次成本、响应速度四个维度,最后画一张高低配对比表。你很可能发现,简单意图分类用中档模型就够了,只有复杂推理任务才需要最强模型。另外要提早意识到,换模型的代价很高,不仅是接口适配,更麻烦的是输出分布会变,很多Prompt要重新调。所以选型不是想换就换,更要选一个长期能托底的底座。
5.2 提示词版本管理:Git、评估集与Eval脚本三件套
现在很多团队做AI工程,把Prompt直接写在代码里,想改就改,改完也不知道改了哪里,上线后效果变差了也不知道是哪个改动导致的。我呼吁每个人把提示词当作一等公民来管理,独立成文件,放进Git仓库,提交信息写明原因。
和提示词配套的,是评估集和Eval脚本。没有评估集的Prompt改动,在我看来就是无证驾驶。我会先跑一遍离线对比,确认没变坏,再上灰度。每次发布Prompt变更,在执行记录里留下commit号,这样线上如果出了异常,可以直接通过日志定位到当时用的哪个版本的提示词。这套习惯形成后,项目的稳定性会有质的提升。
5.3 幻觉的工程化处理:不是消灭,而是拦截与兜底
必须承认一个现实:大模型的幻觉无法被彻底消灭,只能通过工程手段控制和降低。我在生成式任务里最常用的拦截手段有三道。第一道是防火墙,在Prompt里明确限定“只能基于给定资料回答”,并在代码里限制上下文只有已检索的资料。第二道是来源校验,要求模型回答时必须附带来源编号,没有来源编号的内容一票否决。第三道是规则抽检,在回答输出前用正则或分类器快速检查是否包含“可能有问题”的表态,比如数值、日期、名称,如果检测到关键实体浮动,就强制降级为“信息不足,建议人工确认”。
当然,最有效的兜底是允许模型说“我不确定”。这个能力在纯生成模型里天生较弱,所以我在任务设计阶段就会给用户一个“人工介入”的明确出口。邮箱、工单、联系电话,关键时刻要能接得住。
5.4 看不见的安全红线:数据、权限与合规底线
AI应用的安全问题比传统后端更隐蔽。第一个是企业数据,我把所有用户请求送到外部模型API前,都会做脱敏处理,姓名、手机号、身份证号等实体先替换成占位符,返回结果再还原。第二个是权限纵深,模型拿到的是“加工后的数据视图”,而不是底层数据库的真实结构,这样即便发生提示词注入,攻击者也无法探测数据资产全貌。第三个是内容合规,输出侧要有关键词过滤器和敏感内容识别机制,避免模型生成不合适的内容流向用户。
这些工作在Demo里可以被忽略,但一旦进入生产,就是硬要求。我在早期接一个知识库项目时,因为赶进度跳过了文件上传的白名单过滤,结果有用户传了一个含恶意脚本的文档,差点把内部系统的Cookie带走。那次之后我才真正明白:再聪明的模型也代替不了基础的安全工程。
6. 个人与小型团队从零起步的路径,以及我的几条实操建议
6.1 三个月自学路线:从写Prompt到部署一个Agent
如果你目前是单兵作战,建议给自己三个月的时间,按阶段推进。第一个月,先别写框架,直接调模型API,读官方文档,把提示词写扎实,同时建立自己的迷你评估集,每天跑一个指标。第二个月,学会让模型调工具,从写一个能联网搜索并总结的小程序开始,然后逐步增加超时、重试、去重、Terminate条件。第三个月,开始关注部署和运维层面的内容:把服务封装成接口,加上日志和trace_id,配上监控告警,最后做一个性能压测和成本预算表。
这个路径我走了半年才理顺,现在回看其实还能更快,核心就是要“边跑边接触真实数据”。真实用户反馈比任何技术教程都更能教会你什么叫AI工程。
6.2 给三种人群的差异化建议:后端、产品与算法
如果你本身是后端工程师,请发挥你在服务编排和稳定性上的优势,先不要迷恋Prompt技巧,多花时间设计清晰的输入输出契约和监控体系。你的加分项是,能把AI能力无缝埋进已有系统。
如果你做产品经理,请先把精力放在用户任务边界和“误判代价”的定义上,多问“这个AI代替用户做了哪一步,错了会怎样”,少问“能不能生成得更惊艳”。一个把场景限制做得很准的产品,比一个看起来炫酷但不稳定的Demo离落地更近。
如果你是算法工程师,建议你尽快补工程课,重点学数据库、缓存、队列、容错这四样。很多算法出身的人会过度关注“如何让模型更聪明”,但我看到的大量问题其实出在“工程接不住模型”:服务一压就挂了、失败重试把成本烧穿了、日志不完整没法定位问题。这些地方才是真正的分水岭。
6.3 几条提升整条链路效率的实操技巧
最后分享几个我在大量项目里沉淀下来的小习惯,不一定惊天动地,但屡试不爽。
第一,每次修改提示词或调整模型,都在保存变更的同时跑一遍黄金评估集,跑完把结果贴到群里或评论里。没有评估结果的变更请求,不要上线。第二,所有模型输出在下发前都要过一道规则校验器,校验通过才发,校验不通过就进入备选分支。哪怕规则只有三条,也能拦截大多数低级错误。第三,给Agent循环设置一个“定期汇报”机制,不是让它汇报给用户,而是汇报给系统日志,这样一旦循环异常,你能第一时间从日志里看到它卡在哪个行动上。
我个人实际体验里价值最大的一条是:从第一天起就把提示词版本号、模型名、评估结果、线上指标四者绑定到一条线上。每次上线前都问自己一句——“如果这个改动在线上出了问题,我能靠哪条日志在十分钟内回滚到准确版本?”如果回答不上来,说明观测还不完整,继续补齐了再上。
从零开始做AI工程,最怕的不是不会用某个框架,而是不知道自己在做工程。模型在变、框架在换、热词在轮转,但“定义好边界、拆分好任务、建立好观测、控制好成本、兜住底”这五件事,无论哪一轮技术浪潮到来,都依然是AI工程的骨架。你能把它们做扎实,AI工程这扇门就算真正打开了。