ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从零搭建AI工程链路:四层架构与全流程实战复盘

从零搭建AI工程链路:四层架构与全流程实战复盘 去年我给自己定了一个稍微有点“自虐”的目标不买现成的AI编排平台套餐不套用那些“三分钟搭建智能助手”的缝合教程也不直接把开源框架一把梭拉起来就完事而是从零开始亲手把一整套AI工程链路从模型调用写到数据管道再到部署监控。这个持续了几个月、反复推翻重来的项目我最后整理成了一个开源仓库名字就叫ai-engineering-from-scratch。今天这篇文章就是对这个项目的一次完整复盘。先说这个项目解决的问题。很多想进入大模型应用开发的人都会撞上一堵墙单个API调用的示例看得懂向量数据库的快速入门也跑得通但一旦要把“文档处理 向量检索 模型调用 工具执行 会话管理 部署监控”串成一条完整链路就不知道从哪里下手了。网上到处是零碎的知识点真正缺的是一张能指导你按顺序落地的主线地图。ai-engineering-from-scratch就是我的那张地图现在把它分享出来希望给同样在AI工程这条路上摸索的朋友省下几个月的试错时间。这篇文章适合三类人刚转行的工程师、在校学生以及已经写了多年业务代码、想系统性地往AI应用方向靠拢的后端开发者。1. AI工程的切入点做能交付的系统而不是只会调接口1.1 为什么我把重心放在“工程”而不是“算法”开始动手之前我先把“AI工程”和“AI算法”这两件事彻底分开了。算法工程师的日常是跟模型训练、损失函数、评测指标打交道研究的核心是“怎么让模型在某个任务上表现更好”。而AI工程要回答的是另一组问题模型能力已经达标的情况下怎么稳定地对外提供服务怎么控制成本怎么在模型抽风的时候降级兜底怎么让业务方能够方便地接入我自己更倾向于后者因为“工程能力”在大模型应用时代变得比以往更重要了。你让一个训练过千亿参数模型的算法专家去上线一个客服问答机器人他未必比你更快解决“用户问了一个超大知识库之外的问题系统该返回什么”这种落地难题。今天的AI应用不再是“训练一个模型、部署一个接口”那么简单而是数据怎么进、知识怎么组织、工具怎么编排、上下文怎么管理、异常怎么恢复这一整套系统工程。所以这个项目从一开始就定下了基调一切以可交付、可运行、可维护为标准而不是以“用了多先进的模型”为标准。每一阶段的产出物都必须是一个能跑、能测试、能被别人使用的东西而不是一段孤零零的示例代码。1.2 “from scratch”的真正含义不是重复造轮子很多人一听“from scratch”就以为是要拒绝所有现成工具从矩阵乘法开始手写神经网络那纯粹是误解而且是很低效的误解。我的做法恰好相反成熟的基础设施比如向量数据库底层、模型SDK、Web框架我照用不误。真正“从零开始”的是架构决策和应用层逻辑比如为什么选择这套分块策略而不是那套为什么用这种召回方案而不是更炫酷的方案上下文应该怎么管理工具调用失败以后应该走什么流程。这里面的核心区别在于你有没有能力在“换掉一个组件”的情况下依然保住整条链路的可用性。如果你只是照着教程把某个全家桶跑起来那你学到的是“这个框架的点击顺序”一旦上游API涨价、模型失效、数据格式变化你会瞬间失去迭代能力。而如果你亲手把每个环节的逻辑都写过一遍哪怕写得粗糙你也拥有了定位问题、替换组件、重新组合的能力。后者才是工程能力的本质也是整个项目想要训练的东西。2. 顶层设计把AI工程拆成一张四层可执行地图2.1 一张图理解AI应用链路数据、记忆、工具、交互做知识库问答也好做客服机器人也好做AI编程助手也好剥开外壳几乎所有大模型应用共享同一套底层骨架。我把它简化成四个层次这也是ai-engineering-from-scratch项目的第一层设计原则。第一层是数据层。你要回答用户的问题总得有知识来源。这一层解决的是原始文档从哪里来怎么清洗怎么切分怎么向量化怎么存储。第二层是记忆层。多轮对话不是每次都把用户上一句话单独拿去检索而是要有会话级记忆和长期记忆让模型在上下文里看到“之前聊过什么”。第三层是工具层。模型不能只输出文字还要能真正执行动作查天气、查库存、发工单、调另一个系统的API。这一层要解决函数定义、参数提取、执行结果回填。第四层是交互与部署层。这层把前面三个层包起来对外提供一个稳定的HTTP接口内部处理超时、重试、限流、日志、成本统计。用开餐厅来类比数据层是采购和备菜记忆层是记熟客偏好工具层是后厨的锅碗瓢盆和炉灶交互与部署层就是前台接待和店面运营。只学一层开不了店每层都通才能把一个AI应用从想法变成别人真正能用的东西。2.2 四个阶段的产出物与验收标准为了避免陷入“一直在学习、永远不交付”的陷阱我给项目设定了非常明确的阶段划分和验收标准。每个阶段结束的时候都必须有一个看得见、摸得着的产出物并且要通过预先定义好的验收测试。阶段核心内容核心产出物验收标准阶段一模型接入、提示词管理、结构化输出一个支持多模型切换的问答脚本10个测试问题全部返回合法JSON阶段二文档切分、向量化、混合检索一个本地知识库问答服务针对自有文档的20个问题召回命中率≥80%阶段三工具调用、多轮记忆、智能体编排一个能调用工具并记住上下文的工作台连续10轮对话不丢失关键信息工具调用成功率达90%阶段四服务封装、监控、成本估算、降级方案一个带日志的HTTP服务连续运行72小时无内存泄漏单次请求延迟低于3秒这里面的每一个验收标准都不是随便写的。比如阶段二里面“召回命中率≥80%”这个指标不是看模型输出好不好而是看检索层能不能在用户说完问题之后从几千个文本块里把真正有用的几段拎出来。如果你的检索质量不够后面模型再强也白搭。这种验收思路贯穿整个项目保证每个阶段都有明确的目标感。2.3 为什么按“应用链路”组织而不是按“技术栈”组织刚开始设计这个项目时我差点走回传统学习路径的老路Python 语法、机器学习基础、深度学习框架、部署工具……一条线学下来学完前四章已经忘了第一章。后来我意识到问题不在于知识本身而在于组织方式。按技术栈学习的问题是知识点之间没有一条“业务主线”把它们串联起来你学到的是一个个孤立的概念而不是一个完整的系统。按应用链路组织就完全不一样了第一个阶段带你走通“用户提问 - 模型回答”的最小闭环第二个阶段加入知识库第三个阶段加入工具和记忆第四个阶段让它生产化。每加一块都是在前一块的基础上做增量而且是站在一个已经能跑的系统中加增量。这样做还有一个额外好处每个阶段结束你手里都有一个可以拿来演示、拿来给别人看的半成品。这种正反馈对维持长线学习的动力非常重要。我自己就是在第二个阶段做完之后第一次敢在朋友面前演示“问我任何关于这本技术书的问题”那一刻的成就感比学完十节网课都来得真实。3. 从零跑通一条AI应用链路的实操复盘3.1 第一阶段从API接入到稳定的JSON输出整个项目的第一步没有选复杂的架构就是把“一个大模型接口”用起来。这个阶段的核心目标非常朴素写一个Python脚本把用户的自然语言问题发给模型再把模型返回的内容解析成结构化的JSON同时保证在模型返回格式漂移的情况下程序不会直接崩溃。我当时做的第一件事是搭好本地环境用一个统一的配置管理文件维护接口地址、密钥和默认参数。在这个阶段我强烈建议所有接口参数都要显式写出来而不是依赖SDK的默认值因为不同提供方的默认行为差异很大。举个实际例子有的接口默认开启流式输出有的默认关闭有的模型默认温度是0.7有的则是1.0。这些细微差别在单次调用时无感进入批量测试后会被迅速放大。这个阶段的真正难点不在“调通接口”而在“拿到干净的、解析不出错的JSON输出”。大模型的输出本质上是概率生成的文本即便你要求它返回JSON它也可能带上几句解释、前后缀或Markdown标记导致直接json.loads失败。我的处理方案是三步走第一在系统提示词中明确“只输出JSON对象不要任何其他文字”第二对返回结果做清理使用正则去掉可能的代码块包裹第三设置重试机制解析失败时让模型按照错误信息自我修正一次。这里有一个从实战中得到的体会不要指望模型一次就输出完美结果要做容错设计而不是追求完美的提示词。提示词写得再好模型也可能犯傻但容错做得好用户就感知不到模型犯傻。这个思路贯穿了整个项目的始终。3.2 第二阶段手工搭建RAG链路把文档变成可检索的知识第二阶段是整个项目里最磨人、也是收获最大的一个阶段。目标是给模型装上“长期记忆”——让它可以基于你提供的文档回答问题而不是只靠训练时的知识。这就是现在到处都在讲的RAG检索增强生成。我没有直接使用某个开箱即用的RAG框架而是亲手把整条链路拆开文档加载、文本清洗、切分、向量化、存储、召回、重排、注入Prompt。每一步都自己写哪怕写得简陋也必须知道原理。最大的坑出现在文本切分这一步这也是我强烈建议每个做RAG的人都要亲手试错的地方。一开始我图省事按固定的500个字符硬切结果把一个完整的技术名词从中间劈开把一个表格拆得七零八落最后召回回来的文本块信息残缺模型回答的质量惨不忍睹。后面我改成了“按段落语义切分优先保留标题上下文”并在切分时让文本块之间保留少量重叠才把召回质量拉回来。向量化环节也有个容易忽略的细节嵌入模型的选择要和检索文本的语言、领域匹配。如果知识库主要是中文技术文档直接用英文通用嵌入模型效果会差不少。我当时在一个开源中文嵌入模型和一个商业接口之间做了对比测试发现开源模型的准确率在技术文档场景下反而更高原因是它对中文专业术语的分词粒度更友好。整个阶段我坚持做了一件事给检索环节建立了一个小的“人工测试集”打比方就是给搜索引擎准备了一套“标准考题”包含20个问题每个问题标注了正确答案应该出现在哪个文档片段里。每调整一次切分参数或嵌入模型就用这套题跑一遍记录召回命中率。没有这个测试集你就会陷入“感觉好了一点又不知道哪里好了一点”的混沌状态。3.3 第三阶段给AI助手装工具、加记忆从聊天变成干活如果说前面两个阶段做的是“让AI更懂知识”那第三阶段做的就是“让AI真的能办事”。这里说的“办事”是指它不止回答你的问题还能根据你的指令去调用外部系统的API比如查天气、查汇率、查库存、发工单。这一步的核心是函数调用function calling。你需要把每个外部能力描述成一个带参数的函数包括函数的名字、用途说明、参数列表和参数类型然后把函数列表一起发给模型。模型在理解用户意图后会返回一个结构化的指令告诉你它想调用哪个函数、参数是什么。你的代码再去真正执行这个函数把结果回传给模型让它基于真实结果生成最终回答。我实际做的第一个工具是“根据城市名查询当前天气”。这个例子看起来简单但完整走一遍所有工具调用的底层逻辑就都通了。让我印象最深的一个细节是函数描述里的“用途说明”直接决定模型会不会调用错工具。例如如果你写“查询一个城市的天气”模型在任何跟天气沾边的问题上都会倾向于调用它但如果你写“查询一个城市当天的实时气温数据来自本地气象站接口仅支持国内主要城市”模型就知道这个工具有限定的适用范围问题超出范围时会向你反馈而不是硬调。多轮记忆是这阶段另一个绕不开的技术点。一开始我把所有历史消息一股脑塞给模型很快就把上下文窗口塞爆了花钱多、响应慢而且模型会被无关信息干扰。后来我做了两级记忆短期记忆保存最近几轮的关键对话长期记忆则把重要的用户偏好写入向量库需要时检索回来。这个设计后来帮我省下了大量token也让对话质量提升明显。3.4 第四阶段封装成服务解决超时、重试与可观测性到第三个阶段结束时运行脚本已经能完成很多工作了但离“可以被别人当作服务使用”还差得远。第四个阶段要解决的是工程化中最不性感但最要命的环节服务封装和运维保障。我把核心逻辑封装成了一个FastAPI应用对外提供两个接口一个用于单轮问答一个用于多轮会话。内部做了这几件必须做的事第一所有外部接口调用统一走异步方式避免慢请求阻塞整体线程第二给所有请求加上超时控制和重试机制避免模型接口偶发抖动时直接抛错给用户第三引入结构化日志记录每次请求的耗时、token消耗量、命中的文档片段、调用的工具还有最终的回答结果。在这个阶段日志比模型本身更值得投入时间。原因很简单模型是一个概率系统你没办法保证它每次的行为都一致所以必须通过日志去复盘“为什么这次回答这么差”——到底是检索没召回还是召回后模型没答好又或者是工具执行出错。没有日志你面对一个表现不稳定的系统就只能靠猜来调优那是最痛苦的状态。最后我还补了一个平时很少被提及但非常关键的设计降级方案。我设定了两种情况一是向量数据库不可用降级为不带知识库的普通对话模式二是大模型接口超时降级为返回一个明确的“当前服务繁忙请稍候重试”的固定文本。这个设计看起来简单但在真实生产环境里它可能比花大价钱优化模型效果更能保住业务体验。4. 工具链选型与学习节奏少而精手动优先4.1 尽量用最少的工具把每一层都手动拧一遍整个项目做下来我在工具选型上坚持了一条原则必须能用最简工具链完成的绝不上重型框架。这样做的原因不是“不用框架显得厉害”而是当你手动实现一次之后再去看框架文档你会一下子明白它里面的很多参数设置到底在解决什么问题反过来如果你一上来就抱住框架的大腿那些参数就只是一堆需要抄写的咒语。我的实际工具链非常简单Python作为主力语言FastAPI作为Web框架一个向量数据库用来存放文档块外加一个嵌入式模型和一个大模型接口就这么多了。我没有上任何重量级的AI应用编排平台也没有引入分布式任务队列因为项目阶段根本不到那一步。这种“少而精”的策略还有一个好处每次出问题时可排查的范围非常小你能快速定位到具体环节而不用在一个庞大的系统里到处找线索。4.2 一个可复制的每周推进节奏整个项目我排成了四个阶段一共用了大概十周。这里分享一下我每个阶段的节奏模板你可以根据自己的时间弹性去调整但节奏感是共通的。周次目标重点动作交付物第1周环境搭建与最小闭环本地环境、API接入、结构化输出、日志框架可运行问答脚本第2周数据层与RAG文档清洗切分、向量化、检索测试集知识库问答脚本第3周工具与记忆函数调用、工具执行、两级记忆可执行命令的助手脚本第4周服务化FastAPI封装、超时重试、日志监控对外HTTP接口每个阶段结束后我还要回答三个复盘问题哪一步花的调试时间最长这个长时间的根因是什么如果重新来一遍我会做什么不同选择这三个问题逼着我去审视过程而不是只看最终跑通的结果。事实证明很多真正有价值的方法论都是在回答这些问题时浮现的。4.3 如何判断自己真的学会了而不是把教程跑通了学AI工程最容易制造的错觉就是“代码能跑我学会了”。为了戳破这个错觉我每次阶段验收时会额外做三件不太舒服的事第一面前不参考任何文档从头默写这一阶段的核心流程用文字画出链路图第二换一个完全陌生的场景比如把“技术文档知识库”换成“产品说明书知识库”检验自己的代码改起来顺不顺手第三尝试回答“如果换一个底层组件链路哪里会受影响”这类问题。这三个测试非常有效。你会发现很多人能照着教程把项目跑起来但一旦你问他“如果文档从PDF换成一堆网页你的切分逻辑还能用吗”他就卡住了。这种卡住的地方恰恰就是真正的学习点所在。也正是因为这三次“灵魂拷问”我才敢说这个项目里的每一个模块我是真的理解而不只是使用。5. 实战中的高频问题与避坑清单5.1 必踩的坑症状、原因与对策速查表把实战中高频踩坑整理成了一份速查表都是很真实的经验希望能帮你绕开我之前掉进去的洞。症状根本原因对策模型回答经常“答非所问”检索召回的文档块与问题不相关建立人工测试集量化召回率调整切分策略和嵌入模型JSON解析时不时崩模型输出带了额外文字或Markdown包裹强调输出格式增加正则清理加入自我修正重试对话超过几轮后模型“失忆”上下文管理策略缺失早期信息被挤掉引入短期记忆窗口重要信息写入长期向量记忆工具调用时参数为空函数描述里没有说清必填参数和格式补充参数的示例值必要时增加一层参数校验与提示接口偶尔超时大模型API响应本身不稳定设置超时时间、加入指数退避重试、提供降级回复服务跑久了内存上涨日志或缓存无限累积连接未释放定期清理会话数据限制单个会话的最大上下文长度还有一个容易被忽视的坑有必要拿出来单独说做RAG时文档清洗的重要性被严重低估了。很多教程直接用现成的解析库提取文本就完事但真实场景里一份PDF可能有页眉、页脚、重复的表格说明甚至扫描件里混杂着乱码。如果你不把这些脏数据清洗干净它们会在被向量化之后进入检索池并在某个倒霉的时刻被当作“最相似的片段”召回然后把模型的回答带偏。5.2 三条“花钱买不到”的项目心得第一垂直场景优先于通用助手。项目走到第三个阶段时我发现一旦把目标放宽到“什么都聊”整个系统就会变成一个空壳没有数据积累没有工具边界没有清晰的用户体验。反而是当我聚焦到“产品技术问答”这个垂直场景后知识库、工具、提示词全部有了明确的优化方向质量一下子提上来了。第二可观测性要比模型效果更早建立。这是整个项目中我最后悔没有提前做的一件事。如果一开始就把日志和追踪设计好后面查问题的时间至少能省下一半。很多AI项目做到后面难以为继不是因为效果差而是因为系统是一个“黑盒”出了问题根本无从下手。第三一定要准备退化方案。模型是会挂的API是会有波动的向量库也是会出故障的。一段诚实的兜底回复远远好过让用户对着加载界面干等。这种“反脆弱”思想是我在这个项目中收获到的、比任何技术细节都要宝贵的工程经验。ai-engineering-from-scratch这个项目到这里已经跑完了全链路但说实话它的价值不在仓库本身而在于亲手把它搭起来的过程中踩过的每一个坑。如果你现在也正在研究AI工程我的建议很简单不要急着上最复杂的架构先从最小闭环开始把每一层都亲手拧一遍螺丝。各层的技术选型会过时但你对整条链路的理解不会过时这种能力才是这个领域里最保值的东西。
返回列表