尧图精选

从零构建AI应用:大模型工程化落地的完整实践指南

🕒 发布时间:2026/10/2 11:26:21 📁 来源:尧图网络
1. 项目概述从零开始AI工程的完整路径如果你最近两三周一直在各种AI群里潜水大概率会看到两类人一类是拿ChatGPT写周报、让Midjourney出头像的普通用户另一类是张口闭口上下文窗口向量检索模型微调的工程派。这两类人的差距恰恰就是这个项目标题想填平的鸿沟——ai-engineering from scratch从零开始做AI工程。我想先说清楚一件事AI工程不等于调API。它是一整套把大模型能力落地成稳定、可控、可评测的系统工程能力。我在这个项目里做的事情就是把一个完整的AI应用从零搭起来不靠现成的一站式平台而是亲手走完需求拆解、技术选型、核心代码、评估回归、成本控制的全流程。整篇内容适合三类人刚入门想系统了解AI工程全貌的人已经会用API但总感觉差点意思的开发者以及需要给团队做技术预研的人。说白了这个项目的价值在于它帮你把会用AI升级成能造AI系统。读完你会清楚一条提示词是怎么变成一次可靠的服务调用的一个检索库是怎么跟大模型配合回答问题的以及为什么别人的AI应用看起来聪明你的却总是胡说八道。下面我把整个项目的核心思路、实操细节和踩坑记录全部摊开按我实际执行的顺序来讲。2. 为什么强调从零开始先扎马步再打拳2.1 从会调用到会设计的关键跨越很多人第一次接触大模型API时兴奋感来自一句话就能让模型干活。但一旦你开始做真正的工程第一个打击就来了同样的提示词今天好用明天不好用换了模型版本输出风格完全变样参数稍微调大一点连格式都保不住。我在项目启动前给自己的定位很明确不直接抄别人的Demo而是从最底层的问题开始问自己——什么是token为什么上下文有上限温度参数到底在控制什么这些听起来基础的问题恰恰是后期排查问题时的救命稻草。举个例子我在这项目里要做一个文档问答助手。最初版本简单粗暴把用户问题直接丢给模型让它凭记忆回答。结果发现两个明显的毛病——第一回答含糊经常答非所问第二模型压根不知道我给的文档里写了什么。这时候如果不懂检索增强的原理你只会去堆提示词但真正该做的是把外部知识检索进来再喂给模型。这个认知转变就是调用者和设计者的分界线。2.2 你需要先建立的五个基础认知根据我这次从零搭建的经验动手之前先想明白这五件事后面会省掉大量返工第一模型是概率系统不是数据库。它不知道答案它是在概率上推断最合理的下一个词。所以你不能指望它像查表一样返回稳定结果。第二一切性能问题的根源在上下文。输入太长会超窗口输入太短信息不够中间没有一个完美平衡点。上下文管理是最花时间、最考验设计能力的部分。第三质量不靠感觉靠评估。我在项目里建了一套测试集每条输入都有标准的期望输出每次改动代码都拿这套测试集去跑看准确率是升是降。没有这个过程你永远在盲调。第四成本是工程指标的一部分。一次调用几毛钱看着不贵但流量大了以后提示词多一个token都是钱。工程师必须对token成本敏感。第五AI工程的主战场在后处理。模型输出你要校验格式、清洗噪音、处理失败情况这些脏活累活才是工程化的核心。这五个认知是后面所有章节的地基。我接下来讲的每一个具体操作背后都是围绕这五个点在转。3. 核心细节解析AI工程的基本功3.1 Token与上下文窗口一切性能的起点先花三分半钟把token这件事说透。Token是模型处理文本的最小单位它可以是一个词、半个词、一个标点甚至一个字节。中文尤其费token因为一个汉字可能对应一到两个token英文一个单词往往就是一两个token。你心里要有本账1000个汉字大约对应1500到2500个token具体看分词方式。我项目里用的模型上下文窗口是128K token听起来很大但实际操作中根本不能按满额用。原因有三一是窗口越大单次调用的延迟和成本都上升二是长上下文对模型注意力有稀释效应塞太多无关内容关键信息反而被淹没三是留出给模型发挥输出的空间。实践下来我维持一个原则输入控制在窗口上限的六成以内输出留两成剩下两成做缓冲。这里给你一个我实测过的token估算方法请求内容包含系统提示词、历史对话、检索到的知识片段、用户当前问题四大块。系统提示词控制在100到200个token历史对话按最近十轮截断检索片段每段控制在200到300个token优先保以保留与问题相关性最高的前两三段。这样设计之后单次请求的总token量基本稳定在1500以内既不会超窗口也留够了回答空间。3.2 提示词工程不是写作文是写接口我把提示词当接口设计来对待。接口要有清晰的输入输出约定、错误处理和版本管理。普通用户用提示词是你要帮我写一份总结工程师写提示词是给定以下会议记录文本提取决策项、负责人和截止日期以JSON格式返回字段名为decision、owner、deadline若信息缺失填null。这个差异用代码类比更好懂前者像你跟实习生口头交代工作后者像你给函数写文档字符串和类型签名。我在项目里把提示词拆成四个固定部分角色定义——先说清楚模型在这个任务中扮演什么角色比如你是一个严谨的代码审查助手。这不能玄学它的作用是稳定模型的语气和关注点。任务描述——一句话讲清楚要干什么越具体越好。总结这篇文档是模糊的提取这篇文档中的三个核心论点每个论点用不超过50个字概括是可执行的。输入格式说明——告诉模型输入长什么样有几种形式异常情况怎么处理。我在实战里发现这一步特别重要模型如果知道可能会收到空值或者乱码它在异常情况下的行为会稳定很多。输出格式约束——明确规定返回结构。要JSON就必须给字段名和示例要列表就必须说明排序规则。我在项目里所有涉及结构化输出的地方都强制要求模型先输出一个固定前缀再输出内容这样解析逻辑好写得多。还有一个我踩过几次坑后的心得提示词里禁止出现可能也许试试看这类模糊词语。这些词会让模型在不确定时更容易发散直接降低输出的稳定性。尽量全用肯定句和祈使句。3.3 结构化输出让模型按你的格式交卷AI工程里最让人头疼的其实就是格式问题。模型输出的文本你要拿来直接对接业务逻辑如果今天是JSON明天是散文你的下游代码就没法写。所以我从项目一开始就决定所有面向系统的输出一律走结构化路线。我采用的方式是双保险第一层是提示词的格式约束给出明确的JSON示例第二层是代码层的格式校验和纠错用正则或者轻量解析库提取模型输出中疑似JSON的部分再做一次加载。加载失败就自动调一次修正API把模型输出和错误信息一起传给模型让它自己改正。实测下来这个闭环能把格式正确率从九成左右拉升到接近满分。这里有个细节值得说某些模型后端原生支持JSON模式会从解码层面保证输出合法JSON。能用就用能大幅简化你的解析逻辑。我的建议是任何时候都优先开原生JSON模式再叠加提示词约束最后用代码校验兜底。三层保护之下格式基本就不是问题了。3.4 上下文管理记忆是系统工程单轮对话的模型是没记忆的。你上一句问了什么它下一句就忘了。所谓多轮对话能力其实是工程师把历史消息一股脑塞回请求里。所以记忆不是模型能力而是你的系统设计。我在这个项目里做了一套简单的上下文管理方案核心是三层记忆固定记忆放用户画像和长期偏好保存在应用数据库里每次请求都注入工作记忆保存最近几轮对话按轮数截断超了就淘汰最旧的场景记忆保存当前任务相关的临时信息比如正在处理的文档ID、当前步骤状态。截断策略我试验过几种最后用的是按token量加轮数的双重限制。对话记录超过十轮或累计超过1500个token就触发裁剪。裁剪不是简单删除而是把早期对话压缩成一句摘要塞进系统提示词里。比如原始对话里用户反复确认了某个需求压缩后就变成用户偏好简短回复风格一句话。这样既能保留关键信息又不会让上下文无限膨胀。你如果自己搭系统我建议不要跳过这个环节。很多AI应用看起来傻不是模型不行而是上下文管理没做好——该记的没记不该记的占地方最后模型被一堆无关历史干扰。4. 实操过程从零搭建一个可用的AI问答系统4.1 项目骨架先定边界再写代码动手写代码之前我花了差不多一个晚上只做一件事画边界。这个系统到底解决什么问题不解决什么问题。边界不划清楚后面会被各种顺带加个功能的念头带偏。我这次做的是一个内部知识库问答系统。边界如下支持上传PDF和Markdown文档支持基于文档内容的提问输出带引用来源。明确不做的不做语音、不做多模态、不做跨文档对比。划清楚之后所有技术选型都围绕这三个能力展开思路清晰了很多。技术栈我最终选定的是Python作为主语言FastAPI做接口层轻量级向量检索方案做知识召回前端只做了一个极简的网页测试入口。之所以不选重型框架是因为这个项目核心要验证的是AI应用链路不是在选型上堆复杂度。4.2 环境准备与依赖安装环境这块我踩过一个不小的坑必须提醒你。Python版本直接决定你后面装包的顺利程度我最初在3.10环境下有几个依赖老是冲突换到3.11之后一次通过。建议你直接新建虚拟环境不要偷懒用全局环境。我的操作顺序是先装基础库FastAPI、uvicorn、python-dotenv再装模型SDK最后装文档解析和向量相关库。这里有个实用小技巧——把依赖按必须的和可选的分开装。核心链路用到的包第一时间装好增强功能比如PDF解析里的OCR增强放到后面按需再装这样能避免一次性引入大量包导致版本冲突。装完依赖后我会做一件事写一个五行的最小调用脚本确认模型API能通、返回正常。很多项目的第一个卡点根本不是代码逻辑而是密钥没配好、网络不通、账号没有权限。先跑通最小闭环比写一大堆代码再debug要高效得多。4.3 核心链路实现文档导入、切片、向量化、检索增强这块是整个项目的主心骨也是从零搭建最有含金量的部分。完整的RAG链路我拆成四步走第一步文档解析与清洗。PDF要提取文本Markdown要保持标题层级同时要统一编码格式。这里有个容易忽略的坑源文档里的大段噪声页眉页脚、表格乱码、无关的水印文字会直接污染后面的切片质量。我在清洗环节专门写了一个过滤器剔除明显的无意义行再把连续空白压缩。第二步文本切片。切片策略直接影响检索质量这是我在项目里花时间最多的地方。我按结构优先、长度锚定的方式来做Markdown文档优先按标题分块遇到超长段落再按长度二次拆分。块大小我最终定为每块300到500个token相邻块之间保留50个token的重叠。这个重叠很重要它保证了一个完整语义被切开后检索时至少有一块能覆盖到上下文。切完还要给每块生成一个元数据标签包括来源文档、章节路径、块序号。这些元数据在给用户展示引用来源时是必需品。第三步向量化入库。向量化就是把文本变成一串浮点数让语义接近的文本在数值空间中距离更近。这一步我直接用模型自带的嵌入接口把所有切片逐批转成向量存进向量库。嵌入维度不用你操心模型会给你固定值。你真正要关注的是检索时的相似度阈值怎么定——我在项目里用余弦相似度阈值调到0.72左右比较舒服低于这个值的召回结果基本都不相关直接不要。第四步检索与生成。用户提问来了之后先把问题向量化到库里找出最相似的几块文本拼装成上下文喂给模型。这里有一个关键的细节不要把原始检索结果原样塞给模型要按相关度排序并标注来源。我在提示词里告诉模型以下信息来自内部资料回答时优先依据这些内容如果资料中没有答案明确说不知道不要编造。这句话看着简单但对减少幻觉非常有效。4.4 评估与回归没有评估就没有工程我在项目中期遇到一个尴尬情况改了一段提示词自测两个问题都变好了但在更全面的测试集上一跑准确率反而降了三个百分点。那一刻我意识到没有评估体系的AI项目就是盲人摸象。所以我在项目里搭了一个极简但有效的评估流程。先建了大概五十条测试样例覆盖了系统该答的、不该答的、边界含糊的三种情况每条都人工写好期望答案。每次改动后全量跑一遍记录三类指标准确率回答是否命中要点、引用率引用来源是否真实、拒答率不知道时是否老实说不知道。这三个指标分别对应系统质量、可追溯性和诚实性缺一个都不行。评估跑完还不够要把失败案例记录下来归因。我自己的流程是失败案例先看是不是检索漏了→再看是不是上下文拼装丢了→最后猜是不是模型理解跑偏。按这个顺序排查百分之八十的失败其实都出在检索和上下文上模型本身很少是罪魁祸首。这个认知很重要因为它意味着你的优化重心应该放在前面两环而不是死磕提示词。5. 常见问题与排查技巧实录5.1 输出格式从JSON变成散文怎么修这是我在接入不同模型时遇到最频繁的问题。同一个提示词A模型规规矩矩给JSONB模型就是喜欢加一段好的下面是我的回答。原因在于不同模型对指令的遵循程度不一样而且它们的基座训练数据里JSON往往出现在散文上下文里模型可能模仿了那种风格。我的修复思路是三层兜底首先明确提示词要求只输出JSON对象不要额外解释并把示例从一段补全成三组不同情况正常、空值、多结果其次开启原生的JSON模式让解码层限制输出最后代码层加解析器先从模型返回里抽离疑似JSON片段再做加载和字段校验。这样处理后格式问题基本绝迹。5.2 答案越来越长费用水涨船高项目上线跑了一周后我看账单发现成本比预想高了三倍。追查下去发现原因不在模型调用次数而在于一次失败的格式化调用会触发重试每次重试都按满token计费。另外历史对话没有做截断导致每一轮请求都携带了越来越长的上下文费用是递增的。解决方式有两个第一是给输出长度设置上限max_tokens参数设到够用的数值即可比如一般问答512就够了不需要默认的2048第二是上下文压缩策略前面说过的按轮数和token量双阈值裁剪这里直接见效。账单一下子降到了原来的四成左右而且改写后延迟还更快了。这件事给我一个教训成本控制从第一天就要设计进去而不是等账单报警再补。5.3 模型总是一本正经地胡说八道幻觉问题在知识库问答里最致命。用户问一个文档里没有的内容模型居然能编出一个有模有样的答案带着来源引用。这个问题我在项目里遇到过两次排查后原因各异。第一次是检索召回的相关片段本身跟问题无关但模型还是拿它当了素材于是明显露馅。修复方式是在提示词里加了若提供的资料与问题不相关请告知用户无法回答。第二次是切片的锅。源文档里有一句话的过度总结切片后变成一个孤立的断言模型把它当成事实输出了。这个比较难防只能靠评估集里的幻觉检查用例来兜底。我自己最后的经验是幻觉无法消除只能压低概率。能做的就三件事——检索质量要过硬、提示词里明确不知道就说不知道、输出中强制附带来源让用户能追溯判断。5.4 检索不到相关内容回答质量崩了如果你发现系统答非所问先别急着调提示词大概率是检索环节没召回相关内容。我调试时常用的一个手段是把检索结果直接打印出来看召回的都是什么。很多次我一看就知道问题出在切片上——有意义的上下文被拦腰截断或者切片太细碎语义不完整。这类问题我整理了一个排查顺序表可以按这个顺序逐个过排查点可能原因验证手段文档解析异常表格被拆散、编码问题导致文本缺失直接查看清洗后的纯文本切片不合理块太小/太大、关键上下文被切断检查切片边界附近文本是否语义完整嵌入模型不匹配查询和文档用了不同的嵌入接口核对嵌入模型版本与参数一致性阈值太严/太松相似度阈值过滤掉了有效结果或引入了噪声输出候选分数做分布分析提示词上下文拼装错误检索结果未按相关度排序权威片段被埋没检查拼装后的提示词全文这套排查表救了我很多次。可以说百分之九十的模型回答差问题最后定位都在检索链路而不是模型本身。6. 工具选型解析哪些该用哪些没必要6.1 框架之争LangChain、LlamaIndex 还是裸代码这个项目我做了一个比较反主流的选择核心链路不用重量级框架而是手写。不是说框架不好而是从零开始这个项目的目的就是理解底层细节如果直接套框架你等于买了一个集成厨房但不知道火是从哪来的。但我要诚实地指出如果你做的是生产环境项目时间紧、需求多成熟的编排框架值得考虑。LangChain的优势是生态丰富Agent、工具调用、记忆管理都现成LlamaIndex在文档处理尤其是检索增强方面做得很深。它们的劣势也同样明显——封装层级多出了诡异问题排查成本高而且版本升级时API变动频繁升级一把就得改一堆代码。我的建议很直白先用手写代码跑通一条最小链路理解每一环在干什么然后再决定要不要上框架。框架是节省时间的工具不是帮你逃避理解的拐杖。顺序错了后面调试时你会抓瞎。6.2 模型选型通用模型还是专用模型做AI工程逃不开选模型这个问题。我在项目里分别测了通用对话模型和偏推理型模型两个方向。通用模型的中文理解好、对话自然但复杂任务指令遵循能力弱一些推理型模型在逻辑拆解、多步任务上表现更强但中文对话风格有时候偏机械。选型有个务实原则主链路用什么模型取决于任务的推理密度。纯问答类任务通用模型性价比更好需要工具调用、代码生成、多步推理的任务应该上推理能力更强的模型。我这个知识库问答系统主链路用通用模型就够但做文档精读摘要的子任务会切到推理型模型效果提升很明显。模型切换带来的一个头疼问题是提示词可能需要重新适配。同一个提示词在这家好用到那家就不一定遵循。我的对策是设计提示词时尽量用通用表达避免只对某一模型有效的小技巧并且每次切换模型后必须全量跑一遍评估集再上线。6.3 向量数据库别在最不重要的环节纠结很多AI工程新手一上来就在向量数据库选型上纠结半天什么向量索引算法、HNSW参数、磁盘vs内存研究得比主线还深。我的实际体会是中小规模项目百万级向量以下向量数据库的差异没有你想象的那么大。你用开源的轻量方案或者直接用云服务的向量接口性能都完全够用。真正影响检索质量的不是向量库本身而是两件事嵌入模型选得好不好、切片做得好不好。同样的数据切片优化之后检索效果可能翻倍但换一个向量库几乎感觉不到差别。所以我的建议是别在存储层过度设计把时间花在数据预处理和检索质量调优上收益高得多。7. 最后说几句掏心窝的话这个项目做下来我最深的体会是AI工程的核心不在于会调用模型而在于能设计围绕模型的系统。模型是大脑但大脑需要消化系统喂食知识检索、需要神经系统传递信号工作流编排、需要免疫系统防御错误评估与校验。每一项都是工程问题都需要扎扎实实的代码和测试去解决。如果你也想从零走一遍这条路我给你一个最低成本的起步建议找一个你真正关心的领域收集大概二三十份文档然后从手写一个最简单的文档进、答案出脚本开始。先不追求功能多就追求一句话问出去能带着真实引用来源返回一个像样的答案。等你把这条链路跑通再去加功能、换模型、上框架每一步都有底气得很多。最后再分享一个小技巧给项目写一个修改日志把每次改了什么提示词、动了哪个阈值、评估指标变化多少都记录下来。我这次项目无数次回头查看上一次为什么效果好全靠这份日志。AI工程的调优往往不是线性的有时候你改了一处另一处莫名其妙变差了没有日志你根本无从复盘。路是走出来的AI工程更是踩坑踩出来的。希望这篇内容能帮你把第一脚迈得稳一点。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →