ARTICLE DETAIL

资讯详情

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

从零搭建AI工程:完整实践路径与踩坑实录

从零搭建AI工程:完整实践路径与踩坑实录 从零搭建AI工程我的完整实践路径与踩坑实录这几年AI发展太快尤其是大模型和Agent相关工具井喷之后“AI工程师”这个岗位的定义一直在被重写。很多人问我要学习路径也有人看到网上铺天盖地的“AI全栈课”就发懵。我自己是从传统后端转过来从一开始只会调API到后来能独立完成一个带数据回流、评测、部署闭环的AI工程前前后后走了不少弯路。今天想借“ai-engineering-from-scratch”这个主题把我从零开始搭建整套AI工程结构的方法论、工具选型、核心细节和常见坑一次性讲清楚。这篇文章适合两类人一是刚入门、想系统构建AI工程能力的开发者二是有一定基础但总觉得AI项目停留在“调通接口”层面、想往工程化方向深挖的人。我理解的“from scratch”不是让你从写神经网络开始而是指在AI能力已经很普及的当下依然从一个原始问题出发不依赖现成的全栈AI平台靠工程手段把模型、数据、评测、部署、迭代这些环节串联起来。这中间涉及的不只是Prompt怎么写还包括怎么理解业务、怎么设计评测集、怎么管理版本、怎么理解模型行为、怎么防止“跑通一次就再也跑不稳”的尴尬。1. 内容整体设计与思路拆解1.1 为什么“从零开始”反而是最优解很多人做AI项目第一步是打开LangChain或者扣子这类平台把几个节点拖一拖觉得“跑通demo”就完事了。但真正的工程化场景——比如企业内部的知识库问答、客服智能体、内容审核辅助系统——一旦涉及私有数据、权限模型、效果量化、成本控制那些可视化平台往往最先成为瓶颈。我的经验是哪怕最后会引入框架第一步也应该从最原始的形式开始。也就是先搞清楚模型API的输入输出、写裸Prompt、用脚本做批量评测、手动追踪每一条bad case。这个过程强迫你把AI当作“一个不稳定但能力很强的组件”来对待而不是当作黑盒神仙。只有当你亲手处理过几十条输出乱跳、JSON解析失败、幻觉引用错误文档等等问题之后再回头看LangGraph、Semantic Kernel这类抽象框架才能真正理解它们到底在解决什么问题也才能避免被框架带节奏。从零开始还有一个隐性收益对系统里每个环节都有掌控感。出了问题你知道去哪查——是Prompt问题、模型参数问题、上下文检索问题还是后处理逻辑的问题。这个能力是在真实业务里存活的核心技能也是面试和晋升时最能体现工程水平的地方。1.2 核心架构选型单Agent起步我在第一个AI工程里抱着“一步到位”的心态直接上了多Agent架构结果被教训得很惨。Agent之间互相传递上下文一个环节出错就整体崩盘而且很难定位。后来我回到单Agent起步才找到稳定推进的节奏。所谓“from scratch”的合理路径是先做单Agent把问题边界、工具调用、评测闭环走通再考虑并行、编排、多模型协同。单Agent不等于简单它已经把下面这堆问题全包含了输入解析用户到底在问什么工具选择需要不需要查询数据库、调用搜索、读文档上下文管理几轮对话之后如何压缩记忆输出校验模型给的答案是否完整、是否可信兜底策略模型拒绝回答或瞎编时怎么办把单Agent跑稳比十个Agent跑demo值钱得多。我在实际项目中反复验证过单Agent如果评测通过率能做到95%以上业务基本就能用了多Agent反而常常因为依赖链过长准确率掉到80%都费劲。1.3 工程闭环模型只是最薄的一层很多人对AI工程的理解就是“调模型、写Prompt”这是最大的误区。我后来想明白了一个类比模型API相当于一个外包的高级开发人员能力很强但偶尔会胡说八道你需要给它明确的任务书Prompt、给它必要的工具检索、计算、数据库、给它做质量检查校验和评测、给它建反馈机制bad case回流。这一整套“管理机制”才是AI工程真正的工作量。我画过一张围绕AI应用的闭环图核心要素永远是这几个业务问题定义数据准备与评测集构造模型与参数策略上下文增强RAG或其他外部工具输出校验与安全护栏线上日志与持续迭代这六个环节里模型选择的占比其实只有20%左右剩下80%都在“模型之外”。这也是为什么很多非AI背景的工程师反而更容易做好AI工程——因为工程能力本来就是通用的。2. 核心细节解析与实操要点2.1 Prompt工程的“结构化”思维先说Prompt Engineering。我见过两种极端一种人觉得Prompt不就是用自然语言写几句话另一种人把Prompt写成几千字的八股文连语气都规定得死死的。这两个方向都不够工程化。我在实践中摸索出来的Prompt结构通常会分成五个块角色定义、任务标的、约束条件、输出格式、边界说明。像一个任务书一样让模型明确知道“你是谁、你要干嘛、你不许干嘛、你给我什么格式、实在不行怎么办”。举一个知识库问答的Prompt片段你是一位严谨的文档助理。你的任务是仅基于提供的参考文档回答用户问题。 约束条件 1. 如果参考文档中没有明确信息直接回答“文档中未找到相关信息”禁止自行推测。 2. 回答必须标注引用来源编号例如[1]。 3. 如果用户问题与文档无关礼貌说明你的能力范围。 输出格式 - 回答正文 - 引用来源列表这段Prompt看起来简单但每句话都是在控制模型的自由度第1条是在遏制幻觉第2条是在做可溯源第3条是限定范围。实际工程里我会把这些规则继续细化成可测试的断言。比如评测的时候会专门构造“文档里没有答案”的一类问题看模型是不是老老实实说不知道。Prompt不是写一次就完了它是随着bad case不断迭代的。我习惯把每一版Prompt都存进Git提交信息里写清楚这次改动的目的和对应case编号。这样出了回退问题能立刻定位是哪一版引入的。2.2 参数选择的“调参纪律”模型参数里最常说top_p、temperature但真正用到工程场景时我建议先把temperature从默认值调低尤其在任务有明确正确性的场景代码生成、信息抽取、结构化输出里temperature定在0.2以下会比较安全。温度太高模型发挥“创造力”时会给你乱编。再就是max_tokens的设置。很多人忽略这个但如果输出长度上限设置太短回答会被截断设置太长延迟和成本都会上涨。我一般会根据业务场景拿一批真实问题做分位数统计确定合理的上限。比如内部知识库问答答案通常500字以内我设max_tokens为800足够覆盖同时也不至于因为长尾巴浪费资源。还要关注response_format。如果模型支持JSON模式或者结构化输出工程上一定要用起来。让模型输出自由文本再做解析是给自己挖坑。实测下来开启JSON模式后解析失败率能从10%降到0.5%以内。2.3 RAG链路中的“隐性炸弹”RAG检索增强生成是AI工程里最常见的模式但它的坑比Prompt本身多得多。我一开始以为只要接个向量库、做次相似度检索就行了结果上线后被用户连续吐槽“答非所问”“引用的内容不对”后来一点点排查发现几类隐藏问题第一是切分策略。很多教程喜欢按固定长度切块比如每块512字符。但真实文档有结构无脑切分会把段落、表格、代码块拦腰截断。检索命中之后模型拿到的上下文是破碎的回答自然不对。后来我改成按标题层级和段落语义来切并且让每个块带上一级标题作为上下文前缀效果立刻好了不少。第二是召回数量。召回太少信息不全召回太多无关内容会干扰模型判断。我的习惯是先做5路召回再通过重排序模型压缩到2到3条高质量段落。没有重排序能力的时候就用关键词匹配向量相似度的分数加权简单但有效。第三是“检索返回空”的兜底。这个问题最容易被忽略。你构造了100条评测发现模型回答错误一查原因是检索没召回任何内容。这个锅其实不在模型而在检索链路。我后来在代码里加了检索结果为空时的专用Prompt提示让模型明说“未找到相关内容”而不是硬着头皮答。这样线上的体验反而更可信。2.4 Agent设计里的工具边界Agent是现在最火的概念但工程上它的核心是“工具调用”而不是“自我规划”。我见过太多Demo让Agent自由发挥工具选择结果路径不可控、同样的输入每次执行流程都不一样。这在生产环境是灾难。我采用的方案是“半受控Agent”预先把问题分流通过意图识别决定走哪个子流程每个子流程里只开放必要的工具集。比如查天气的意图只能调用天气API查库存的意图只能调用库存系统。这样做的好处是流程可预期、权限边界清晰、调试容易。真正需要完全自由规划的场景很少至少我做的这些业务里几乎没有。工具定义也很有讲究。OpenAI Function Calling格式里除了函数名和参数description才是重头戏。我习惯在description里写清楚“这个工具在什么时候使用、什么时候不要使用、参数怎么填最合适”。模型对工具的选择主要靠读description你写得不清楚它就会乱来。3. 实操过程与核心环节实现3.1 从0到1搭建一个最小可运行的AI问答系统这里我用一个内部文档问答机器人作为示例展示我如何从零开始一步步做出来的。先说明整个代码都用Python模型接口以OpenAI兼容接口为例你也可以用国内任意兼容接口替换。环境准备只需要两个库pip install openai langchain-core chromadb这里我不推荐一开始就上完整LangChain全家桶先学会用openai库直连接口亲手处理流式、异常、重试你会对API机制有更深的肌肉记忆。langchain-core只是用来做向量存储和文档处理的轻量工具。第一步定义基础问答函数。from openai import OpenAI client OpenAI( api_keyyour-api-key, base_urlyour-endpoint-url ) def ask_model(system_prompt: str, user_content: str, temperature0.2) - str: resp client.chat.completions.create( modelyour-model-name, messages[ {role: system, content: system_prompt}, {role: user, content: user_content} ], temperaturetemperature, ) return resp.choices[0].message.content这个函数是所有后续环节的地基。注意我把temperature固定在0.2这是出于正确性优先的考虑。第二步加入检索增强让回答基于私有知识库。from langchain_core.documents import Document from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings embeddings OpenAIEmbeddings(modelyour-embedding-model, api_keyyour-api-key) vectorstore Chroma(collection_namedocs, embedding_functionembeddings, persist_directory./chroma_db) def search_docs(query: str, top_k: int 3) - list[str]: docs vectorstore.similarity_search(query, ktop_k) return [doc.page_content for doc in docs]注意Chroma的sentence transformer版本可能会更轻量一些。如果是纯本地的场景可以用BGE或者M3E嵌入模型效果也挺稳定。第三步把检索到的上下文拼接进Prompt。def rag_answer(query: str) - str: context \n---\n.join(search_docs(query)) user_content f 用户问题{query} 参考文档 {context} system_prompt 你是一个严格的文档问答助手。 只依据上述参考文档回答不得补充文档外信息。 如果文档没有相关内容请直接说“知识库中未找到相关信息”。 return ask_model(system_prompt, user_content)到这里一个最小可运行的RAG问答系统就搭好了。我通常会再封装一个API层用FastAPI暴露接口方便接前端或企微机器人。这个阶段不用纠结框架跑通链路才是最重要的。3.2 评测集构造让效果“可度量”很多人说AI效果“凭感觉”那是因为没有一套评测集。我构建评测集的方法论是找业务方收集100到200条真实问题按类型分层抽样。比如一个HR知识库问题大致分几类制度查询、流程咨询、系统操作指引、特殊情况判断。我按这种方式给每类问题打标签并且为每一类设计“期望回答要点”。评分的标准也不是要求模型逐字一致而是检查模型是否包含必要信息点、是否引用了正确来源、是否出现了幻觉。我常用两类评测方法一是LLM-as-judge用大模型打分别二是基于规则的断言。基于规则的断言适合硬性标准比如def check_no_hallucination(answer: str, must_include: list[str]) - bool: return all(kw in answer for kw in must_include)LLM-as-judge适合评估开放回答质量但要注意评委模型也得有统一标准。我会写一份打分Prompt要求模型从“准、全、稳”三个维度打分并给理由。这里要注意评委模型的temperature同样设低不然打分会不稳定。评测集一定要存储成文件纳入Git管理。每次迭代Prompt或者换模型后都跑一遍全量评测对比通过率。哪怕只提升了2个百分点也说明这次改动有正面价值。3.3 工程化监控与日志线上效果不靠猜这个环节是被低估最多的。我一开始做AI应用只关注接口有没有报错完全没有记录模型输入输出。结果用户反馈“某句话回答离谱”我们连是哪天、哪个版本、哪些上下文都不知道排查成本极高。现在我的做法是每一次模型调用都记录结构化日志字段包括时间戳、用户ID、请求ID、模型版本、系统Prompt版本、温度参数、完整的输入messages、输出内容、tokens用量、延迟。这些日志存进ClickHouse或者Elasticsearch同时把bad case自动推送到一个标注队列里。有了日志之后线上出现脏数据我们可以复盘到底是因为检索召回错了还是Prompt没约束住还是模型能力上限不够。大部分问题在日志面前一眼就能看出来。同时tokens用量日志也是分析成本的关键手段不看用量根本不知道钱花在哪。3.4 模型评估与选择别迷信“最强的”最后聊聊模型选型。大模型榜单迭代很快今天的最强就是明天的常态但工程上选模型不能只看分数要看任务类型、数据隐私、成本、并发要求。我总结了一个选型决策矩阵场景类型推荐路线原因开放闲聊 / 创意生成大参数多模态模型能力上限高创意强知识库问答 / 信息抽取专精指令模型 结构化输出更稳成本可控幻觉率相对低代码生成代码专用模型对语法、逻辑理解更准私有化部署场景中小参数可商用开源模型数据不出域成本可预测我在实际业务里会把两到三个模型同时跑一组离线评测带上延迟和成本数据再做最终选择。千万不要只看一张榜单就定了同一任务不同模型的表现差异可能极大。4. 常见问题与排查技巧实录4.1 模型输出频繁“幻觉”怎么压下来幻觉是RAG系统里最高频的问题。我发现很多情况下模型的幻觉不是它“不懂”而是Prompt给它的压力太大——它总觉得必须回答点什么。这时候在Prompt里加一句“如果文档中找不到请直接说不知道”就很有用。此外要求模型在回答里标注引用来源也能大幅降低胡编概率因为模型知道“有据可依”是硬要求。还有一个技巧是把问题拆细。用户提问经常很宽泛比如“报销流程是什么”模型容易自由发挥。我这边会用一层前置改写把问题改写成“公司差旅费报销的提交步骤和审批流程是什么”改写后检索精度明显提升。4.2 JSON解析总失败怎么规避做Agent应用时模型要返回结构化JSON。我不论怎么调Prompt总有百分之几的输出不合法不是多了前后缀就是少逗号。遇到这种问题第一是开启函数调用或JSON Mode第二是代码做容错用正则提取JSON子串、尝试用json.loads解析失败后再用“修复模式”让模型重新输出。我最终采用的是“自修复”策略当解析失败时把失败原因和原始输出一起丢给模型让它修正。实测一次修复成功率能有90%以上修复两次基本上升到99%。但这个策略必然增加延迟和成本所以最好还是在源头控制好别把自修复当作默认路径。4.3 Agent循环失控怎么办Agent循环失控是新手最容易遇到的问题。模型会不断调用工具、不断接到反馈、又继续调用结果就是上下文越来越长、成本飙升、执行时间无限拉长。我给的方案很直接设置最大工具调用轮次上限比如3步超过了就强制停止并输出当前结果或说明“问题过于复杂”。还可以给工具调用加“时间感知”。有的Agent在一个问题上反复横跳根本原因就是缺一个“当前进度”的概念。我习惯在Agent系统Prompt里增加一个“执行计划”字段要求模型每次执行前先写一句当前任务计划然后每一步都对照计划。这样既限制了模型的分心也方便追踪过程。4.4 线上效果和评测效果不一致这种情况非常常见离线评测集通过率95%上线后用户还是骂。原因是评测集过拟合或者评测集和线上真实分布不同步。我后来做的补救是上线初期先小流量灰度同时用线上真实对话持续补充评测集。每个月固定抽一批线上日志人工标注成golden set并替换掉那些已经“过时”的问题。这件事听起来累但是保证效果长期稳定的唯一办法。没有哪个团队能做到永远不更新评测集还保持效果在线。4.5 成本飙升如何控制AI工程成本大头就是token调用量。我的几条控费经验一是缓存高频问题的答案在Prompt完全一致且文档未更新时直接命中缓存二是控制检索的token长度重排序后限制上下文总长三是监控单次请求token如果某类问题平均tokens超高要针对这类问题优化Prompt减少冗长的思维链输出。另外模型降级策略也能省钱简单意图走小型模型复杂推理才调用大模型。我在实际项目里用了一个意图识别分类器先判断问题难度简单问题走轻量模型准确率和成本之间平衡得非常好。5. 工具链与工作流沉淀走到这一步你已经有了完整的最小闭环。我再分享一个自己沉淀的AI工程工作流模板照着做可以少走很多弯路。首先是项目目录结构我习惯这样组织project/ ├── data/ │ ├── raw/ # 原始文档 │ ├── processed/ # 切分后的文档 │ └── eval/ # 评测集 ├── prompts/ # 所有Prompt版本按模块存放 │ ├── system/ │ └── few_shot/ ├── src/ │ ├── rag/ # 检索增强 │ ├── agent/ # Agent逻辑 │ ├── eval/ # 评测脚本 │ └── api/ # 服务接口 ├── logs/ # 运行日志 └── tests/ # 单元测试这个结构是我从几个项目里迭代出来的不一定适合所有人但可以在前期模仿。即便你习惯另一种结构也建议做到“prompt版本化、评测集版本化、日志完整记录”这三件事。在很多中型业务里我还发现引入“多AI协作”能带来稳定的质量提升让一个模型做初稿另一个模型做审核再由规则引擎判断是否通过。这个模式比单纯调大模型参数便宜而且能减少低级错误。不过要注意多模型之间如果逻辑冲突要靠后置的仲裁逻辑去统一不能只看谁的输出“更像”。6. 我的经验沉淀与后续可选方向很多人会问“从零学AI工程最快路径是什么”。我给不了捷径但我可以给一个方向先做一轮端到端的极简项目把链路跑通然后不断往链路上加“质量保障”的环节等稳定了再开新项目复制同样的方法论。每个项目都沉淀出标准化的工程模板、评测集和Prompt版本管理机制时间久了你手里就有一套属于自己的AI工程基础设施。如果这个基础打得够牢后续可以自然扩展到更复杂的方向比如引入自主Agent编排做一些真实的自动化流程或者把多模态能力接进来做音视频内容的理解与处理也可以把AI能力嵌入到离线的数据分析管道里做分阶段、可回滚的智能化改造。这些方向我都验证过路径是通的但前提永远是先把最小可信闭环做好。我个人最大的体会是AI工程不是“发明创造”而是“管理不确定性”。模型输出天然带有随机性工程的目标不是消灭随机性而是把随机性封装在一个可控的边界里。这个边界靠的就是评测、日志、版本、护栏、兜底这些看起来不性感、但真正决定项目成败的东西。如果你现在正准备做一个AI工程化的项目我的建议是不要急着嵌套复杂的架构找一个真实小场景把模型API调用、评测集构建、日志回流这三件事做透。做完之后你会发现很多复杂的问题其实是早期这三个环节没做扎实导致的连锁反应。最后再分享一个小技巧写Prompt或者设计Agent流程时永远同时写一份“坏case预案”。想象模型在每一步可能出什么错然后给出应对措施。这个过程比想象中更能提升系统的健壮性。它不产生炫酷的Demo但它会在生产环境里一次又一次救你。
返回列表