资讯中心

LLM应用开发的十大常见陷阱——从Prompt设计到服务部署的血泪教训

📅 2026/7/27 14:51:30
LLM应用开发的十大常见陷阱——从Prompt设计到服务部署的血泪教训
LLM应用开发的十大常见陷阱——从Prompt设计到服务部署的血泪教训一、当看起来能用不等于生产可用大模型应用的开发门槛确实比传统软件开发低——一个Prompt 一个API调用就能跑起来。但正是这种低门槛给人一种错觉LLM应用很容易做。实际上从Demo到生产中间隔着十个巨大的陷阱。7月份我们团队同时维护了三个LLM应用的生产版本每个都至少在三个以上的陷阱中踩过坑。本文按照LLM应用的全生命周期——Prompt设计、RAG流水线、Agent编排、服务部署、效果评估——逐条列出十大陷阱和对应的解法。二、Prompt设计层的两个陷阱陷阱一过度指令导致意图模糊常见错误为了让模型输出规整在System Prompt中塞入大量格式要求、角色设定、示例和约束条件。一个3000字的System Prompt看起来详尽但模型实际只会关注其中的部分内容导致输出不一致。正确做法将Prompt按优先级分层——核心约束必须遵守放最前、格式说明放中间、示例放最后。同时每个约束用Markdown的强调语法加粗标记便于模型识别关键指令。陷阱二Few-shot示例不可控与标签泄露在Prompt中放入3~5个示例可以提升效果但存在两个风险一是示例中的标签可能在推理时被模型记住并照搬二是示例过多会挤占实际任务所需的上下文窗口。正确做法控制示例数量不超过3个示例格式与实际输入严格一致并在Prompt末尾添加以上示例仅供参考请根据实际输入独立判断的约束语句。三、RAG流水线层的三个陷阱陷阱三文档分块策略的一刀切许多团队使用固定的chunk_size如512 tokens对所有文档做分块。但技术文档、法律合同、FAQ这三种类型的文档对分块粒度的要求完全不同FAQ每个问题集应该独立成块、法律合同需要按条款分块、技术文档按段落和章节分块。正确做法根据文档结构动态决定分块策略——Markdown文档按标题级别分块、表格数据按行分块、代码按函数/类分块。以下是基于文档类型的自适应分块策略实现/** * 基于文档类型的自适应分块策略 * 不同类型的文档使用不同的分块粒度 */ Component public class AdaptiveChunkStrategy { /** * 根据文档类型选择合适的分块策略 * * param document 原始文档内容 * param docType 文档类型TECH_DOC、LEGAL、FAQ、CODE * return 分块后的文本列表 */ public ListString chunk(String document, DocumentType docType) { switch (docType) { case TECH_DOC: return chunkByHeading(document, 3); // 按三级标题分块 case LEGAL: return chunkByPattern(document, Pattern.compile(第[一二三四五六七八九十]条)); // 按条款分块 case FAQ: return chunkByPattern(document, Pattern.compile((Q|问)[:].*?(A|答)[:], Pattern.DOTALL)); // 按问答对分块 case CODE: return chunkByMethod(document); // 按方法边界分块 default: return chunkByParagraph(document, 512); // 默认按段落token限制 } } private ListString chunkByHeading(String doc, int level) { try { String regex ^ #.repeat(level) \\s.*$; Pattern pattern Pattern.compile(regex, Pattern.MULTILINE); return splitByPattern(doc, pattern); } catch (Exception e) { log.error(按标题分块异常降级为段落分块, e); return chunkByParagraph(doc, 512); } } private ListString chunkByPattern(String doc, Pattern pattern) { // 按正则模式分割文档 return splitByPattern(doc, pattern); } private ListString chunkByMethod(String doc) { // 按Java方法边界分块基于大括号匹配 return splitByPattern(doc, Pattern.compile((public|private|protected)\\s[\\w]\\s\\w\\s*\\([^)]*\\)\\s*\\{)); } private ListString chunkByParagraph(String doc, int maxTokens) { // 按段落分割超过maxTokens的段落进一步切割 ListString chunks new ArrayList(); String[] paragraphs doc.split(\\n\\s*\\n); for (String para : paragraphs) { if (estimateTokens(para) maxTokens) { chunks.addAll(splitByTokenLimit(para, maxTokens)); } else { chunks.add(para.trim()); } } return chunks; } // splitByPattern、splitByTokenLimit、estimateTokens 等辅助方法实现省略 private ListString splitByPattern(String doc, Pattern pattern) { // 简化实现 return List.of(pattern.split(doc)); } private ListString splitByTokenLimit(String text, int limit) { // 按token数量切分文本 return List.of(text); } private int estimateTokens(String text) { // 粗略估算中文约1.5字/Token英文约4字/Token return text.length() / 2; } }陷阱四检索Top-K的固定思维默认的Top-K5或Top-K10在大多数场景下有效但有两个场景需要调整一是答案需要综合多个文档片段时如法律条款解读Top-K应设为1520二是答案的精确性要求极高时如代码搜索Top-K应设为35以减少噪声。正确做法将Top-K作为可配置参数通过A/B测试确定每个业务场景的最优值。陷阱五忽略Embedding模型的版本管理Embedding模型升级后相同文本生成的新向量与旧向量不兼容导致存量向量的检索失效。7月份一次Embedding模型小版本升级bge-large-zh-v1.5 → v2导致检索准确率下降30%。正确做法将Embedding模型版本作为向量索引的一部分存储升级前全量重建向量索引建立新旧模型的召回率对比测试流程。四、Agent编排层的两个陷阱陷阱六Agent循环的无限递归Agent在调用工具后获得的结果如果不满足预期会自动重试。如果没有最大迭代次数限制会陷入无限循环单次请求消耗十余万Token。在1.md中已有详细讨论核心解法是设置max_iterations5的硬限制每次迭代间加入人工确认点记录循环原因用于Prompt优化。陷阱七工具调用超时的级联失败Agent调用外部工具API、数据库、搜索引擎时超时是一个常见场景。如果超时未被处理Agent可能无限等待导致上游调用也超时。正确做法为每个工具设置独立的超时时间HTTP工具的connectTimeoutreadTimeout超时后Agent应返回工具暂时不可用请稍后重试而非生成错误内容在Agent框架层面实现断路器机制。五、服务部署层的两个陷阱陷阱八流式输出的缓冲控制SSEServer-Sent Events流式返回时Nginx/Spring Boot的默认缓冲区可能导致响应的chunk被合并用户看到的是一段一段蹦而非一个字一个字出的流畅效果。正确做法在Nginx配置中关闭代理缓冲proxy_buffering off在Spring Boot中设置spring.mvc.async.request-timeout300s使用Flux的delayElements控制输出频率。陷阱九并发调用的速率限制大模型API通常有RPM每分钟请求数和TPM每分钟Token数的限制。当多个用户同时调用时很容易触发限流。正确做法实现本地令牌桶限流器使用Guava的RateLimiter或自研将API的RPM/TPM作为上游约束本地做预限流和排队避免实际调用被拒绝。六、效果评估层的两个陷阱陷阱十离线评估与线上指标的脱节在1.md中已有讨论离线评估标注数据集上计算准确率只是下限保证不能替代线上A/B测试。离线评估得分高的Prompt/模型配置在线上往往表现平平。核心原因是离线评估的测试集无法覆盖用户提问的多样性。正确做法建立离线评测→小流量灰度→全量上线的三阶段发布流程。小流量灰度期间的核心指标是用户点赞率、转人工率、平均对话轮数。七、总结十大陷阱可以归为三类思维误区陷阱一、二、四——固定思维、过度设计、工程缺失陷阱五、七、八、九——版本管理、容错、缓冲、限流、流程缺陷陷阱三、六、十——策略选择、循环控制、评估体系。LLM应用开发的难点不在于LLM本身而在于将软件工程的最佳实践——版本控制、容错机制、性能调优、灰度发布、效果评估——移植到这个新领域。把LLM看作一个概率性、有状态的外部依赖用工程化的方式管理它是十大陷阱背后的共同解法。