新闻详情

新闻详情

首页 / 资讯中心 / 详情

从零搭建AI工程线:文档智能问答项目全流程复盘

发布时间:2026/10/1 13:55:53来源:尧图网络
从零搭建AI工程线:文档智能问答项目全流程复盘
从零开始搭一条AI工程项目线远比想象中复杂。年初我们团队要做一个企业内部文档智能问答的项目仓库里没有任何AI相关的基础设施甚至连GPU机器都是临时借的。整个项目从立项到上线小范围试用我踩过的坑、推翻掉的方案、以及最终沉淀下来的工程套路凑齐了这篇文章。如果你也正打算从零开始搭ai-engineering能力希望这篇复盘能帮你少走几段弯路。文章会围绕一个具体项目展开从问题定义、数据管线、模型实验评估到上线部署和线上回归完整走一遍。1. 项目背景与第一阶段把问题定义清楚再动手1.1 我们到底要解决什么问题项目最初的需求很模糊做一个智能问答助手让员工查制度、查流程更快。这种描述几乎等于没说。我入职后第一周做的事情不是选模型而是把问题拆成了三个层面用户场景员工在什么场景下会提问比如年假怎么算报销流程需要几个审批节点。回答形式是直接返回一段文字还是给出相关文档片段让用户自己判断数据范围知识库包含哪些文档更新频率如何有没有权限隔离要求这个拆解过程直接影响了后续所有技术选型。比如回答形式如果要求给出文档出处那么纯靠大模型背诵知识是不够的必须有检索增强环节如果数据范围包含敏感部门文档那么权限过滤就必须进入系统设计而不是事后补。我的强烈建议是动手写代码之前先把这些问题整理成一页纸的需求文档。哪怕团队只有你一个人也值得写。因为AI工程最贵的时间不是训练模型而是在错误的方向上反复试错。需求文档不用严谨到PRD级别但必须能回答用户怎么用、答错了会怎样、数据从哪来这三件事。1.2 从零做技术选型的判断逻辑技术选型阶段我给自己定了四个约束不开源的技术不碰避免被厂商绑定。社区活跃度优先于文档漂亮程度因为踩坑时只能靠社区。允许先用一套简单但能跑通的方案再逐步替换组件。每一步都考虑能不能回滚到上一版。基于这几个约束我挑了主链路向量数据库用PostgreSQL的pgvector扩展没有单独引入Milvus模型部分先走API调用把流程跑通后再决定要不要私有化部署编排框架直接用Python写不引LangChain之类的大型框架。这个选择看起来不够AI-native但在当时团队没有专职AI运维的情况下它最大程度降低了排查链路跨度。事实证明很多问题都出在管道衔接上组件越少越容易定位。踩坑提示不要一上来就搭一套完整的AI平台。平台化是业务验证之后的事情早期最合适的形态是一个可以被快速丢弃或重写的脚本级管线。2. 数据管线的搭建真正的工程量集中在数据2.1 文档采集与清洗问题比想象中琐碎我们的知识库文档散落在多个系统里有Word、PDF、Excel、PPT还有少量直接写在Wiki里的页面。第一步是写一个采集脚本把这些内容统一抓下来转成纯文本。这一步我踩了三个实打实的坑第一个坑是PDF解析质量。很多表格型制度文档用常规解析库抽出来之后行列关系完全乱了比如审批节点和审批时限被拆成两段孤立文本。后来我换成了基于布局分析的解析方式对表格结构做感知再针对特殊模板单写规则。第二个坑是图片型PDF扫描件必须先做OCR这导致整体处理时间涨了三倍。第三个坑是重复文档和版本问题同一个制度文件在共享目录里存在最终版最终版V2绝对最终版三个版本如果没有去重和版本识别知识库会被污染得很严重。清洗阶段我按规则做了几件事把连续空白符压缩、统一换行符把全角符号转半角把页眉页脚切掉把第X页共Y页之类的噪声行去掉。这些处理看起来基础但直接影响后续切分质量。你切出来的文本块如果带着页眉噪声检索向量里就会混入高频无意义特征轻则浪费token重则检索结果漂移。2.2 切分策略改过三次才算稳定文本切分是决定检索质量的核心环节我前后调了三轮。第一轮用固定字符数硬切每512个字符一个块。结果很糟糕很多句子被腰斩检索到的片段读不通。第二轮改成按段落切超过上限再折半。段落切分保留了语义完整性但遇到超长列表类文档时一个段落可能有几千字继续切分会把编号列表腰斩。第三轮我索性自己做了一个切分器以标题层级和段落边界为主边界。单个块的上限设为800字超过则按句子边界切。切完后对相邻块做10%~15%字符重叠避免检索时刚好遗漏边界内容。每个块保留来源文档ID、标题路径、页码方便溯源。def split_document(text, max_chars800, overlap_ratio0.1): blocks [] # 先按标题和段落边界拆成粗块 rough_blocks split_by_headings_and_paragraphs(text) for block in rough_blocks: if len(block) max_chars: blocks.append(block) else: sub_blocks split_by_sentence(block, max_chars) for i, sub in enumerate(sub_blocks): if i 0: sub merge(blocks[-1][-int(max_chars * overlap_ratio):], sub) blocks.append(sub) return blocks这个切分器的代码本身不复杂但它是我整个项目里改动最频繁的模块。每次线上检索效果有问题回头查切分都能发现新边界情况。经验是切分规则尽量数据驱动把一段异常文本喂进去观察结果比在纸上设计完美算法更有效。此外我给每个文本块算了一个质量分低于阈值的块比如全是表格碎片会标记为低优先级不进主检索索引。这个策略在后来的效果回归中帮了不少忙。3. 模型实验与评估决定成败的是评测方法3.1 先跑一个笨的baseline团队里有人一开始就想微调开源模型我按住了这个冲动。理由是在数据管线和评测集都没准备好的时候动手微调结果好坏都没有参照系。我选择先做一个基于检索增强的baseline从预置知识库里检索TopK文本块拼进提示词让模型生成回答。这一步用了商用模型API回答质量不稳定但胜在能快速串联整个链路。baseline的价值不在于效果好坏而在于它给了你一个可比较的地板后续任何优化策略都必须打过这个地板。如果哪天真要微调也必须先确认检索管线本身没有短板。我们当时测下来baseline在简单制度问答上粗略正确率大约有75%但在多跳问题比如申请A补贴需要满足B条件吗上掉到不到50%。这些问题成为后续优化的重点。3.2 评测集不建评测集效果就是玄学我见过很多项目上线时凭感觉说效果不错结果用户一用就崩。为了让效果可量化我建了一套三层评测体系第一层是单轮问答集每个问题配标准答案和文档出处用于跑离线自动评测。第二层是带干扰项的问答集问题里故意混入无关条件看模型会不会被带偏。第三层是真实用户会话回放集从灰度日志里捞真实问题手动标注好标准答案。离线自动评测我用了一个很简单的打分逻辑先判断回答里是否包含关键实体再判断标准答案中的关键句子是否被召回最后人工抽检百分之二十。之所以不把整段语义相似度作为唯一指标是因为在实际场景中用户更关心的是数字、日期、流程节点这些硬信息有没有答对。语义相似度高但关键数字错等于完全错误。指标上我盯四个检索召回率RecallK、生成答案的事实一致性、端到端正确率、平均响应延迟。这些指标会进每周一次的效果回归任何技术改动都不能只看一两天的表现。3.3 从纯RAG到混合方案的一次转折跑了三周之后发现纯RAG方案有一个硬伤知识库里的制度更新之后检索到的旧版本内容会有误导。我们当时在知识库文档里加了版本字段但检索的是文本块向量版本信息只是元数据并不直接参与相关性排序。于是结果经常是旧版本制度排在前面新版本排在后面。解决思路不是在提示词里写请优先使用新版本,而是改检索逻辑如果同一个文档标题下有多个版本只索引最新版本同时在检索阶段增加一个硬性过滤条件把已归档的文档排除掉。这个操作本身不花哨但它逼着我把数据管线里增加了版本号提取和索引重建任务。进一步地我引入了混合检索向量召回负责语义相关性关键词召回负责精确匹配制度和术语编号。比如用户问报销上限5000时关键词报销上限精确命中远比向量相似度靠谱。混合检索融合后TopK召回率从原来的0.78提升到了0.86端到端正确率从56%升到了67%。这个收益在当时比换更贵的模型大得多。4. 部署、监控与回归上线才真的开始4.1 推理服务设计别只盯着模型性能上线之前我们面临一个选择继续用API还是私有化部署一个小模型。对比之后我选择了后者。原因有三个数据不能出域、用户请求量有波峰、长期算成本更可控。但私有化的代价是自己扛运维。我选了支持量化的模型用半精度推理单卡能撑住大约30并发再配合排队机制把请求削峰填谷。推理服务部署成三个独立服务互不拖累检索服务只负责向量召回和关键词召回返回TopK文本块。生成服务调用本地模型输入提示词文本输出回答。路由服务负责权限校验、请求转发、超时控制。# 部署时用到的关键启动参数示例 python -m vllm.entrypoints.openai.api_server \ --model ./model_dir \ --served-model-name local-qa-model \ --dtype bfloat16 \ --max-model-len 4096 \ --gpu-memory-utilization 0.8 \ --port 8001这里踩过一个真实教训单独压测检索服务和生成服务时都正常一联调就超时。原因是检索服务在大并发下偶尔跑到300毫秒生成服务首次请求因为显存预热的冷启动高达8秒路由服务设置的超时时间是10秒勉强能过。但在高峰期检索偶尔会跑到400到500毫秒加上排队整体就崩了。定位到问题后我把路由超时拆了两级第一级等待调度第二级等待生成首字。同时给生成服务加了空闲预热把冷启动时间压到2秒以内。这种单服务正常、联调崩的问题最能体现AI工程化和单纯搞模型的区别。4.2 线上可观测性没有日志就是盲人摸象第一版部署上线之后我几乎每天都会被用户反馈吓一跳。有人说回答不完整有人说怎么答非所问最麻烦的是这些反馈很难复现。后来我硬性规定所有线上请求必须记录三层日志输入层原始问题、用户身份、请求时间。中间层检索到的文本块ID、相关性得分、排序位置。输出层生成的回答、各阶段耗时、是否触发超时。有了这些日志我就能做归因分析。比如回答不完整的案例查日志发现是检索到的文本块太少只有两个块生成时信息不足。于是我把TopK从3调到6情况立刻改善。答非所问的案例则大多是权限过滤把关键文档滤掉了检索返回的是替代文档。这时候问题出在权限规则配置而不是模型本身。我还会定期做线上效果抽样回归每周从日志里随机抽200条问答人工判断是否正确并将结果拆到各知识分类下。长期积累下来我大致知道哪个分类的错误率偏高再去反向优化切分和索引。这个过程很费人力但没有捷径。4.3 效果回归让每一次迭代都可度量上线后我定了一个规矩任何改动包括改提示词、换模型权重、调检索参数都必须先跑一遍离线评测集并记录前后的指标变化。评测集跑完还要在包含真实流量回放的测试集上过一遍防止过拟合到小样本。一次典型的回归流程是写清楚改动意图和影响范围。导出当前线上配置作为基准版本。在离线评测集上跑基准版本和候选版本对比四个核心指标。用线上日志回放50条真实请求人工观察输出质量。评估风险后灰度发布先放5%流量再逐步放量到100%。我在这个流程里吃过亏。有一回只改了切分器的重叠比例离线指标略有上升线上却在某些超长文档场景下检索结果变乱。原因是我没有在回放集里加入超长文档问答这一类典型样本。从那之后评测集里专门加了一个长文档子集每次都单独看它的指标。AI工程的严谨性说到底就是这些细节积累出来的。5. 从零到一线复盘真正的门槛其实在工程环节5.1 我重新理解的AI工程概念这个项目做下来我对AI工程这个标签的理解有了很大变化。AI工程不是训练一个模型而是把模型放进真实业务环境并稳定运转的一整套能力。它包含数据管理、评测体系、部署方案、监控告警、迭代流程以及团队协作规范。模型本身只占了整条链路的一小部分。回头看最耗时间的三个环节分别是数据清洗与切分、离线评测集的建设、线上效果归因。这三件事都不需要高深算法但它们决定了项目的天花板。如果你也在做一个AI项目建议先在纸面上把这三个环节的人力和流程排出来不要全部注意力都放在模型选择上。5.2 给零基础起步者的最后几点建议第一条不要等数据完美了再开工。先拿10%的数据把链路跑通你会更早发现真正的问题。第二条评测集从项目第一天开始攒。做了第一版问答后立刻手动记录失败案例这些内容以后都会成为评测集的一部分。第三条保留每个阶段的实验记录。我之前用表格记录每次改动的参数、指标、结论三个月后回看这张表格比代码注释更有价值。第四条警惕任何玄学调优。如果一项改动解释不通原理就生效了很可能只是在小样本上的一次偶然波动要复测确认。第五条控制技术栈数量。每多一个组件排查链路就多一个黑暗角落。能用数据库扩展解决的就别单独引一个服务。最后分享一个我的个人习惯每次做完一个阶段的迭代我会把当时的判断依据和后来实际发生了什么写进一个单独文档。这些内容写的时候很费劲但等到下一个新项目开始时它就是你最可靠的参考手册。从零起步做AI工程没有想象中那么光鲜大部分时间都是在和数据、日志、不一致的结果较劲。可也正是这些较劲的过程让我真正理解了什么是工程什么是炼金。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Codex × 短视频变现:全景分析——从 Seedance 多模态生成到 AI 编程智能体落地 2026/10/1 14:36:27

Codex × 短视频变现:全景分析——从 Seedance 多模态生成到 AI 编程智能体落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
100万Token上下文到底有多大?一文读懂GPT-5.4与TaoToken的API调用实践 2026/10/1 14:36:27

100万Token上下文到底有多大?一文读懂GPT-5.4与TaoToken的API调用实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Agent 结构化输出工程:别让下游解析“看起来像 JSON“的自由文本 2026/10/1 14:36:27

Agent 结构化输出工程:别让下游解析“看起来像 JSON“的自由文本

Agent 结构化输出工程:别让下游解析"看起来像 JSON"的自由文本 摘要:当 Agent 开始承接真实业务——抽取、分类、编排、跨系统操作——"模型说了什么"远没有"模型输出的东西能不能被机器可靠地消费"重要。本文从真实开发者…

阅读更多 →
2026 秋招财务数字化校招工具栈拆解|JD 与面经复盘 2026/10/1 14:36:27

2026 秋招财务数字化校招工具栈拆解|JD 与面经复盘

一、2026 秋招财务数字化岗位核心工具清单,结合岗位日常工作任务说明2026 秋招财务数字化岗位,应届生核心必备工具包含 Excel、SQL、Power BI,加分工具为 ERP 系统、RPA、Python,这是从 BOSS 直聘、应届生求职网 2026 届校招 JD 提…

阅读更多 →
2026国内大模型API聚合平台横评:TaoToken统一Key接入四大平台核心优势解析 2026/10/1 14:36:27

2026国内大模型API聚合平台横评:TaoToken统一Key接入四大平台核心优势解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Cursor 锁机器码后如何把 Base URL 改到 TaoToken 恢复调用 2026/10/1 14:36:21

Cursor 锁机器码后如何把 Base URL 改到 TaoToken 恢复调用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉