
1. 为什么90%的AI项目都死在Demo到产品这条路上在AI这行干久了你会发现一个很残酷的现实Demo谁都能做产品不是谁都能做。我见过太多团队拿着一个跑通的对话Demo把PPT包装得天花乱墜结果一上生产环境就被用户真实的输入打回原形。模型的回答时好时坏、上下文一长就乱、同一个问题换个说法答案完全不一样——这些在演示时都不会暴露因为Demo里全是精心挑选的完美样本。我说的ai engineering from scratch指的不是从零写一个深度学习框架而是从零搭建一整套AI应用的工程化体系。从第一版提示词开始到模型选型、数据流设计、Agent编排、自动化测试、线上监控——把AI能力真正变成一个可信、可控、可维护的业务系统。这个过程中最大的挑战不是让模型回答问题而是让模型稳定地回答对问题。那工程化到底要解决什么我总结下来就四件事确定性让模型在合理范围内稳定输出而不是每次推理都像抽奖。可观测性模型为什么这么回答中间发生了什么出问题时能追溯。可迭代性换模型、改提示词、调参数之后怎么知道变好了还是变坏了。兜底能力模型出错时系统要有降级方案和安全边界而不是裸奔。如果你正准备从零开始做AI应用或者已经做完Demo但不知道怎么往产品方向推进这篇文章会把这四件事全部拆开讲清楚。我不讲那种加载LangChain跑一下Hello World的新手教程我讲的是我踩过坑之后沉淀下来的那套完整链路。2. 从需求到架构AI工程的第一张设计图应该怎么画2.1 模型选型的前提是够用就好不是越强越好很多人做AI工程的第一步就是选模型这是个陷阱。真正正确的顺序是先想清楚任务边界再倒推需要什么能力的模型。举个例子我做过一个企业内部知识库问答机器人。最初团队直接上了当时最强的通用大模型理由是大模型能力强什么都能答。结果上线两周就出问题了一是单次调用成本高得离谱二是知识库问答这种任务根本不需要模型具备写诗和写代码的能力三是大模型的泛知识反而会干扰它对内部文档的判断一本正经地编造出不存在的公司制度。后来我们把任务拆成三类文档检索用向量数据库召回、结构化抽取从文档里提取关键信息、自然语言生成把答案组织成流畅的表述。前两类完全可以用传统NLP工具加小模型搞定只有第三类才需要调用大模型。这么一拆大模型的调用量下降了70%成本和延迟都降下来了回答准确率反而提高了。模型选型时我建议你关注三个维度维度思考方式能力边界任务需要什么能力普通对话、复杂推理还是专业领域知识成本预算每日调用量乘以单次Token消耗再乘模型单价算完你就不纠结了延迟要求用户能接受几秒出结果这决定了模型参数量级和是否要用流式输出做这个决策有个很实用的办法先做人工标注。把50条真实业务问题整理出来人工写出标准答案再拿不同模型去跑人工打分对比。别迷信榜单分数榜单跑的是通用任务你的业务问题才有发言权。2.2 数据流设计你的AI系统每天在吃什么模型选完紧接着就是数据流。AI工程的数据流和传统软件不一样它的核心是上下文管理每一次模型调用你要喂给模型什么信息这些信息从哪来怎么拼装还是说知识库问答这个例子。用户问今年年假政策有没有变化系统需要做三件事从向量数据库检索出与年假政策最相关的3-5段文档切片把用户问题、检索回来的文档切片、历史对话摘要拼装成系统提示词设置温度参数我一般用0.1到0.3确保回答严谨、不发挥。这段链路听起来简单实际工程里最容易被忽略的是上下文窗口的管理。大模型的上下文窗口是有限的你不能把所有历史对话一股脑全塞进去。我的做法是维护一个三级缓存短期记忆最近5轮对话的原始内容直接放进上下文中期摘要每10轮对话结束后让模型把要点压缩成摘要放进系统提示词长期记忆用户画像、偏好等结构化工数据按需检索注入。这么设计的目的是在有限的上下文窗口里把最高价值的信息递给模型。很多项目上线后出现聊到第20句就胡言乱语的问题基本就是上下文管里堆了太多垃圾信息把真正关键的指令给稀释了。2.3 状态与可控性AI应用最容易忽视的地基传统工程里状态管理是好学生的必修课但到了AI工程里很多人反而把状态给扔了——他们觉得模型自己能理解一切。这是大忌。AI应用本质上是一个有状态的计算系统。用户说再解释一下第二点模型需要知道第二点指的是你上一轮回答里的第二个要点。如果每一轮调用都是无状态地独立发起这类指代问题模型就会瞎猜。所以工程上必须显式维护对话状态把用户意图、当前话题、待确认信息等结构化地存储下来在组装上下文时动态注入。这一点在Agent类应用里尤其致命。我后面会细说Agent编排这里先记住一个结论不要让模型去记忆状态要用代码去管理状态。模型负责理解和生成工程代码负责状态流转和持久化。这个分工一旦模糊你的AI系统就会变成一个不可预测的黑盒。3. 提示词工程从复制粘贴到可版本管理的工程资产3.1 提示词的模块化拆分提示词工程是AI工程里最容易被低估的一环。很多人觉得提示词就是写一段话让模型干活复制粘贴就完事了。但实际上只要提示词进入产品代码它就成了需要被版本管理、测试、迭代的软件资产。我自己的做法是把一个复杂的系统提示词拆成五个模块分别维护角色定义Role模型以什么身份回答问题。比如你是一名资深的HR政策客服回答必须基于提供的企业内部文档不得使用文档之外的信息。任务描述Task模型这一轮具体做什么。比如根据以下检索到的文档片段回答用户关于年假政策的问题。如果文档中没有相关信息明确告诉用户资料库中暂未找到相关内容。输入数据Data动态注入的文档片段、用户历史、查询结果等。这个部分不写死用占位符在运行时填充。输出约束Format规定输出格式和风格。比如回答需分点列出每条控制在50字以内严禁编造文档中不存在的内容使用简体中文。兜底指令Fallback当模型遇到不确定情况时的处理策略。比如如果你无法从文档中确定答案直接说不确定不要尝试猜测。这套拆分有两个好处。第一日常迭代时不用重写整段提示词只改对应模块就行第二每一个模块都可以单独做测试出了问题能精准定位是角色设定不够明确还是输入数据有问题。我见过太多人改提示词靠整体重写一次然后看运气改完发现A问题解决了B问题又冒出来了就是这个原因。3.2 Prompt版本管理与A/B实验模块化拆完之后提示词的版本管理就顺理成章了。我强烈建议你给每一版提示词打上版本号记录改动内容和变更原因就像管理代码一样管理Prompt。在我的项目里每条生产环境的提示词都对应一个JSON配置文件大致长这样{ prompt_id: hr_policy_answer_v3.2, modules: { role: 你是一名资深的HR政策客服..., task: 根据以下检索到的文档片段..., data: {{retrieved_docs}}\n用户问题{{user_query}}, format: 回答需分点列出每条控制在50字以内..., fallback: 如果你无法确定答案直接回答不确定... }, model: gpt-4o-mini, temperature: 0.2, updated_at: 2025-06-18T10:30:00Z, change_log: v3.2将兜底指令从可以说不知道改为直接说不确定减少模型过度解释 }配好之后每次提示词变更都走一次A/B实验把线上流量切一部分到新Prompt版本上对比新旧版本的程序化指标和人工抽评分数再决定是否全量上。这套机制看起来很重但它能让你的AI系统在持续迭代中保持稳定不会出现今天改了提示词明天线上效果崩了的尴尬。3.3 结构化输出让模型遵守你的数据契约提示词工程里另一个高频翻车点就是输出格式不稳定。你让模型返回JSON它偶尔给你夹一句好的以下是您需要的JSON格式答案把下游解析直接搞崩。解决这个问题的工程手段叫结构化输出约束也就是在调用API时告诉模型必须返回符合某个JSON Schema的数据。现在主流大模型的API基本都支持这个能力你只需要定义好Schema{ type: object, properties: { answer: { type: string, description: 对用户问题的直接回答 }, confidence: { type: number, description: 置信度0到1之间 }, need_human_handoff: { type: boolean, description: 是否需要转人工 } }, required: [answer, confidence, need_human_handoff] }配合这个Schema每次模型输出都是规规矩矩的JSON下游代码不用再做容错处理。这一步很值得做它把模型输出这个不确定事件变成了可解析的数据是AI工程确定性的关键一环。另外提醒一个细节结构化输出不等于模型理解了你的业务约束。它只是格式上合规了内容上可能还是错的。所以Schema解决的是解析崩溃问题内容正确性问题要靠评估体系去保障——这就是我后面要讲的重头戏。4. Agent编排让模型学会调用工具而不是背诵答案4.1 Agent的核心是工具与循环当你的AI应用不只是回答问题而是要完成任务比如帮用户查天气、订会议、提交工单那你就需要Agent了。Agent的本质是让模型具备使用外部工具的能力。做一个Agent工程上要做两件事定义工具集、编排推理循环。工具集就是一组可被模型调用的函数通过JSON描述它们的名称、参数和返回值。模型在对话过程中如果判断需要某个工具来完成用户需求就会输出一个工具调用请求由你的代码去实际执行再把执行结果回传给模型让它继续推理。这个模型思考 — 调用工具 — 拿到结果 — 继续思考的过程就是循环。以我做的工单Agent为例我给模型挂了三个工具[ { name: search_articles, description: 在知识库中搜索与用户问题相关的文档, parameters: { type: object, properties: { query: { type: string, description: 搜索关键词 }, top_k: { type: integer, description: 返回的文档数量 } }, required: [query] } }, { name: create_ticket, description: 为用户创建工单, parameters: { type: object, properties: { title: { type: string }, description: { type: string } }, required: [title, description] } } ]工具描述的质量直接决定了模型能不能正确调用。我调试过很多次发现工具描述里最关键的不是做什么而是什么情况下该用、什么情况下不该用。否则模型会乱调工具把应该直接回答的问题也去触发工单创建。4.2 循环控制与失败兜底Agent安全的第一道防线Agent的推理循环给了模型极大的自由度也让系统面临失控风险。你见过Agent触发工具调用后进入死循环吗我见过。一个工具执行结果没达到模型预期于是它反复调用把API配额刷爆了。这就是行业里常说的循环工程问题——Agent循环不是让模型无限转圈工程上必须对循环过程做硬性约束。我的做法是两个参数最大循环次数和单次工具调用超时时间。循环次数一般设3到5次超过就强制让模型基于已有信息做最终回答工具调用超时设定为10到20秒超时后直接抛出可读的错误提示。另一个关键点是失败兜底。工具调用可能失败、可能返回异常数据、可能超时你的Agent系统要把这些失败场景当成正常业务路径来设计工具调用失败把错误信息回传给模型让模型决定重试还是换一种方式模型连续两次循环没有进展中断循环输出我暂时无法完成这个任务已为你转接人工用户输入涉及敏感操作如删除数据、大额转账Agent拦截并转人工确认。这些兜底逻辑不该写在提示词里让模型自觉遵守而应该用代码在Agent执行层面硬性拦截。模型是概率系统让它承担安全职责显然不靠谱。4.3 从单Agent到多Agent协作分工与上下文隔离做完单Agent你很快会遇到单Agent的能力瓶颈一个Agent既要负责理解用户意图又要负责检索知识还要负责生成最终答案即使模型能力再强任务变复杂之后也会出现顾此失彼的局面。于是多Agent协作就登场了——让多个专精的Agent各管一摊配合完成复杂任务。我在实际项目里用一个主控Agent 多个专家Agent的架构主控Agent负责理解用户整体意图将任务拆解路由给对应的专家Agent检索Agent只负责查文档、返回检索结果工单Agent只负责创建和更新工单质检Agent负责审核最终回复是否有事实错误。多个Agent之间如何协作这比单Agent复杂得多。我的经验是不要让Agent之间直接对话而是通过共享的工作记忆来协作。主控Agent把任务上下文写入一个结构化的共享缓冲区专家Agent只读取与自己相关的部分产出结果后写回。这么做的好处是上下文隔离——每个Agent只看到自己需要的信息既节省Token又不会因为无关上下文干扰专家Agent的判断。这里还有一个容易踩的坑多Agent的调用成本是成倍增加的。我做过多Agent架构后单次完整对话的成本从约0.02美元涨到了0.08美元翻了4倍。所以设计时要考虑清楚是不是所有任务都需要全流程的多Agent协作。我后来加了一条分流规则简单问答直接走单Agent快速通道只有需要工具调用或多步骤推理的复杂任务才走多Agent协作链路。这么一改成本又降回了一半。5. 多AI协作的调度问题让模型团队高效运转5.1 什么样的任务才需要多AI协作多AI协作不是把一堆模型往系统里一扔就完事。它要解决的真正问题是异构模型的调度——不同任务交给不同能力的模型再把各自的结果合并加工。举例来说我的知识库问答系统同时使用了三个模型一个小参数模型负责意图识别和任务分类一个中等参数模型负责常规的文档问答一个强推理模型只在用户问复杂对比分析时才会被调用。三者按任务难度分流形成一条推理成本梯度。这种设计背后的逻辑很简单用户问公司年假有几天和小模型就能答好没必要动用强推理模型但用户问如果把入职时间从9月改到7月年假额度怎么变化这类需要多步计算的问题小模型就容易出错这时候才值得花更高成本调用强模型。实际做的时候任务分类的准确率至关重要。分发错了要么多花钱要么答错题。我建议在分流层做一次轻量级校验——用第二个模型或规则引擎对路由结果做个快速确认发现拿不准的任务就默认走强模型通道宁可多花成本也不能答错。5.2 协作的三种模式路由、编排与协商我梳理下来多AI协作的常用模式大概有三种模式一路由分发。根据输入内容把任务分给最合适的单一模型处理。这是最轻量的模式适合不同任务类型有不同最佳模型的场景。模式二流水线编排。任务按固定顺序经过多个模型前一个模型的输出是后一个模型的输入。典型场景是先做意图识别再做检索最后生成回答。这种模式链路稳定适合处理流程相对固定的业务。模式三协商合并。多个模型对同一问题各自产出结果再由一个汇总模型或投票机制选择最优答案。成本最高但确实能提升回答质量。一般只在高价值场景使用比如医疗咨询、法律建议这类容错率极低的输出。实际工程中三种模式经常混用。我的建议是先按业务逻辑画出任务流程图再为每个节点选择模型。这条规则听起来简单但极有用——因为一旦动辄让所有模型大乱炖你连问题出在哪都定位不到。6. 测试、评估与监控AI工程的生死线6.1 给LLM写自动化测试不是只测能跑通AI工程的测试和传统软件的测试有本质区别。传统软件测试断言函数返回了预期值AI测试断言答案在可接受范围内——这个可接受范围需要人先定义清楚。我给AI应用搭建测试体系时先做了三件事第一建回归测试集。从真实业务中挑选200条代表性输入覆盖常见问题、边界情况、历史踩坑问题手工标注理想回答。每条数据都记录为什么选这条理想结果是什么未来提示词或模型的任何变更都要先过这200条回归测试。第二定义评估指标。纯人工评估一天看不了几个样本必须有程序化指标辅助。以下是我常用的几个指标指标计算方式适用场景回答相关性用另一个模型或余弦相似度计算回答与标准答案的接近程度快速筛选明显不合格的回复事实一致性用另一个模型检查回答是否与提供的文档内容矛盾防幻觉、防编造格式合规率生成的JSON能否被解析字段是否齐全保障下游链路稳定性端到端成功率整个Agent流程中用户目标是否在N步内达成Agent类应用最核心的指标第三把评估变成CI/CD的一环。我搭过一套这样的流程每次修改Prompt或更换模型自动跑一遍互联网问答测试集生成对比报告。那些感觉新Prompt更好的模糊判断在这个报告面前瞬间真相大白。很多次我直觉以为新版效果不错结果一看回归报告老版本在几十个边界案例上处理得更好果断回滚。6.2 LLM-as-a-Judge用一个模型给另一个模型打分LLM-as-a-Judge是我强烈推荐每个AI工程团队上手的一个方法。它指的是用一个模型充当评审员对被测模型的回答进行质量评分。听起来有点套娃但实测下来效果很可靠特别是用于做大面积的初筛。实践中要注意几个细节评审模型与被评模型最好不同厂商避免自卖自夸的偏差给评审模型明确的评分标准考卷rubric比如分4个维度各1-5分总分取加权平均每批评审结果抽样20%做人工复核防止评审模型自身的偏好带偏整体评估。我的经验是LLM-as-a-Judge能帮你把全量人工评测的工作量压缩到原来的20%剩下那20%人工方式重点盯——这就够了。6.3 上线后的监控模型也会漂移你的AI应用上线后千万别觉得万事大吉。模型推理会随着时间有性能漂移业务数据变化、用户输入分布变化、模型服务端更新任一环节出问题线上效果就会悄悄退化。我搭建的监控体系分三层请求日志层记录每一次调用的输入、输出、耗时、费用和模型版本作为后续分析的原始素材质量指标层每天跑一批评估任务计算事实一致性、格式合规率等指标检测质量滑坡的早期信号业务结果层跟踪最终业务指标——比如用户是否真的解答了问题、工单创建成功率等。这一层才是老板真正关心的。监控的黄金法则是把异常报警接到IM上。现在我的团队每天都能收到一份质量日报指标正常就静默一有滑坡立刻报警并附上趋势曲线。这比出了问题靠用户投诉反馈要主动得多。关于质量监控还有一个容易忽略的点成本监控。大模型的API计费是按Token走的你的Agent如果循环失控或者多Agent协作频繁触发强模型调用成本可能直接翻几倍。我一直用实时费用面板跟踪每次请求的消耗设置日费用阈值超了自动切换降级模型。很多人把成本问题留到月底账单出来才意识到那个时侯就晚了。7. 最后的几点实在话走到这里AI工程化的主线闭环已经完整了——从模型选型、数据流设计到提示词管理再到Agent编排、多模型调度最后用测试和监控兜住质量与成本。我自己走完这一圈最大的体会是AI工程不像传统软件开发有标准答案可抄它更像是在概率系统和工程确定性之间不停找平衡。几个经验送给你做AI工程一定要有敬畏心。模型不是你插件里的一个黑盒它的每一次输出都是概率采样工程上必须假设它会出错来做设计。你的任务不是让它永不犯错而是让它犯错时可发现、可控制、可回退。把AI应用当真正的软件工程来对待。单元测试、版本管理、Code Review、CI/CD这些传统软件工程的老手艺在AI工程里一样都不能少只是评估标准从对不对变成了好不好。最后持续拥抱变化。这个领域的技术栈更新速度极快模型能力、编排框架、评估工具每隔几个月就会换代一批。别指望一套架构用一年不动你要做的是把工程骨架搭得足够稳健——评估体系、监控体系、数据链路这些底层设施永远不过时换掉的只是模型和框架本身。我踩过的那些坑就是活教材愿你少走弯路。