
1. 项目概述为什么我从零开始搭建AI工程链路我是在一次内部工具开发中意识到这个问题的。团队里所有人都能跑通大模型API、都能写出一段还不错的Prompt但一旦涉及“这个功能能不能上线”“效果怎么评估”“模型换版本了会不会崩”整个讨论就开始含糊。市面上不缺AI教程缺的是从零到一、按工程标准把AI应用搭起来的方法论。这也是我做“ai-engineering-from-scratch”这个项目的初衷——不依赖任何封装好的低代码平台不跳过任何一个关键环节用最朴素的工程手段把一套完整的大模型应用从零搭出来。这个项目能解决什么问题它解决的是很多人“只会调接口、不会做系统”的尴尬。举个具体场景你想做一个智能客服不只需要接一个大模型的API还需要考虑知识库怎么切分、用户问题怎么改写、模型回答怎么裁剪、超时和成本怎么控制、效果怎么回归验证。这些全都是工程问题而不是模型问题。项目从需求分析、技术方案选型、数据准备、提示词设计、评估体系、部署监控一路走下来覆盖的正是这条完整链路。适合谁来看两类人最适合。一类是刚接触大模型应用开发、想建立正确工程观的技术人员你可以照着项目把流程跑一遍形成自己的框架另一类是已经在做AI应用但总感觉“差一口气”的人你缺的往往不是模型能力而是工程化手段这个项目里踩坑和补课的记录正好能对上你的困惑。我选择“from scratch”这个角度还有个深层原因封装好的框架确实快但会让你失去对细节的掌控感。你用完LangChain可能依然说不清Chain内部到底做了什么、为什么会失败。自己从零写一遍哪怕只实现最基础的功能你对整个系统的理解都会完全不一样。这个认知差异在真正的生产环境中会直接体现在你排障的速度和方案设计的质量上。2. 核心思路拆解AI工程不是堆模型而是做系统2.1 先搞清楚AI工程和传统软件工程的差异传统软件工程的输入输出是确定的一个函数传进去什么参数就返回什么结果逻辑可以被测试用例完整覆盖。而AI应用的核心推理环节是一个概率系统同样的输入可能产生不同的输出甚至可能产生错误输出但表现形式非常“像样”。这个本质差异决定了你没法用传统的测试方式来验证AI应用。我现在做项目规划时会把AI系统拆成三个层次来看基础设施层模型API、向量数据库、缓存、对象存储这些是相对确定的组件编排层提示词模板、工具调用、上下文管理、知识库检索这层开始出现不确定性交互层用户输入、流式输出、反馈收集、人工介入这层的不确定性最大。每一层都要有独立的容错策略。比如基础设施层要考虑模型服务不可用时的降级方案编排层要考虑检索结果为空时怎么回复交互层要考虑用户连续追问时怎么维护上下文状态。传统软件工程关注的是“逻辑正确性”AI工程还得额外关注“输出安全性”“成本合理性”“体验一致性”。2.2 技术选型背后的决策逻辑这个项目里我做的第一个重要选型决策是不直接使用重型编排框架。很多人在项目一开始就引入LangChain或LlamaIndex我建议你先hold住。不用的原因不是这些框架不好而是它们把太多细节藏起来了。你拿LangChain搭一个RAG链路可能二十分钟就搞定但之后出了问题你很难定位是Embedding的问题、还是向量检索参数的问题、还是Prompt拼接的问题。我见过太多团队把时间浪费在“框架行为猜测”上而不是花在“业务效果优化”上。我的做法是用原生代码做一层薄的封装。核心链路就几个函数文档加载、文本切分、向量化、检索、拼接上下文、调用模型、解析输出。每个函数都可以单独测试、单独调优、单独加日志。等你把这条路跑通了再去对比LangChain的实现你会瞬间看懂它替你做了什么也更容易判断什么时候该用框架、什么时候该自己写。模型选型方面我遵循的原则是“任务复杂度匹配模型规模”。能做分类的就不做生成能用小模型解决的就不上大模型。比如用户意图识别如果类别有限我倾向用embedding加规则匹配而不是每次都调用一个千人规模的模型去“理解”。延迟和成本在生产环境中是实打实的指标不能只盯着效果看。2.3 从需求到AI方案的路径规划很多人拿到需求就直接开始写Prompt这是最大的误区。我现在的流程是四步走第一步把需求翻译成“输入-输出-约束”三元组。输入是什么格式、可能有哪些变化输出是什么结构、给谁看约束有哪些——实时性要求、成本上限、合规要求第二步判断这个问题是否真的需要大模型。如果传统规则能覆盖80%的场景就先做一套兜底规则再用大模型处理剩下的长尾。这个思路在真实项目中非常实用因为规则系统稳定且便宜大模型处理的是规则覆盖不了的灵活场景。第三步定义评估指标。这一步必须在写代码之前做而不是之后补。我会先把“好回答”和“坏回答”的样子定义出来用一批真实样例固定下来作为后续迭代的基准。第四步才是方案设计和编码。如果你前三步做扎实了到这一步通常是水到渠成的事。这个路径帮我避过很多坑。最典型的是需求方一开始说“做一个智能问答”你如果不往深了问“答错了会怎样”“用户问的问题大概在什么范围”“回答的格式有没有要求”你做出什么他们都可能不满意。需求澄清的过程在AI项目里比在传统项目里更重要因为模型可调的方向太多了方向不对的努力全白费。3. 核心环节实操RAG链路、提示词工程与Agent设计3.1 知识库构建切分策略决定检索质量RAG检索增强生成是当前AI工程中最常用也最容易被做砸的模式。我见过不少团队向量数据库换上最贵的、Embedding模型也选最新的但回答效果依然不理想。问题往往出在文本切分这个最不起眼的环节。文本切分的目标不是“切成固定长度”而是“切出语义完整的单元”。我用过固定chunk_size500的切法结果一句话被从中间截断检索出来了也看不懂。后来改成按段落边界加滑动窗口的混合策略情况好了很多。我目前在项目中用的切分规则是优先按标题结构切Markdown的##、###HTML的h1-h3保留标题信息作为上下文段落过长时再按句子边界二次切分单块大小控制在300到800字之间相邻块之间保留20%的重叠避免关键信息正好落在切缝上每块都附带来源信息、标题路径便于回答时引用。这套策略我用一万多字的内部文档测过检索出来的内容相关性明显提升。切分这个活看起来简单其实值得反复调。你如果拿PDF测试还要考虑表格、页眉页脚、多栏布局的影响往往需要单独做解析和清洗。向量化也是一步讲究的工程。选择Embedding模型时我建议拿你自己领域的语料做个小规模检索测试看结果在top-k中的命中率不要只看模型榜单上的分数。榜单分数高不代表在你的领域里表现就好尤其是专业术语多、表达方式独特的场景。我踩过的坑是用通用模型向量化医疗术语文档检索“空腹血糖”完全匹配不上“FPG”这种缩写表达后来加了同义词扩展才解决。3.2 提示词设计结构化输出的工程化技巧提示词工程在这个项目里占了很重要的篇幅因为它是你与模型交互的主要界面。我总结了一套自己的写法核心思路是把提示词当成接口协议来设计而不是当成聊天文案来写。具体来说一个生产级提示词至少包含五个部分角色与目标模型以什么身份、完成什么目标输入数据说明输入是什么结构、可能有哪些边界情况输出格式约束JSON结构、字段说明、枚举值范围限制条件什么不许做、超纲怎么回应示例少量高质量示例尤其是反例。我写过一个客服场景的提示词输出要求是严格的JSON。如果没有格式约束模型偶尔会输出纯文本或者Markdown下游解析就会崩。加了JSON Schema描述和示例之后解析成功率从91%提到了接近100%。注意这里不是要求模型“严格遵守”而是你需要在提示词里把结构描述得足够清楚还要在代码层做二次校验和修复。另外一个关键工程手段是给模型“不知道”的权利。很多Prompt写得不好会强迫模型在不确定时强行编造。我在实际项目中会明确加上一句“如果你不确定请直接说明不知道不要猜测”。这句话看起来简单却能大幅度降低幻觉问题。配合知识库检索的置信度判断我做过一个测试回答准确率从78%提升到了86%。提示词迭代要遵循“一次只改一个变量”的原则。我见过有人一次改了角色描述、输出格式、示例、限制条件四个地方效果差了却不知道是哪个改动导致的。正确的做法是用版本号管理提示词每次只动一个维度用固定的测试集跑效果对比。这个习惯养成之后提示词优化就不再是“玄学”而是可追踪、可回退的工程过程。3.3 Agent设计工具调用的状态机思维Agent智能体是AI工程中更有挑战性的一块因为它从“单次问答”扩展到了“多步任务执行”。我设计Agent时最核心的理念是不要让模型自由发挥而是给它铺一条轨道。我实现了一个轻量级Agent框架核心组件包括任务规划器接收用户请求拆解为子任务列表工具注册表维护可用工具的描述、入参结构、调用方式执行引擎按规划器输出逐步执行每步把结果反馈给模型状态管理器维护上下文历史、中间结果、重试次数。最容易出问题的是“让模型自己决定下一步做什么”这个环节。模型可能会调用一个不存在的工具名、传错参数类型、或者在已经拿到答案之后还在循环调用工具。我的解法是在工具调用环节加一层校验器模型输出的工具调用先过一遍JSON Schema校验不合法就反馈错误信息让模型重新生成执行结果也会被截断和格式化后再交回模型上下文。这里我强烈建议用状态机的思维来管理Agent生命周期。我把Agent的状态定义为初始化、规划中、执行中、等待用户输入、完成、失败。每个状态都有明确的进入条件和退出条件有全局超时控制有最大执行步数限制。这样即使模型行为不可控整个流程还是在工程可控的范围之内。工具调用测试要格外用心。我在项目中给每个工具都做了单独的模拟器和真实的沙箱环境先离线测通再去真实环境跑。工具越复杂比如改数据库、发邮件越要警惕不可逆操作。我的经验是在生产环境禁用具有写权限的工具或者至少增加确认机制。3.4 上下文管理窗口有限但信息要够大模型的上下文窗口虽然是越来越大了但“能容纳”和“用得对”是两回事。上下文窗口中每加一段信息模型的处理时间、成本、注意力分散风险都在增加。上下文管理的核心是把对当前任务最有用的信息放在最重要的位置把不相关的信息果断丢掉。我实现了一个分层的上下文管理策略短时记忆当前轮次的对话历史和中间结果始终保留工作记忆与当前任务直接相关的检索结果、工具输出有容量上限长时记忆用户画像、历史偏好、领域知识按需摘要加载总结记忆当对话历史超过阈值时用模型做摘要压缩。用这种分层方式我测试过一个多轮对话场景用户连续修改需求五次前四次的细节不可能全部放进窗口但通过逐步摘要Agent依然能准确记住用户的最终意图不会因为早期信息的丢弃而出错。做这个功能要舍得花摘要的API调用费用它比你配置更大的上下文窗口便宜得多。4. 效果评估与性能调优拿数据说话不靠感觉4.1 建立离线评估集AI工程的“单元测试”在传统软件开发中没有单元测试你不敢重构在AI工程中没有评估集你不敢改Prompt、不敢换模型、不敢动检索参数。我建评估集的原则是“真实优先、反馈闭环”。我从用户的真实日志中抽样覆盖以下类型常见问题高频问题必须是多数边界问题空输入、超长输入、多语言混杂困难问题需要多步推理、跨文档查询拒答问题不该回答的内容测试模型是否会越界每个样本要标注标准答案和关键评分点。评分不只用“对/错”而是多维度的正确性信息是否准确、完整性是否漏了要点、相关性是否答非所问、格式合规性是否是要求的输出结构、安全性是否产生不当内容。评估的方式可以用模型打分也可以用人工评审我建议两者结合模型打分做日常回归每周抽一批做人工盲评。盲评很关键因为模型打分偏好和人类真实感受有偏差你不定期校准就会跑偏。4.2 在线监控指标准确率之外的三座大山到了线上环境单纯看回答质量已经不够你需要一套可量化的监控体系。除了常规的响应时延和错误率我在项目中重点监控以下三类指标第一是成本指标。大模型应用的成本是可变的随用户输入长度、输出长度、检索次数波动。我按“每千次会话成本”来做预算管理这个指标能直观反映你的系统是否被恶意刷量、是否某些用户的请求路径异常复杂。第二是空回答率与兜底率。系统有多少比例的请求没找到知识库内容有多少比例的回复是“我不确定”这些指标上升通常意味着知识库覆盖不足或检索质量下降需要及时补充资料。第三是用户反馈数据。线上要埋点收集“赞/踩”和“追问/离开”行为。用户如果追问往往代表第一轮回答没能解决他的问题这是比显式差评更丰富的信号。把这些信号回填到评估集里就形成了一个持续优化的闭环。4.3 性能调优从“能用”到“好用”的路径在项目进入到打磨阶段后性能调优主要围绕三件事延迟、成功率和效果一致性。延迟优化方面我推荐三个手段流式输出优先用户首字延迟大幅降低对复杂请求做任务并行比如先并发检索多个知识库再合并结果模型选择降级简单问题走小模型快速通道复杂问题才路由到大模型。这套组合拳一般能把体感延迟降低一半以上。成功率方面要重点做输入校验和异常恢复。输入超长就截断或者摘要输出格式不对就自动修正一次模型超时就重试且切换备用模型。每加一道防护线上成功率都能提高零点几个百分点。效果一致性是我特别想强调的。相同的问题不同时间问回答风格可能飘一会儿详细一会儿简略一会儿用列表一会儿用段落。我的做法是在提示词中固定回答风格偏好比如“回答控制在200字以内先给出结论再补充理由”同时在输出后做规范校验不符合就直接重生成一次。一致性直接影响用户信任感这一块值得扣细节。5. 部署上线与踩坑实录那些文档里不会写的事5.1 从开发到生产配置管理与安全基线AI应用部署上线与传统服务相比多了一层麻烦你不仅要管理代码版本和配置还要管理提示词版本、模型版本、Embedding版本。这三个版本的组合不一致系统行为就会千差万别。我在生产环境中采用了一套管理方案每一个线上请求都在日志中记录当时的提示词版本号和模型版本号。这样就算模型厂商改了底层行为这种事并不少见你也能精确定位到是“哪一次更新导致效果波动”。需要注意模型版本这东西不是你自己能锁定的在线API随时可能悄悄升级所以要做效果基线监控每周跑一遍标准测试集发现指标波动及时跟进。安全方面有几个容易被忽视的细节系统提示词可能被用户通过Prompt注入套取。我在用户输入进入上下文之前做一轮转义和截断并且提示词中明确标注“以下内容来自用户可能不可信”日志中不能记录用户的敏感信息。我在开发环境可以随意打印上下文但生产环境必须对输入输出做脱敏处理尤其是身份证、手机号、地址这类数据API密钥必须使用独立的密钥管理服务不能出现在代码库中哪怕是私有仓库也保不准哪天泄露。5.2 我踩过的五个坑和排查路径这个项目从零到一遇到的坑比预期多得多。我整理了最有代表性的五个每个都花了不少时间排查第一个坑是向量检索的“方言问题”。用户提问用词与文档用词不一致Embedding匹配不上。排查了很久才发现不是代码问题是语料覆盖问题。解决办法是在切分阶段加入领域同义词表同时增加一条扩写链路把用户问题先做一次改写再检索。第二个坑是上下文被“毒化”。系统跑了一段时间后用户多轮对话的中间内容中混入了错误信息导致后续回答全部走偏。排查后发现是上下文管理只加不减旧信息在窗口里堆着干扰了模型注意力。修复方式是引入了对话回合级别的相关性过滤和过期淘汰机制。第三个坑是模型输出格式的“幽灵空格”。模型返回的JSON有时会被Markdown代码块包裹有时在字段名里多出空格下游解析偶尔失败。排查后发现不能用简单字符串匹配来解析后面改成先提取代码块、再修复JSON语法、最后用Schema校验三层处理这个组合方案上线后解析失败率几乎降为零。第四个坑是超时重试引发的重复写入。一次工具调用超时客户端重试结果工具实际上执行成功了导致数据库里出现重复记录。这个问题很经典需要在工具层实现幂等控制用请求ID做去重。排查过程中我还顺带发现了流式输出场景下的“半截回答”问题——用户页面显示了一半就断掉后来加上断线重连和补偿机制才解决。第五个坑是评估集和线上数据分布不一致。离线评估集的指标很好上线后用户实际体验却一般。原因是评估集是团队成员写的用词正式、意图明确线上用户提问随意、口语化严重。解决方法是增加线上日志回流到评估集的机制保证评估数据分布和真实流量靠拢这个机制建立后离线指标和线上体验才开始对齐。5.3 成本控制与模型降级的实践经验大模型应用跑在真实流量上成本会以你想象不到的速度攀升。我在项目中有几个屡试不爽的成本控制手段第一是缓存策略。相同的用户问题在短时间内重复出现直接命中缓存不调用模型。我的实现是用Embedding近邻匹配做语义缓存设置24小时过期缓存命中率在客服场景能到15%左右对应成本能省下一成多。第二是Prompt瘦身。生产环境下在每轮对话里都塞长篇系统提示词成本和时间都在隐性地增加。我把一些“一次性说明”挪到首次交互时以用户可见的方式说明尽量保持系统提示词精简。实验下来提示词从1200字减到600字对回答质量几乎没有影响但token消耗少了将近三成。第三是任务拆分时的模型分级。一个复杂的分析任务我拆成多个子步骤简单子步骤用小型模型只有最终综合和深度推理才用大模型。这个策略在生产环境跑下来总计成本降了40%多效果基本不受影响。6. 经验总结与可复用的行动清单这个项目做下来我最大的感受是AI工程的核心竞争力不在“会调模型”而在“能控制不确定性”。模型行为有随机性但你的工程手段可以把随机性限制在可控范围里。提示词可以写得很灵活但必须有版本、有测试、有回滚机制检索可以做得很快但必须有评估指标和监控告警Agent可以做得很智能但必须有状态管理和权限边界。另外一个很深的体会是AI工程的成效取决于“反馈闭环”的运转速度。你改了一版提示词需要评估集告诉你效果变好还是变差你换了一种切分策略需要检索命中率告诉你值不值得你上了新模型版本需要线上监控告诉你有没有回归。闭环越快迭代越快系统的成熟度也就越高。那些“跑起来就不管了”的应用过了三个月往往已经悄悄变得不可用原因就是反馈闭环断了。如果你想从这个项目里带走最关键的三件事我会总结为先用离线评估集锁定基线再动手优化任何改动要有版本记录和回滚方案线上和离线的效果指标必须打通形成闭环。这三件事听起来不酷但它们才是AI应用真正能落地的基石。最后再分享一个小技巧在你开始写代码之前先手工模拟一遍完整的用户旅程。拿你准备做给用户的AI应用自己扮演用户手动在纸上走一遍流程记录每一步需要的输入、期待的返回结果、可能的失败点。这个动作看似原始但在项目前期能帮你发现大量需求理解偏差。AI工程和传统工程一样需求理解的偏差在后期修正的成本是最高的前期的“笨功夫”是最划算的投资。