多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

从零搭建AI工程:核心链路、评估体系与生产落地实践

从零搭建AI工程:核心链路、评估体系与生产落地实践 1. 项目概述与核心思路1.1 什么是AI Engineering我在这个标题下面想聊聊一个特别容易混淆的概念很多人以为AI Engineering就是指会调用大模型API、写几段提示词、把ChatGPT的输出接进自己的系统里。我一开始也是这么想的结果在实际做一个从零开始的AI项目时被现实狠狠教育了一轮。真正的AI Engineering是把一个能聊天的模型变成一个稳定、可评估、可维护、成本可控的生产系统的过程。它至少包含数据工程、模型选型、提示词与工具调用、评估体系、监控运维、迭代机制这六块内容。你可以把大模型想象成一台刚出厂的发动机它确实有强劲动力但你得自己设计油路、变速箱、底盘和仪表盘才能让它变成一辆能上路的车。这个从发动机到整车的过程就是AI Engineering。从这个角度来看AI Engineering和AI Research是不一样的。研究关心的是模型还能不能更聪明工程关心的是这个系统明天还能不能稳定运行、出了错能不能定位、需求变了能不能快速调整。这也是我极建议每个想做AI落地的开发者至少完整经历一次从零搭建的原因——只有亲手把一个模型接进工程链路你才会真正理解那堆框架和平台在帮你省掉哪些麻烦。1.2 为什么强调From Scratch提到from scratch很多人第一反应是不用任何现成框架从神经网络自己训练。这算一种理解但我觉得在工程领域更合理的理解是不要把别人的完整方案当成黑盒而是把整个系统按层次拆开每一层都自己决策一次。举个例子现在做知识库问答最快捷的办法是直接套用某个RAG平台上传文档拿到一个聊天机器人。但这套方案在你的数据格式特殊、答案需要严格引用、并发量又高的时候很容易崩。你甚至不知道问题出在文档切分、向量检索还是模型上下文。如果我从零开始搭我会清楚知道每一层是怎么实现、为什么这样选出了问题才能顺着链路排查。从零开始也会逼你把工程素养补齐数据清洗的细节、接口超时处理、Token计费方式、并发限流、日志追踪。这些东西在demo里不重要在生产里致命。我个人的体会是第一个从零搭建的AI应用即使做得丑一点也比直接套一个炫酷框架学到的多十倍。1.3 适用的人群与应用场景如果你正在做下面这几类事这篇文章会比较对路想给团队内部做一个知识库问答助手而不是简单挂个开源项目正在评估用大模型API还是自己微调模型需要一套判断标准想把Agent类的多步任务比如自动写周报、自动整理邮件、自动做报表落地但总是卡在稳定性上手头有数据、有业务场景但不知道怎么把模型接进自己的代码里已经用了一段时间现成平台但遇到瓶颈想搞清楚底层原理。这些场景共同的特点是你需要的是可控而不是炫酷。从零搭建过程中做出的每一个技术选型最后都会体现为系统稳定性、成本和维护体验上的差异。2. 从零搭建AI工程的技术栈选型2.1 模型层开源与闭源怎么选技术选型是AI工程里最让人纠结的事。我见过太多人一上来就想自己训练一个大模型结果数据量不够、算力不够最后项目死在第一步。我的建议是先别急着训练先考虑调用 微调的组合策略。所谓组合策略就是主链路用成熟API模型比如国产大模型或国际主流模型因为它们经过充分对齐指令遵循能力强适合做通用的理解和生成然后针对专业领域用开源基座模型做微调或者做检索增强专门处理私有知识和特有格式。选型的时候我一般看五个维度上下文长度决定你能塞多少资料工具调用/函数调用的支持程度Agent场景的命脉输出速度与成本生产环境每天的调用量会让单价无限放大私有化部署的难度涉及敏感数据时你必须能自托管社区生态和文档质量遇到问题能不能快速找到答案。这里特别想提一个常被忽略的点模型的风格对齐能力。有的模型数学推理强但写作生硬有的模型代码能力强但中文表达差。你以为是在选哪个聪明其实是在选哪个适合你这个业务场景。2.2 数据工程层AI项目的隐形基础很多教程讲AI工程直接从调API讲起我把它看作是一种误导。真实的AI工程里数据工程至少占掉一半的工时。你要做的包括收集从业务系统、文档库、网页、数据库抽取原始数据清洗去重、去噪、纠错、过滤敏感信息结构化转成统一的JSON、Markdown或其他格式切分把长文本切成适合模型输入和检索的块标注为评估集准备标准答案。我踩过最深的坑是文档扫描件直接喂给模型。PDF里的表格被转成乱码模型给出的答案自然全是幻觉。后来我把所有文档统一走OCR版面分析人工抽检准确率才上来。数据这块没有捷径唯一的技巧就是建立一套可重复执行的流水线并定期检查数据质量。2.3 工程框架层选型原则与组合方式OpenAI之后市面上出现了大量AI框架LangChain、LlamaIndex、Dify、Coze还有各种Agent框架。我的态度是框架可以用但必须理解它替你做了什么。否则出了问题你会像个不会修车但开得飞快的人迟早翻车。从零搭建时我更倾向于最小核心 外围框架核心链路自己写调用模型的代码、提示词拼接、工具调用循环、结果解析这些必须自己掌控外围能力用现成库比如向量数据库用Milvus或QdrantEmbedding用现成模型OCR用PaddleOCR任务队列用Celery或Redis Stream。这么做的理由是核心链路决定了产品的体验必须可掌控外围能力是通用组件复用别人成熟方案效率最高。举个例子我自己实现过一个非常简化的工具调用循环后面会给出代码总共不到200行但它把模型怎么决定调用工具、工具结果怎么回填、什么时候终止这个流程彻底讲明白了。有了这个认知再去看那些重型Agent框架你会觉得豁然开朗。2.4 运维与监控层常被忽略的保命环节自建的AI系统最怕什么一怕模型接口超时二怕Token消耗失控三怕输出质量凭空变差。这些都需要监控来解决。我的监控方案分成三层基础监控服务器CPU/内存/磁盘用Prometheus Grafana就能解决应用监控请求量、延迟、错误率、Token用量需要自己在代码里埋点质量监控人工抽样评分 自动评估指标比如答案相关性、引用命中率、幻觉率。第三层最难因为质量不像接口延迟那样有明确的数值。我的经验是建立一个小规模的黄金评估集每周跑一遍用自动评估脚本输出指标变化。只要指标掉我就能在用户投诉之前发现问题。3. 核心环节从提示词到Harness工程3.1 Prompt Engineering不是魔法咒语Prompt Engineering的关键词在Engineering而不是Prompt。它约等于你如何用自然语言给模型定义角色、任务、输入格式、输出格式、约束和示例。很多人觉得提示词就是写一段好听的话这个认知会让你的系统极其不稳定。我通常把提示词拆成五个模块系统指令定义身份和总体规则任务描述定义要做的具体事输入数据动态插入用户问题或检索资料输出格式定义JSON结构或模板示例给一两个few-shot示例。举个实际的例子我在做一个招聘助手时一开始提示词写得很短你是一个HR助手回答关于招聘的问题。结果输出五花八门有的回答带表情有的编造公司政策有的输出超长。后来我把提示词改成结构化格式要求只能基于给定的制度文档回答不知道就说不清楚输出JSON包含answer和source两个字段效果立刻稳定了。这说明Prompt这层是系统稳定性的第一个杠杆。3.2 Harness Engineering把模型装进笼子我最近非常关注harness engineering这个概念。它比Prompt Engineering更进一步不是靠语言去约束模型而是用代码去约束模型的边界。一个典型的harness包括输入校验确保用户输入在合理范围内输出解析强制把模型输出解析成结构化数据解析失败就重试工具调用协议定义模型可以调用哪些工具、参数格式是什么安全防护对模型输出做敏感词过滤、权限校验重试与回退模型输出不合法时自动重试或走备用链路。你可以把harness理解为给模型造的一个结构化接口。模型在这个接口内拥有自由度但不能越界。这对生产系统至关重要因为大模型的输出天然具有不确定性你必须用一个确定性的外壳去兜底。举个例子我做个一个工具调用型Agent最初是让模型直接输出调用search工具参数是xxx这样的文本。结果模型时而用中文括号时而用英文括号解析代码改了一轮又一轮。后来我改成了JSON Schema约束 代码侧校验模型只能在预定义的函数列表里做选择参数类型不对就会被harness拦下来重新生成。这个改动让整个工具调用的成功率从82%提升到了接近97%。3.3 从零实现一个极简Harness下面这个简单的Python片段展示了harness的核心逻辑大概就是让模型决定调用哪个函数然后由代码去执行# 极简工具调用Harness import json def search_knowledge_base(query: str) - str: 模拟检索知识库 return f关于{query}的检索结果在制度文档第3节找到相关描述。 def calculate_leave_days(employee_id: str) - str: 模拟查询假期 return f员工{employee_id}剩余年假10天。 TOOLS { search_knowledge_base: search_knowledge_base, calculate_leave_days: calculate_leave_days, } SYSTEM_PROMPT 你是一个企业助手。如果需要更多信息选择一个工具并返回JSON {tool: 工具名, arguments: {参数名: 参数值}} 不要编造工具不存在的功能。 def run(model, user_input: str, max_steps: int 3): messages [{role: system, content: SYSTEM_PROMPT}, {role: user, content: user_input}] for _ in range(max_steps): reply model.chat(messages) try: action json.loads(reply) except json.JSONDecodeError: # 模型没有输出JSON直接作为最终答案返回 return reply tool_name action.get(tool) if tool_name not in TOOLS: return 模型试图调用未知工具已终止。 result TOOLS[tool_name](**action.get(arguments, {})) messages.append({role: assistant, content: reply}) messages.append({role: tool, content: result}) # 让模型基于工具结果生成最终回答 final model.chat(messages [{role: user, content: 请基于工具结果回答用户问题。}]) return final这段代码虽然简化但已经包含了api的定义、工具的注册、结果回填、循环终止这些harness的核心要素。生产环境的Agent框架本质上就是把这个循环做得更健壮加上记忆、规划、并发和可观测性。4. 核心环节Loop Engineering与多AI协作4.1 Agent的本质是一个循环很多人对Agent有误解觉得Agent就是会自动思考的AI。从我实际开发的经验看Agent的本质是一个带循环的控制系统感知环境、做出规划、执行动作、观察结果、修正策略直到达成目标或到达终止条件。这个循环在工程上需要非常严谨的设计。我见过太多Agent项目死在无限循环上模型不断调用工具结果越来越偏Token一直烧。核心问题就是没有做好Loop Engineering。所谓Loop Engineering我觉得至少包括这几方面设计终止条件任务完成、达到最大步数、成本超限、用户中断限制工具的返回长度防止工具返回结果过大把上下文撑爆引入反思机制每轮结束后让模型自查是否回答了用户问题设计异常恢复工具调用超时怎么办解析失败怎么办连续失败怎么办在实际项目中我把max_steps设置为5到8步超过就强制终止同时要求每轮工具调用的返回结果做截断。这样系统最少可控无论模型怎么折腾成本都有上限。4.2 编排式与审议式的多AI协作随着业务复杂度上来单个AI往往不够用。这就涉及多AI协作。我尝试过的模式主要有三种编排式Orchestration一个主Agent拆解任务分配给不同子Agent执行最后汇总。适合写报告、做竞品分析这类流程相对固定的任务。审议式Debate/Critique多个模型对同一问题给出答案互相点评挑出最优。适合需要高准确率的决策场景。专家路由Router先用一个分类模型判断问题类型再路由到不同的专家模型。适合意图差异明显的场景。我自己的偏好是优先用编排式因为它的流程可预测、好调试。审议式虽然效果好但Token开销成倍增长。比如我试过用三个模型对一份合同做风险审查每个人从法律风险商业风险执行风险三个角度单独审再让主模型汇总成报告效果确实不错但花费也翻了3倍。所以我一般只在出错代价很高的任务上才启用多模型审议。4.3 多模型与多AI协作的工程实现实现多AI协作时最容易犯的错是让多个模型共享同一个上下文窗口。这会导致Token爆炸而且不同模型对上下文的侧重点不一样互相干扰。正确做法是给每个子Agent独立的上下文空间只把必要的输入和结果以结构化数据的形式传递。举个我最近做的例子一个生成营销文案的系统拆成了三个子AgentAgent A分析产品卖点输出产品关键属性列表 Agent B基于属性列表生成三版不同风格的文案 Agent C评估文案与品牌调性的一致性并输出推荐版本A的输出是结构化JSON传给BB的三版文案传给C评分最后由主流程选择C评分最高的一版。整个过程没有让任何一个Agent看到全部上下文。实测下来这个分工流水线比单个Agent直接写文案的稳定性和风格多样性都更好。5. 从零构建可控的数据与评估体系5.1 数据质量决定系统上限我强调过很多次AI系统的上限是数据质量决定的模型只是下限。一个项目如果数据乱、格式脏、内容过期再先进的模型也救不回来。所以从零搭建AI工程时数据这块不值得省钱省力。数据处理的几个关键点去重同一份合同被扫描多次会产生多个相似文档检索时它们会互相干扰版本管理业务文档经常更新必须保留快照否则模型会基于旧资料作答权限过滤敏感信息不能进入模型上下文尤其在Agent场景权限必须提前做隔离切分策略我建议先按Markdown标题切块再按段落和句子补全而不是无脑按固定字数切。这里特别说一句现在很流行把文档全部embedding塞进向量库但我提醒你向量检索不是万能的。很多问题需要精确匹配如员工编号、政策编号、金额这些用倒排索引或者传统数据库检索往往比向量相似度更可靠。工程上最稳的方案是混合检索关键词召回 向量召回 重排序。5.2 评估集与指标让感觉还行变成数据做AI工程最怕的就是感觉还行。感觉会骗人数据不会。所以我从第一周开始就要求自己建立黄金评估集。所谓黄金评估集就是一批代表性的问答对每对包含问题和真实用户问法接近标准答案人工撰写引用文档必须来自知识库难度标签简单/中等/困难如果做一个招聘问答系统我会准备200个左右的问题覆盖制度查询、流程咨询、政策计算以及一些刁钻的、知识库里没有答案的问题考察模型会不会诚实说不知道。评估时我有三个核心指标答案相关性模型输出和标准答案的语义相似度引用命中率模型引用的文档是否真的支持答案拒答准确率对于库外问题模型能否正确拒答而不是编造。这三个指标分别对应信息获取、可追溯性和诚实性。它们比单纯看对话流畅度有用得多。5.3 从人工评估到自动化评估200个问题靠人工每天标注显然不现实所以自动化评估是必选项。我常用的方法有两种一种是LLM-as-a-Judge用一个大模型去给答案打分。需要注意评分模型必须和业务模型独立否则会出现自己给自己判卷的问题。并且要给评分模型明确的标准比如输出1-5分和理由。实测这种方案能看出大概趋势但不能完全替代人工复核。另一种是程序化检查规则明确时用代码判卷更可靠。比如要求答案必须引用制度编号那我可以写一个正则去检查答案里是否包含编号XX要求答案不能包含可能这类模糊词我可以写脚本统计不确定词汇的出现次数。我的建议是能用程序化检查的绝不交给大模型程序化检查覆盖不了的再用LLM打标最后保留每周人工抽检30条作为最终校准。这个组合既高效又不离谱。6. 实操过程从零搭建一个可落地的AI问答Agent6.1 需求定义与模块拆分纸上谈兵够多了我分享一个完整可用的案例给一家中小型公司做内部制度问答Agent。需求没有想象中的复杂员工可以查年假、报销、加班规则系统必须回答准确、注明出处、支持追问。我把系统拆成五个模块知识库管理把制度文档清洗、切分、入库检索模块混合检索 重排序问答模块基于Prompt 检索结果生成答案工具模块查询员工剩余假期来自HR系统API评估模块用黄金集定期评估。这个拆分最重要的是让每块可以独立测试。比如我先不接大模型只用检索模块返回有没有找到相关文档就能判断检索质量。上线前也能分别优化每一层而不是等整个系统端到端后乱糟糟地调。6.2 知识库构建从文档到向量构建知识库的流程如下第一步收集所有制度文档统一转为Markdown格式第二步做版面分析识别标题层级、表格、列表第三步按章节切块设置chunk size在512到1024个token之间第四步为每块生成摘要摘要存一个字段原文存一个字段这样检索时可以先用摘要匹配再返回原文给模型第五步用Embedding模型生成向量存进向量库第六步同一时间建倒排索引支持关键词检索。有人会问为什么需要摘要字段因为Embedding模型对长文本的语义压缩效果有限。一个512字的块直接用原文做向量可能聚焦不清晰。用摘要做向量、用原文做参照是我调试检索质量后总结的实用技巧。6.3 检索与重排序让找到变成找准在实际系统中单靠相似度返回TopK还不够。举个我踩坑的例子员工问今年年假几天向量检索返回的第二条文档是年假管理办法看起来很像但内容是五年前的旧版。这就是典型的召回不缺、精准度不够。我的方案是第一轮用向量召回50条候选同时用关键词召回20条候选然后合并去重再用一个重排序模型或大模型对每条候选和问题做相关性打分取前5条作为上下文。这样实现下来答案引用的文档准确度有明显提升。重排序还有个小技巧把候选文档的标题、摘要、首段拼接起来再让重排序模型打分而不是光看向量距离。因为标题往往比正文更精确地反映文档主题能起到找标题的作用。6.4 工具调用接上HR系统为了让Agent能回答我还有几天年假需要接入HR系统API。这个调用通过harness完成模型根据对话内容判断需要查询员工编号然后调用get_leave_balance(employee_id)接口。这里有个产品层面的细节员工编号不能由模型瞎编。解决办法是提前通过企业身份认证拿到员工编号放进会话上下文中模型只能读取不能修改。凡是涉及个人信息和权限的操作都要在模型之外完成校验。我会写一个中间层在模型调用任何查询个人信息工具之前先比对会话里的身份信息和工具参数不一致直接拒绝。6.5 部署与监控上线只是开始部署方案我选择了相对简单的FastAPI提供接口前端接一个极简Web页面服务部署在内网容器里后端接模型API。代码里从三个层面做了埋点每个请求的开始时间、结束时间、Token数检索阶段的候选数和命中位置模型输出被harness解析成功还是失败、重试了几次。日志统一打到JSON文件再导入Kibana展示。上线第一周我就靠这些日志发现了一个大问题带表格内容的文档切块后表格被截断导致模型读到一半的数据答案经常错。后来我专门写了一个表格识别逻辑表格作为整体块存不进向量库只存结构化成文本的版本问题就解决了。6.6 持续迭代用评估驱动改进系统上线后我始终保持一个节奏每周用黄金评估集跑一次回归拉出所有失败case分类整理。失败原因一般就几类检索漏召回占40%文档过期或缺失占30%提示词约束不足占20%模型本身能力问题占10%每一类处理方式完全不同检索问题就优化切分和重排序文档问题就更新知识库提示词问题就调整约束模型问题才考虑换模型或加few-shot。这种用数据驱动迭代的方式比感觉最近好像变差了靠谱太多。7. 常见问题与排查技巧实录7.1 模型输出总是不稳定怎么办症状同一个问题连问三次答案差异很大有时候带大段废话有时候直接给JSON之外的文本。排查思路分两步。第一步把温度参数调低如0到0.3并把输出约束写死在我们前面的harness里第二步检查是不是上下文太长导致模型注意力被稀释这时需要精简检索返回的内容。我实操中最管用的三招强制JSON输出、温度调0到0.2、few-shot示例固定格式。这三招能把飘忽不定的输出拉回稳定轨道。如果还不行说明模型本身能力不够才考虑换更大的模型。7.2 检索不到或检索一堆无关内容这个问题几乎每个RAG项目都会遇到。我的排查顺序是先看召回率直接打印检出的文档标题和得分确认有没有相关内容被漏掉再看重排序让重排序模型打印每个候选的打分理由看看模型是不是被某个看起来像但实际无关的文档带偏了后看切分如果一段内容被切得太碎检索到的块不含答案关键信息就要调整chunk_size或合并策略最后看Embedding模型拿几个困难问题跑一遍人工判断相似度得分是否合理。一个被忽视的建议加关键词检索兜底。向量召回经常对5000元报销上限是多少这类数字密集型问题表现一般而关键词检索能精确命中5000元这类数字。混合检索是成本很低但效果很扎实的方案。7.3 Token成本失控Token失控一般出现在两个场景一是Agent不断调用工具导致多轮上下文膨胀二是检索返回的参考文档过多每条都塞进Prompt。我的成本控制办法为Agent设置max_steps最多5步超出强制结束工具返回结果截断工具只返回最相关的字段不返回全量数据控制上下文窗口每轮对话动态裁剪历史只保留最近2轮和系统指令对长文档先摘要再输入几百页的制度文档不可能全部塞进Prompt只输入检索命中且被重排序选中的部分。线上跑了一个月我发现单个会话平均Token消耗从约8000降到了不足3000效果几乎没变。这让我更确信成本控制不是压缩质量而是减少浪费。7.4 Agent陷入循环反复调用工具症状模型不断调用同一个工具每次都说信息还不够或者在一次失败后换个参数又试一次永无止境。根治方法在设计终止条件时就下手。我的做法最大步数硬限制连续两次同样工具调用失败后直接把该工具列入禁用名单要求模型每轮都要输出当前进展一句话一旦连续两轮进展描述相同就说明在原地打转强制收敛使用成本预算动态终止设定单会话最大Token数超过后提前结束并提示用户。其实Agent循环问题的根源不是模型笨而是工程上缺少安全阀。把安全阀设计好了Agent再疯也烧不掉你的预算。7.5 模型幻觉编造不存在的政策条款幻觉是AI问答系统最致命的毒瘤。我在制度问答系统里用了三重防幻觉机制第一重Prompt里强制要求只能基于提供的文档回答禁止补充外部知识第二重harness自动检查答案文本中是否包含引用编号如果引用编号不在检索结果的文档ID集合里直接拒答第三重后置校验用一个小模型对答案和引用文档做一致性打分分数低就自动改为无法确认请咨询相关部门。这三重机制下来系统中幻觉比例降到了可接受的范围。我要特别提醒别指望提示词就能根治幻觉工程拦截才是更可靠的防线。8. 一些超出教程的体会从零搭一个AI工程最让我意外的不是模型能力而是工程本身的复杂度。模型只要你选对、调好它的智商是稳定在那里的真正让项目翻车的往往是数据脏、接口慢、上下文乱、评估缺失这些看起来不性感的细节。我现在只要听到有人吹用几个Prompt就能做一个Agent我就知道这个人大概率没做过生产系统。真实世界是大模型加上不确定性之后一切都需要重新设计输出要解析、循环要限制、数据要清洗、成本要预算、效果要验证。这些才是AI Engineering里Engineering的真正含义。如果你也在从零搭自己的AI项目我只有一个建议先搭一条能跑通的最小链路哪怕丑、哪怕慢然后围着它一步步加数据、加评估、加固件。链路在手你对整个系统才有掌控感替换任何一环都不慌。反过来如果你一开始就追求完美架构大概率会在某个环节被一个不起眼的细节卡住然后整个项目失去前进的动力。from scratch从来不是目的而是手段。它的价值不在于让你重造轮子而在于让你把手里的轮子摸得一清二楚。等你有过这么一次经历之后再看任何AI框架、AI平台都不再是黑盒而是可替换的零件。这种感觉比任何炫酷的demo都值钱。
返回列表