资讯动态

大模型应用开发实战:从选型到RAG落地的踩坑总结

发布时间:2026/10/20 16:34:48 来源:尧图企业网站定制
前阵子接手的一个内部工具准备接入大模型从选型、接口联调、到后来发现问题再迭代我把整个过程的笔记重新整理了一遍正好可以作为 ACP-LLM 这个实战专题的第一篇来发。这不是什么从原理到数学公式的教科书也不是教你怎么写论文式提示词而是把大模型真正用到业务里时一个从业者踩完坑之后的总结。如果你正准备做大模型应用开发、备考相关认证或者想把手头项目快速接入 LLM这篇的内容应该对你有用。我先把话说在前面大模型项目最坑的地方往往不在模型本身而在你一开始就选错了使用方式。这篇就围绕这个主题从需求判断、基础概念、第一段 API 代码、RAG 落地、问题排查到效果评测展开聊。1. 开工前必须想清楚的几件事1.1 大模型不是银弹先认清能力边界很多人第一次接触大模型都会被它的对话能力震撼直觉觉得“什么都能干”。实际上真把它放到业务里你会发现它像一个知识面极广但有时候会一本正经胡说的同事。它擅长的是文本生成、摘要、分类、信息抽取、代码生成这类自然语言任务但在精确计算、多跳推理、长文档精确检索上并不靠谱。比如你让它“从这份合同里找出所有违约金超过总金额10%的条款并汇总金额”如果合同很长、条款很多它极有可能漏掉某几条甚至把相似但不完全符合条件的条款也捞进来。我做过的几个项目里最典型的翻车场景是让大模型直接算数字。模型不是计算器它内部的每个token都是概率预测出来的让它算三位数乘法都可能出错。这一点不是调prompt能根本解决的你需要的可能是让模型调用外部计算工具。所以开工前最重要的一件事不是选什么模型而是把业务需求拆成“大模型适合干的事”和“不适合干的事”后者就交给规则代码或其他工具。1.2 场景分类决定了模型选型市面上的模型服务很多从参数规模、上下文长度、价格到延迟差异都不小。我建议先把自己的使用场景分好类再考虑选型对话交互类客服助手、陪聊、办公辅助。这类场景对延迟和交互体验敏感选响应快、价格适中的模型。知识问答类内部文档问答、产品手册问答。这种一般要搭配RAG检索增强生成对上下文长度和指令遵循能力要求较高。内容生成类文案生成、内容润色、代码生成。对输出质量和创造力要求高可以选强一点的模型。结构化抽取类从文本中抽实体、抽关键字段。这种不一定要最大模型指令遵循能力强的模型反而更划算。一个常见的认知误区是“越大越好”。我见过某公司为了应付领导直接调用最大参数的模型做日志自动分类成本高、速度慢而且因为最大模型有时候反而更容易在简单任务上“多想”分类准确率并没有比小模型高多少。选型技巧就是把一份简单任务、一份中等难度任务、一份复杂任务分别拿去试用一套固定的评测集跑一遍再结合价格和延迟做综合判断。1.3 给项目设定一个“不确定”预期传统软件开发的逻辑是输入固定、逻辑固定、输出可预期。大模型应用则不一样同样的输入今天和明天的输出可能略有差异而且这种差异你还控制不住。项目排期的时候如果不预留模型调优和评测的时间最后大概率靠加班弥补。我自己的体感是一个“看起来不难”的LLM功能从能跑到真正稳定可用中间至少还要花两到三倍的时间去处理边界情况。所以建议在项目规划阶段就明确哪些输出是“模型生成、人工可改”的哪些输出是“必须严格结构化、出错了会背锅”的。前者可以大胆用模型后者就要在前面加规则校验、后面加兜底逻辑。提前把预期和架构对齐后面能省掉很多返工。2. 大模型应用开发绕不开的核心概念2.1 Token计费单位也是性能上限Token是大模型处理文本的基本单位。简单理解模型不是按“字”读文本而是把文本切成一堆token片段。中文里一个字大概对应1到2个token英文一个词大概1到1.5个token。这个细节决定了你算成本的时候不能直接拿字数去估。另一个重要影响是上下文窗口也就是模型一次会话最多能“看到”的token数量。比如一个模型的上下文是8K大约就是几千个汉字。你发一段很长的文档给它加上它的回答可能直接顶到上限。这不仅仅是能不能放得下的问题当输入接近窗口上限时模型的注意力会被稀释早期的关键信息可能在生成答案时被“遗忘”。很多用户反馈“模型记不住我开头说的要求”排查下来往往不是模型的问题而是输入太长了中间的文本把关键信息淹没了。所以我建议在任何一轮对话里都要有“token预算”的意识。发什么、不发什么不是随意的长文档先用摘要或检索抽出一部分内容再喂给模型效果和成本都会友好很多。2.2 temperature和top_p控制随机性的水龙头模型生成文本时有一个采样过程不是每次都选概率最高的词而是根据概率分布随机挑选。temperature就是你控制这个随机程度的参数。温度调低比如接近0模型输出更确定、更保守温度调高输出更多样、更有“创意”但也更容易跑偏。top_p则是另一套控制方式按累积概率截断候选词。比如top_p0.1意味着只从累积概率达到10%的那些候选词里采样。实践中更推荐先固定top_p再微调temperature不要两个一起乱调。分类、信息抽取这类任务temperature果断调成0或者0.1文案创作、头脑风暴再往上调。我踩过最蠢的一个坑是给信息抽取任务设了较高的temperature导致同一个规则文本每次抽出来的字段都不一样还以为是模型不稳定。2.3 提示词的三层结构大模型应用的提示词通常分成三层系统提示词定义模型角色、任务目标和全局约束。这部分一句话就能决定模型整体行为模式。用户提示词提交具体的内容和需求。不同用户的输入可能差别很大要做好清洗和格式化。助手回复模型输出的内容也可以作为下一轮对话的历史上下文。这一层里的系统提示词最值得下功夫。我在实际项目里总结了几个比较有效的写法原则明确角色例如“你是一个物流客服助手”。不要含糊。明确输出格式比如“只输出JSON不要包含其他文字”。明确边界例如“如果信息不足请直接回答不清楚不要编造”。明确负面指令比如“不要询问用户直接根据已有信息解答”。把这些说明写在系统提示词里比你在每一轮用户问题后面重复强调要稳定得多。还有一个经验提示词要像代码一样做版本管理。每次改完保存一条记录标注改了哪句、效果变化是什么。模型输出的问题很多时候要靠回溯提示词版本才能定位。3. 从0到1做出第一个LLM应用3.1 环境准备与接口接入具体代码示例之前先把环境准备好。大多数大模型服务商的SDK都提供Python和Node.js版本这里以Python为例。你需要先安装依赖然后设置API密钥。密钥建议放在环境变量里不要硬编码进代码否则代码一旦上传到共享仓库密钥就泄露了。pip install openai # 这里以兼容openai风格的SDK为例 export LLM_API_KEYsk-xxx不同服务商的接口参数大同小异大概率都兼容OpenAI风格的接口。如果你用的是国内某云平台或者某个模型服务商拿到它的API地址、密钥和模型ID即可。我习惯把这几个配置单独抽出来写到配置文件或环境管理工具里方便切换环境时统一修改。有一点提醒不要一上来就追求用最新的超级大模型。先拿一个够用的、价格适中的模型把链路跑通后面再根据效果升级。链路跑通比模型本身的强弱重要得多因为后面的RAG、评测调优才是决定项目成败的关键。3.2 第一段调用代码一旦依赖装好、密钥设置好第一段代码其实很短import os from openai import OpenAI client OpenAI( api_keyos.environ.get(LLM_API_KEY), base_urlhttps://api.example.com/v1 # 换成你的实际服务地址 ) resp client.chat.completions.create( modelllm-v1, messages[ {role: system, content: 你是一个简洁的中文助手。}, {role: user, content: 请用一句话介绍OCR技术} ], temperature0.3 ) print(resp.choices[0].message.content)这段代码只需一个接口调用就能拿到模型的输出。但真正到生产环境你需要处理的内容远不止这些。我在调用次数多了之后才发现这些“看不见的地方”才是工程的关键。超时时间大模型接口的响应时间波动很大高峰期可能几秒也可能几十秒。如果不设置超时用户那边可能出现长时间转圈。我建议默认设置一个20到30秒的超时再在用户体验上做“正在处理中”的状态提示。重试机制接口总有概率失败比如网络抖动、服务端限流。重试两次是合理选择但要注意指数退避不要一失败就立刻重试否则只会加剧限流。具体来说第一次失败后等2秒第二次失败后等4秒最多重试3次。配合实验比单纯的“失败就重报错”靠谱得多。返回校验模型偶尔会输出空内容或者内容里混着多余字段。建议在代码里对输出做一次非空校验必要的场景还要按约定的格式解析解析失败就重新问一次或降级到默认回答。一个真实的案例某次日志摘要功能一直偶发成功但有时输出是空的。排查发现是SDK返回结果里choices[0].message.content偶尔为空字符串而代码里没有处理这个情况。加了一行“如果空就重试”之后问题率直接降为0。这种细小问题不踩一次坑很难注意到。3.3 多轮对话与上下文管理很多应用不止一问一答需要连续对话。大模型本身不“记得”之前的对话它靠的是你每次把历史消息一起发给它。简单说你的代码里messages 数组要把之前的对话拼进去messages [ {role: system, content: 你是客服助手}, {role: user, content: 我的订单怎么还不发货}, {role: assistant, content: 请提供订单号我来帮你查询。}, {role: user, content: 订单号是123456} ]这样一来模型就能基于上下文回答。但问题来了对话轮次多了以后整个history 会越来越长直到撑爆上下文窗口。这时候就需要做“滑动窗口”裁剪只保留最近几轮或者把历史总结成更短的摘要再和最新问题一起发给模型。我自己的经验是一般业务对话保留最近5到8轮就够了如果历史信息很重要额外维护一个“要点摘要”每几轮用模型更新一次摘要比简单截断效果更好。这算是一个非常实用的工程技巧能让项目在高频长对话场景下既省钱又能保持可用。3.4 把代码变成工程化系统刚写完能跑的代码时可能很兴奋但走完demo阶段你会发现样例里缺的东西正是生产环境最需要的东西缓存。相同或相似的问题在短时间内直接返回上次结果可以省掉很多token费用。为了控制成本和时间我建议给经常查询类的问题加一层缓存。异步化。如果你的应用是同步接口每次都要等模型慢慢吐出答案用户会非常着急。更合理的做法是接收请求后立刻返回“处理中”状态模型生成完成后再通过回调或轮询让用户拿到结果。限流。不设上限的话某个用户脚本疯狂调用一晚上就能把预算打光。按账号或按IP做配额是基本操作。日志与Trace。记录每次请求的模型、输入长度、输出长度、耗时、错误码。没有这个模型出问题时你都不知道怎么查。做完这些你的代码才真正算得上“能上线”这也是从写demo到做产品的关键一步。我见过有人把所有逻辑都堆在一个函数里上线后加了半个月班每天在日志里大海捞针。把trace信息打清楚就是在给自己省心。4. 检索增强生成RAG落地的那点事4.1 为什么一定要关注RAG大模型的知识截止于训练数据内部也没有你的私有资料。想让模型回答公司内部制度、产品文档里的内容靠微调成本高、周期长最实用的方案就是RAG先从资料库里检索出与问题相关的片段再把片段塞进提示词里让模型生成答案。RAG还有一个很关键的价值它能让大模型“承认不知道”。不检索到足够的依据时它可以回复“资料库中没有相关内容”而不是一本正经地编一个答案。很多人问怎么能减少幻觉RAG目前是最有效的手段之一从工程角度看性价比也很合适。我这里要把RAG的核心流程分成五步下面逐步展开说明。4.2 一个最小可用的RAG全流程要做到一个能用的RAG系统下面这些环节一个都不能省文档解析。不管是PDF、Word还是网页先转成纯文本清洗掉页眉页脚、多余空格和特殊符号。文本切分。这一步很关键。你把长文档随便丢给模型它一定记不住。需要把文本切成若干块每一块要语义完整还要包含足够上下文。切太小单块信息不完整切太大检索噪声高、token浪费。我通常按段落再结合标题层级来切控制在200到500个token左右一块。向量化。对每一块文本调用embedding模型生成向量并存储到向量数据库。召回。用户提问时也对问题生成向量然后去向量库做相似度检索找出最相关的几块文本。生成。把检索到的文本片段拼进提示词附上原文内容让模型基于这些上下文回答。下面我用一个最小示例模拟流程假设你已经有向量数据库客户端# 1. 把文档拆成块 chunks split_doc(doc_text, chunk_size300) # 2. 逐块生成向量并入库 for i, chunk in enumerate(chunks): vec embed(chunk) collection.add(idf{doc_id}_{i}, vectorvec, textchunk) # 3. 查询时向量化问题检索top_k q_vec embed(公司年假规定是什么) results collection.query(vectorq_vec, top_k5) # 4. 把检索到的文本拼入提示词 context \n.join([r[text] for r in results]) prompt f请仅根据以下资料回答\n{context}\n问题{q_text}这个过程不难但每一环都值得打磨细节。嗯这段代码本质上就是RAG的雏形理解好这些简单的结构比跑一个大而全的框架更能把握原理。4.3 切块、召回与提示词协作的细节实践中最容易影响RAG效果的三个点我必须单独展开说。第一切块策略。不要按固定字符数硬切。硬切的后果是一句话被从中间截断语义就不完整。更好的方式是递归切分优先按段落、再按句子、最后按固定长度保证每一块尽量是完整语义单元。同时保留标题层级比如把“3.2 请假流程”作为上下文前缀拼到块前面检索时模型会更容易判断这是哪一部分的内容。第二召回数量。top_k并不是越大越好。召回太少可能漏掉关键信息召回太多无关文本会稀释模型的注意力。我一般先从top_k5开始试验再根据评测结果调整到4到8之间。如果你有自己的历史对话数据可以用“问题-期望文档块”的对应关系来做召回评估这样调整就有数据支撑。第三引用标注。当模型回答时最好要求它标注“根据资料1、资料3”这样用户能对照原文发现答错时也能追溯到是哪块资料误导了模型。这个设计对实际落地效果影响巨大。我还要提醒一个RAG特有的坑用户问题里可能有代词比如“他的离职手续怎么办理”“他”指代谁不明确。只检索“他”那肯定是找不到答案的。解决方法是在进入检索之前用模型对人工发问或上下文推理出完整的实体名然后改写成一个更明确的查询。将语义改写这一步加进去检索效果会有明显提升。5. 大模型项目最常见的问题与排查思路调试大模型应用和调试普通程序完全不同最大的区别是你很难看到一个清晰的堆栈信息。模型不报错它只是输出一个“看似合理但实际错误”的结果。这种问题才最让人头疼常规思路排查不出来只能靠经验。5.1 输出内容不遵循格式我遇到最多的投诉是模型“没有按照要求的格式输出”。让它输出JSON它非要加一段解释让它只输出“是/否”它非要补一句语气词。排查思路第一步检查是否真的在提示词里把格式要求写清楚了。很多人只写了一句“输出JSON”但模型不知道是要纯JSON还是带markdown的JSON也不确定字段名。要给一个示例让模型照着做。在我这里最有效的格式稳定方案就是提示词里写一个具体的输入输出示例。如果加了示例还是不稳定那就减少temperature。又或者不用“让模型自觉遵守”的思路而是增加格式修正逻辑例如拿到模型输出后用代码把多余的markdown内容剥掉再做JSON解析。不要把希望全寄托在“模型自觉”上前后两重保障更稳妥。5.2 幻觉和编造答案幻觉是大模型应用绕不开的坎但在排查前要先分清“幻觉”还是“信息来源不对”。比如你让它根据客服记录总结用户诉求它却引用了一段“仿佛存在但实际不存在”的内容这就是严重幻觉。而如果资料库本来就没有答案它却硬编了一个也是幻觉。缓解幻觉大概有几个方向缩小提示词的可用范围。明确告诉它“只能使用参考内容不要补充外部知识”。检索不到相关内容时主动输出“未找到”比强行作答体面得多。回答后增加校验环节让模型自己复盘一遍你刚才的结论在材料里都有依据吗指出对应段落。第二遍校验成本翻倍但对高准确率场景是值得的。某客服知识库项目里加上这个“自校验”逻辑之后准确率提升了好几个点。5.3 响应特别慢、异常报错、限流响应慢可能的原因有好几个。一是模型本身推理时间长长输出比长输入更耗时。二是你请求的提示词太长解码阶段慢。三是后端限流排队了。排查时先看API返回里的时间统计或者看Trace日志。如果遇到限流报错例如429或API异常500、超时需要做好重试和退避。有些服务商的限流是按QPM或者TPM执行的也就是说每分钟只能调用多少次或者每分钟只能消耗多少token。这时候光改提示词没用要加排队调度。批量处理场景可以设计一个简单的任务队列把请求均匀铺开比一次性集中调用稳定也容易压住限流。5.4 成本失控成本问题往往在项目上线两周后爆发。某次我看账单吓了一跳发现大量调用都是几百甚至几千token的重复请求一问才知道业务方写了个定时脚本每天轮询调用API。这种问题靠事后控制很难建议提前做给接口按用户或场景设置每日配额。加结果缓存比如“同一问题一天内不重复调用”。对日志输入做脱敏和精简能少传的话少传。上线后第一周每天看一次按模型、按场景统计的token消耗第一时间发现异常增长。成本问题不是开发完才考虑而是架构设计的一部分。多花半天把配额、缓存、监控做了可能省下整季度预算。6. 评测、上线与后续迭代6.1 给项目建一个评测集很多大模型项目能跑、但不稳定、不可信最核心的原因是没有评测集。评测集就是一组“问题-标准答案”对用来衡量模型表现。哪怕只有二十条也比完全靠“感觉还行”好得多。构造评测集时要注意三点一是要覆盖正常场景二是要包含边界情形比如“资料库里没有这个答案”“问题包含歧义”等三是标准答案要明确能判断对错最好不能直接判断的也要能人工裁定。把它们对齐成Excel也好、JSON也好只要能回放就行。6.2 回归测试与Prompt调优每次改提示词、换模型、改切块参数都需要在评测集上跑一遍。我习惯把上一版和这一版的结果放一起对比统计正确率、无效输出率、平均耗时等指标。只有量化数据才能说服你改对一个方向。如果某个问题在调优后回答变差了有两种可能一是提示词改动影响到了它的行为二是模型本身有随机性。后者可以通过跑三次取多数结果来判断。另外每改一次就在评测集上跑一次这个过程需要自动化。如果团队里有现成CI流程把评测脚本挂进去提交代码时自动跑防止改了半天又改回去了。6.3 线上监控与后续方向模型上线不是终点。需要监控的指标包括接口成功率、响应耗时、token消耗、用户点踩比例。其中用户对回答点踩的比例是产品质量最直接的信号。如果点踩率升高及时回到评测集里寻找规律还原当时的输入和上下文。关于后续迭代我这里就不铺开讲了。简单说大模型应用是一个持续调优的过程。你可以从这个系列的方向继续看后面几篇会深入聊流程工程化、提示词版本管理、向量召回优化等话题。最后分享我个人的体会做LLM项目最难的不是写代码而是接受它那种“经常能用、偶尔翻车”的特性。不要试图找一个万能参数组合让模型永远正确这不现实。与其对抗不确定性不如建好兜底逻辑和评测机制把错误控制在自己能接受的范围内。带着这个心态去做大模型项目会顺利很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑