Skip to content

踩坑合集:现象 → 根因 → 解法 ​

1. 本节产出 ​

一张按「现象」组织的排障表:看到什么现象 → 最可能的根因 → 怎么验证 → 怎么修。按 Ctrl+F 搜现象关键词。

2. 前置依赖 ​

无。遇到问题时来查。

3. 为什么按「现象」组织 ​

按技术模块组织(Spring AI 的坑、RAG 的坑、Agent 的坑)在排障时没用——你遇到的是现象,不知道它属于哪个模块。所以这里按现象组织,每条标注相关章节。

4. 核心原理 ​

排障的通用顺序:

1. 确认现象(到底哪里不对)
2. 缩小范围(是模型的问题还是你的代码的问题)
3. 二分定位(去掉一半功能看是否还复现)
4. 验证假设(改一个变量,看结果是否变化)

第 2 步最重要:用一个「假模型」替换真实模型(01-11),如果问题消失就是模型侧问题,否则是你的代码问题。这能省掉一大半的排查时间。

5. 踩坑清单 ​

5.1 启动与配置类 ​

现象根因验证 / 解法
依赖拉不下来starter 命名在 1.x→2.x 变更核对 00-03 版本矩阵,2.x 是 spring-ai-starter-model-*
Could not resolve placeholder 'API_KEY'环境变量未导出或被 IDE 覆盖echo $API_KEY 验证;检查 IDE 启动配置
配置改了不生效属性名拼错,被 Spring 静默忽略打开 logging.level.org.springframework.ai: DEBUG 看实际值
启动报维度不匹配Embedding 维度与向量库建表维度不一致检查 dimensions 与 VECTOR(n)
H2 建表成功、PG 建表失败方言差异(JSONB / 窗口函数)用 Testcontainers 测真实 PG(01-11)

5.2 调用与响应类 ​

现象根因验证 / 解法
401Key 无效或带空格.trim();用 curl 单独验证 Key
404base-url 多/少 /v1通义兼容端点是 /compatible-mode/v1
连接超时代理拦截 / 网络策略先用 curl 验证网络,再查应用配置
响应很慢但不是超时读取超时设太长,请求在排队查网关队列与线程池
工具不触发模型不支持,或 description 含糊先用最简工具(返回固定值)验证模型能力(01-07)
工具返回后模型照着念堆栈工具抛了异常异常转成人话文本返回(01-07)
结构化输出解析失败temperature 太高 / 返回带代码块设 temperature=0;用 BeanOutputConverter 清洗(01-08)
模板渲染后出现 {xxx}变量名改了调用方没改渲染后校验不得含 {(01-09)

5.3 流式类 ​

现象根因验证 / 解法
打字机不生效,一次性返回缺少 produces = TEXT_EVENT_STREAM_VALUE加 produces;用 curl -N 验证
本地有效、生产无效Nginx proxy_buffering 缓冲了 SSE配 proxy_buffering off
关闭页面后又触发请求EventSource 自动重连beforeunload 里 es.close()
WebSocket 连上就断HandlerMapping 顺序被抢setOrder(1)(01-05)
WebSocket 中途断开代理 proxy_read_timeout 60s调超时 + 25s 心跳

5.4 RAG 类 ​

现象根因验证 / 解法
怎么调都搜不到离线段问题(解析/切分/元数据)打印片段肉眼看(02-04)
检索到但答不对片段被切断,语义不完整检查切分是否切在句子中间
每个片段都带「第 3 页」页眉页脚没去跨页高频行过滤(02-03)
搜 PDF 得到空扫描件,需 OCR解析后校验字符数,为空直接报错
精度不高(排不准)缺 Rerank加二阶段排序(02-10)
精确编号搜不到纯向量不擅字面匹配加 BM25 混合检索(02-09)
不该答的答了只有 prompt 约束,没有检索层拒答加检索层硬拒答(02-11)
多轮后答非所问上下文超限被静默截断调估算 Token,超限先压缩(01-01)
换租户答不出检索过滤把结果过滤没了检查 filterExpression 是否正确(02-12)
文档更新后答案没变缓存没失效发布/回滚联动清缓存(02-15)
A 看到 B 的数据过滤漏了 tenantId(严重)跑 TenantIsolationIT 断言测试(02-12)

5.5 Agent 类 ​

现象根因验证 / 解法
Agent 一直跑不结束无迭代上限或上限太大设三限额(轮次+Token+超时)(03-10)
一夜烧掉很多钱死循环加重复动作检测与无进展检测
反复调用同一工具工具返回失败但模型不理解返回可行动的失败文本(03-10)
模型调用不存在的工具编造工具名执行层白名单校验(03-11)
跨租户操作tenantId 是工具参数改为上下文注入(03-11)
服务重启后任务丢失状态只放内存每轮落检查点(03-05)
审批后仍被判超时等待审批计入了总超时恢复时重算 deadline(03-16)
工具被自动重试造成重复业务写操作自动重试写操作禁止自动重试 + 幂等键(03-08)
上下文越来越大没做压缩60% 触发摘要压缩(03-05)
模型乱选工具挂载工具太多(>10)动态筛选到 5~8 个(03-03)

5.6 成本与性能类 ​

现象根因验证 / 解法
账单对不上用了估算值计费 / 超时请求未统计对账只用 usage;超时单独标注(02-18)
重试导致成本翻倍无重试预算加重试预算,后期轮次不重试(03-08)
灌库拖慢在线服务未做资源隔离独立线程池 + 背压(02-16)
检索突然变慢元数据过滤没索引JSONB 建 GIN 索引(02-06)
看不到 P95没开 percentiles-histogram配置 percentiles-histogram(02-19)
Prometheus 内存暴涨指标标签基数过高标签只放低基数维度(02-19)
缓存命中但内容过期文档更新未失效缓存按 sourceId 失效(02-15)

6. 跑起来 ​

排障时按表检索。建议打印出来贴在工位。

检查项通过标准
能按现象找到条目Ctrl+F 搜关键词能命中
有验证方法每条都有「怎么确认是这个原因」
指向正文每条都标注了详细章节

7. 生产避坑 ​

  1. 先区分「模型的问题」和「你的代码的问题」。用假模型替换一次(01-11),这个动作能排除掉一半的可能性。很多人花几小时调 prompt,实际问题是自己的解析代码。
  2. 「静默失败」类问题最危险:配置拼错不报错、解析出空文本不报错、上下文超限不报错。这类问题的共同防御是「显式校验 + fail fast」——宁可报错,不要静默。

8. 延伸与锚点 ​