ARTICLE DETAIL

资讯详情

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

从零搭建AI应用系统:避开框架陷阱的工程实践指南

从零搭建AI应用系统:避开框架陷阱的工程实践指南 最近“AI工程”这个词热度很高但市面上的教程要么一上来就教你调LangChain、LlamaIndex这类大而全的框架要么就是又臭又长的理论推导。真到自己动手从零搭一个能稳定跑的AI应用时你会发现能直接用的东西很少。我一直觉得对于工程师来说最好的学习方式不是读文档而是亲手把一个东西用最朴素的方式做出来。今天这篇我就以我最近的一个“ai-engineering-from-scratch”个人项目为主线聊聊我从零开始搭建一个AI应用系统时的完整思考、技术选型、踩坑记录和最终沉淀下来的工程经验。这篇文章适合那些已经会写Python、懂一点机器学习基础但没完整走过一遍AI应用落地全流程的开发者。如果你正打算自己动手搞一个LLM应用不想一上来就被框架绑架这篇文章应该能给你一份很实用的参考地图。1. “从零开始”到底指什么先搞清楚AI工程的边界很多人在看到“from scratch”这个标题时容易走两个极端一种人觉得这是要从线性代数、反向传播手写一个Transformer另一种人觉得这就是用ChatGPT的API调几个接口。说实话这两个都不是我理解中的AI工程。我理解中的“从零开始”是指不依赖某个一体化的大而全框架用Python基础库和必要的底层SDK亲手把AI应用系统的每一个核心环节搭起来。简单说不重造轮子但也不让框架替我思考。AI工程和单纯的“训练模型”或者“调API”都不太一样它其实是一条完整的产品化链路。我把它拆成五个层面数据层、模型层、服务层、评测层、迭代层。数据层解决“喂什么”模型层解决“怎么算”服务层解决“怎么被调用”评测层解决“怎么算好”迭代层解决“怎么持续变好”。这五层缺一不可很多项目死在半路上往往不是模型不行而是数据没管好或者服务一上生产就崩溃。我之所以决定自己从零搭一遍是因为之前用LangChain做过几个Demo确实快但出了问题也确实难查。Prompt拼装逻辑和Agent的状态管理全部被封装在框架内部一旦输出不符合预期你根本不知道是哪一环出了问题。这种“黑盒”在项目早期还能忍越到后期越让人头皮发麻。自己从零写一遍之后最大的收获就是每一个环节的输入输出我都心里有数排查问题的时间至少缩短一半。这其实有点像学做饭和吃预制菜的区别。预制菜加热即食但永远不会知道你做的这道菜里盐放多了应该怎么补救自己从切菜开始做一遍虽然慢但之后你拿到任何菜谱都能立刻判断大概需要什么火候。AI工程也一样框架迭代速度极快今天用的工具三个月后可能就变了但底层的数据流、评测逻辑、服务架构这些东西不会变。把这些基本功从零走通一遍以后再换任何工具都只是换个接口的事。2. 动手前的最关键一步模块拆分与技术选型依据真正写第一行代码之前我先花了两天时间做了一件事画系统架构图。不是用那种正式到吓人的架构图而是简单地列出“我这个系统需要哪些模块、每个模块负责什么、模块之间怎么通信”。这个习惯是从以前做后端服务时带过来的——你不先想清楚模块边界写出来的代码一定会纠结成一团。我当时要做的项目是一个基于开源大模型的文档问答系统用户上传一个文档系统读取内容并做分析然后用户可以用自然语言向文档提问模型基于文档内容回答。听起来很简单对吧但拆开来看至少涉及这些环节文档格式解析PDF、Word、Markdown都可能遇到、文本清洗与切片策略、向量化与存储、检索逻辑、Prompt构造、模型推理、流式输出、日志与可观测性。每一个环节都值得单独做一个模块这也是我第一个重要的架构决策——不搞一个大文件通吃而是每个环节独立成模块通过定义清晰的输入输出接口来连接。技术选型上我给自己定了四个原则数据层用最普通的SQLite存元数据用文件系统存原始文档用向量数据库存切片向量。不引入太重的基础设施等量级上来了再换也不迟。模型层选一个开源可商用的中量级模型我当时选了Qwen系列的中等尺寸版本先不微调用Prompt工程验证效果把推理服务跑通后再考虑要不要微调。服务层用FastAPI做HTTP接口层用异步方式处理请求流式响应必须支持——LLM应用的体验好坏流式输出占一半。评测层先准备20个真实业务场景的问题作为冒烟测试集等基础跑通后扩大到100个以上做回归。这些决策看起来平平无奇但每一个背后都有理由。比如说为什么不用Docker Compose把向量数据库、模型服务、应用服务全部编排起来因为项目还在快速迭代期容器化带来的环境一致性收益还体现不出来反而每次改代码都要重新构建镜像拖慢节奏。等系统功能稳定了再容器化半小时就能搞定。很多人一上来就套K8s结果一个Demo调了三天还跑不通这就是典型的把复杂度前置了。整个技术栈的选择思路可以总结成一个原则能用文件解决的问题不引数据库能用数据库解决的问题不引消息队列能手动解决的先不自动脚本化。AI应用的核心复杂度在于模型和数据的处理而不在于基础设施有多花哨。把有限的时间花在模型效果和评测闭环上才是正事。3. 数据链路才是AI工程的隐形地基也是最容易翻车的部分我敢说十个AI项目里至少有八个在数据环节埋了雷。文档问答系统的数据链路尤其典型因为输入数据的格式混乱程度远超想象。我处理过的文档里有扫描版的PDF文字层都没有有排版花哨的公众号导出文章有带了大量批注的Word文件还有嵌套了多层表格的Markdown。任何一步处理不到位后面检索的质量就直线下降。文档解析这一步我的经验是先按格式分策略再统一成中间表示。PDF用pdfplumber提取文字遇到扫描版先调用OCR引擎Word用python-docx从结构化节点里抽段落和表格Markdown最简单直接按标题层级切块就行。所有格式解析完之后统统统一成一种“块”结构——每个块包含文本内容、来源信息文件名、页码或标题路径、层级信息。这一步非常重要因为后续的切片、向量化、检索都要基于这个统一的块结构来做。切片的策略我反复调了三次才找到一个比较稳的组合。最初图省事直接按固定字符数切比如每500字切一片相邻重叠50字。实际跑下来效果很差经常把一个完整的语义段落拦腰截断检索回来的片段前言不搭后语。后来我改成按标题层级做结构化切分ManMarkdown文档按##、###切PDF按标题字体或大纲切结合固定长度的回退机制。这个方案的召回质量明显好了很多命中片段的可读性大幅提升。数据清洗方面我踩了一个印象很深的坑文档里的页眉页脚、重复水印和乱码一堆进去之后向量化质量被显著拉低。有个用户的文档每页都带公司名称的水印结果检索时模型老是答非所问排查半天才定位到是这些噪声文本污染了向量语义。最后我加了几条清洗规则去除页眉页脚用正则匹配常见模式、去除连续重复两行以上的文本、把全角字符转半角、去除不可见unicode字符。这几条规则看起来土但效果立竿见影。数据版本管理是我最初没想到、后来补上了并且庆幸补上的模块。我在SQLite里给每一批导入的文档建了批次记录记录文件名、文件哈希、切片数量、清洗规则版本、切词器版本。为什么连切片器版本都要记因为后面一旦改了切片策略旧的向量索引就和新策略不匹配了评测结果会失真你根本不知道效果波动是来自模型还是来自数据预处理。有版本记录之后我随时可以回溯“用旧策略重新生成向量”来做对比实验。这个习惯是从传统软件工程的版本管理迁移过来的但在AI工程里尤为重要——因为数据的任何微小变化都可能传导到最终效果上。提示如果你也想自己搭文档问答系统建议从第一天就建立一个“数据血缘”的概念每一份数据从原始文档到清洗后文本到切片到向量每一步都要能追溯。后期调优全靠这个底子。4. 模型层的核心抉择微调还是Prompt工程我为什么先选后者到了模型层很多人最纠结的问题就是“我要不要微调”我的答案很明确除非Prompt工程已经验证了天花板否则先别微调。这不是因为我排斥微调而是因为微调的成本和风险在你还没有建立评测闭环之前是无法量化的。你花一周时间微调了一个模型效果变好了但你既不知道是数据起了作用还是超参碰巧调好了这种“碰运气”式的优化对工程来说是不可接受的。我先用Prompt工程把一个中量级开源模型的能力榨到了极限。具体来说做了三件事一是设计了一套带角色设定和约束条件的前缀模板让模型明确“你是一个文档分析助手只能基于用户提供的文档内容回答不能编造”二是加了Few-shot示例从真实的业务数据里挑了几个具有代表性的问答对放在Prompt里三是实现了Function Calling风格的调用逻辑——虽然底层是普通的文本生成但在Prompt里严格定义了JSON输出格式让模型先输出答案再输出引用片段位置方便后续做可追溯性展示。这个阶段的关键是“把Prompt当成代码来管理”。我的Prompt模板不是写死的字符串而是版本化的、支持变量插值的结构化模板。每个模板都有命名和版本号评测时可以并行调用多个模板版本对比结果。很多人改Prompt是一通乱改改完觉得“好像变好了”但这种感觉是靠不住的必须让评测数据来说话。关于开源模型还是API的选择我当时的理由是用开源模型虽然部署麻烦一些但数据不出本地响应内容可控成本结构清晰而且我可以看清楚模型的真实能力边界。API方案的优势是省事、效果上限高但如果要做成产品长期来看单位请求成本会是一个绕不开的问题。我身边的案例里超过一半的项目最先淘汰的方案就是纯API因为效果和成本不可兼得的时候产品根本活不下来。这里还必须提醒一个我在实践中印象极深的问题再强的模型也救不了坏掉的检索。我一开始天真地以为模型能力到位了效果自然好结果实际测试发现当检索回来的片段里没有正确答案时模型会一本正经地编造答案。后来我加了“检索置信度”机制如果检索结果的相似度分数低于某个阈值就让模型明确回答“文档中没有相关内容”而不是硬编。这一个改动让系统的胡说八道比例骤降比换一个更大的模型有用多了。5. 服务化和评测闭环让AI系统从“能跑”到“能用”模型在笔记本上跑通是一回事作为一个服务稳定对外提供能力是另一回事。服务化这层水也挺深最核心的不是并发量有多大而是要做到三件事可控的输入输出、稳定的异常处理、完整的调用记录。我基于FastAPI写了一个轻量级的服务层每个请求进来先做参数校验然后走完整的处理链路——检索、构造Prompt、调用模型、解析结果、记录日志——最后通过流式响应把内容吐给前端。流式输出这块我要重点说一下。LLM应用如果做成等全部生成完再一次性返回用户的等待体验会非常糟糕尤其是回答比较长的时候。FastAPI配合异步生成器可以比较方便地实现流式返回我之前写过一篇技术笔记专门讲IterableResponse和异步生成器的配合方式。实测下来同样的回答内容流式返回的用户主观等待感比非流式降低了不止一半这个体验投入产出比极高。然后是评测闭环这是我整个项目里认为做得最值的一个模块。我建立了一个评测集包含三个维度的测试用例业务准确性问题答案是否正确、检索召回问题相关片段是否被召回、拒答边界问题文档里没有的内容是否不乱回答。每一轮改完Prompt或者调完检索参数我就在这套评测集上跑一遍把通过率和失败案例记录下来。评测指标不能只看准确率一项。我在跑评测时会同步记录这些指标平均响应延迟、平均Token消耗、失败请求比例、拒绝回答的比例。延迟和成本往往被新手忽略但它们才是一个AI系统能不能长期跑下去的关键。我给自己定的底线是单次问答控制在5秒内流式成本控制在可接受范围里如果超了就定位问题——是检索太慢、模型推理太慢还是Prompt太长消耗了太多Token。评测集本身也需要不断迭代。我每周会从线上真实日志中挑出10个新的问题补充进评测集尤其是那些模型回答不对、或者用户问了但没得到满意答案的case。这样做的好处是评测集永远不会脱离真实业务场景。这种做法的局限性在于“如果你自己的理解有偏差评测集也会往偏的方向走”所以我们后来引入了多人交叉评审——我自己过一遍之后再拉一位同事用新的视角看一遍错误案例会发现很多我忽略掉的问题。6. 那些文档里不会写的工程经验延迟、成本与系统脆弱性这部分我想聊一些不太会在官方文档和教程里出现、但实际做项目时一定会遇到的东西。第一个是关于延迟和成本的“架构阶段预算”。很多人等到系统上线了才被账单吓一跳才开始优化但这时候往往已经晚了。我建议在架构阶段就做一个简单的估算假设日均请求量是1000次每次请求平均消耗2000个Token模型推理成本是多少向量检索的硬件成本是多少总月成本大概多少。用这个数字来判断方案的可行性。我见过不止一个项目技术方案本身很漂亮但一算成本发现比商业API还贵那就完全没有自研的必要了。第二个是关于模型的“不可控性”处理。LLM和传统软件最大的区别在于它是概率系统不是确定性系统。同样的Prompt换个采样参数结果可能就变了。我吃到教训的地方是线上服务里千万要把Temperature设成固定值并且关闭随机性强的采样策略否则同一道题用户上午问和下午问得到的答案可能不一样。这在客服、法务、医疗等对一致性有要求的业务场景里是硬伤。我后来加了“同题一致性”评测专门抽10个固定问题反复提问对比输出的稳定性。第三个是关于系统脆弱性的心理预期。AI工程的脆弱性是常态模型服务可能OOM、向量库可能连接超时、上游API可能限流。我做的应对是把每一个外部依赖都包上超时和重试机制并且设置降级路径——模型服务挂了至少有返回“服务暂不可用”的能力而不是让请求一直挂到超时。这里面最容易被忽视的是“降级路径的测试”。很多系统写着有fallback逻辑但从不测试真到挂了才发现fallback也是坏的。我会在每次发版时顺手模拟一下服务异常确认降级逻辑是通的。第四个是关于人力的投入预期。AI项目的迭代不是一锤子买卖Prompt要持续调、评测集要持续扩、数据清洗规则要持续加。我给自己定的节奏是每天投入两小时做一轮“评测→分析→优化”的循环周末做一次大版本更新。这种持续投入比一次性憋大招有效得多因为模型的行为空间太大了不靠高频反馈你根本摸不清楚它在你业务上的脾气。7. 新手路径建议如果你也要从零搭一个AI项目文章最后我想给准备动手做类似项目的新手一条可行的路径建议。这个路径我自己走过一遍虽然不算最优但至少是踩过坑之后验证过的。第一步选一个“窄而具体”的场景。不要一上来就做“企业级AI助手”这种大而全的东西选一个具体的、边界清晰的场景——比如“基于指定文档的问答”“销售话术生成”“周报自动总结”。场景越窄数据越可控评测越容易做开发越容易起步。第二步用最快的方式把端到端的链路跑通。不用管效果好不好哪怕直接用开源模型的原始能力先把“文档进来→检索→生成→返回”整个流程走一遍。这步的目的是建立全局认识找到每一环节真正的瓶颈在哪里。很多人废了半天时间在优化单点结果最后发现整个链路的瓶颈根本不在那个点上。第三步建立评测集和评测流程。这一步越早做越好甚至应该在写业务代码之前就开始。把你要解决的问题变成几十个具体的问题和标准答案然后让系统去跑。评测集是AI工程的“红绿灯”没有红绿灯你开着车也分不清方向。第四步基于评测结果做迭代。每改一个地方——不管是Prompt、切片策略还是检索参数——跑一遍评测记录变化。这个循环本身就是一个很好的自我反馈机制改对了就固化下来改错了就回滚重来。全部流程走完你做AI工程的底子就立住了。第五步把工程化的习惯补上日志、版本、监控、降级。这些不性感但早晚要还债的东西越早做越好。我在自己做项目的时候没有优先做日志和版本记录导致中途排查问题花费了额外的时间这是我后期补齐后才切身体会到的教训。这一套走下来不敢说你已经成了AI工程专家但至少你具备了一个很重要的能力——面对一个新的AI应用需求时你脑子里的第一反应不再是“该用什么框架”而是“这个系统需要哪几个模块、每个模块怎么评测、哪里埋了坑”。在我看来这就是“从零开始”最大的价值。
返回列表