引言:一条"正常"日志引发的连锁异常
上周上线前做接口回归的时候,测试同学抛过来一条日志:2026-07-21 11:27:30,587 - app.common.logger - INFO - A...,表面看是普通的INFO级别运行日志,但对应的/api/ai/quick-summarize接口返回的JSON里,本该存在的摘要字段总是为空。一开始我们以为是前端渲染的问题,追了半小时才发现,这条"正常"日志背后藏着3个接口的共性问题,最后用AI编码工具辅助排查,1小时就完成了修复和验证,整个过程踩了不少坑,也总结了不少可复用的经验。
踩坑现场:JSON解析逻辑的共性问题爆发
定位到quick-summarize接口的问题后,我们发现根因是后端解析AI返回结果的逻辑没适配新模型:旧逻辑只取content字段,但新上线的模型会优先返回reasoning_content字段,当content为空时,摘要就直接丢了。顺着这个逻辑扫同类型的JSON总结类接口,又发现/api/bestsellers/analyze-trend接口用了完全一样的解析逻辑,同样会丢畅销书分析的结论字段,对应素材里的"继续把这类JSON总结类请求也扫了一遍;除了quick-summarize,又修了一个同模式问题"。
第一轮修完这两个核心接口后,我们继续扫了一轮全量代码,又发现2个待处理问题:一个是内部统计接口的JSON结构不符合对外约定,另一个是主题追踪的theme_tracker模块在解析reasoning_content时有边界情况处理。对应素材里的"已扫完一轮,结论先说:仍建议继续改的、这轮我先不动的地方、验证"。评估后我们决定:内部统计接口因为有第三方老调用方依赖旧结构,暂时不动避免引发兼容性问题;theme_tracker模块一起加固,完成所有可推进的优化。
这里的问题核心是共性的解析逻辑散落在不同工具类里,如果没有全局扫描的意识,很容易修完一个漏掉其他同类型接口。比如错误的解析逻辑长这样:
python
# 错误写法:只取content字段,未适配新模型返回结构
def parse_ai_response(response: dict) -> dict:
return {"summary": response.get("content", "")}
修复后的逻辑优先取reasoning_content,兜底用content,既兼容旧模型,也适配新模型:
python
# 正确写法:优先取reasoning_content,兼容新旧模型返回结构
def parse_ai_response(response: dict) -> dict:
summary = response.get("reasoning_content") or response.get("content", "")
return {"summary": summary}
AI编码辅助排查的决策链路
如果手动排查的话,我们需要翻3个模块的代码,逐个找JSON处理逻辑,至少要花2-3小时,还容易漏改。用AI编码工具(本次用的是Codex)的流程是这样的:
- 第一步:全局扫描定位问题:把异常日志、接口返回的异常JSON、AI返回的原始结构喂给AI,让它先全局扫所有和JSON序列化、接口返回相关的代码,第一轮就定位到了5处共性的解析逻辑问题,比手动找快了3倍。
- 第二步:对齐业务优先级决策 :核心用户接口(
quick-summarize、analyze-trend)优先改,内部工具接口如果调用方没升级就先标记不动,避免影响现有业务。这里就踩了一个差点改坏兼容性的坑:一开始差点把内部统计接口的字段顺序改了,后来想到有第三方老调用方依赖旧结构,才临时叫停,不然会引发更大的线上问题。 - 第三步:逐轮验证沉淀清单:每改一处就调一次接口看返回是否符合预期,最后把所有改动点整理成最小验证清单,对应素材里的"已整理完,给你一页可直接用的上线前验证清单"。
沉淀的上线前验证清单,下次直接对着查
最后我们整理了一份一页纸的上线前验证清单,把这次踩过的所有坑都列了进去,下次上线对着查就行,不用再翻代码:
- 核心接口返回结构验证:
/api/ai/quick-summarize、/api/bestsellers/analyze-trend等JSON总结类接口,必填字段(摘要、结论、主题标签)是否非空,reasoning_content字段是否被正确解析; - 边界情况验证:AI返回
content为空、reasoning_content存在的情况下,接口是否能正常返回有效数据; - 主题模块验证:
theme_tracker的初始化逻辑是否能正确提取reasoning_content里的主题信息; - 向下兼容验证:所有修改过的接口,老版本的调用方是否能正常解析返回结构,没有字段缺失或顺序错乱的问题。
结尾:可带走的方法论
这次排查最大的收获不是修了几个Bug,而是沉淀了一套排查同类问题的通用流程:
- 遇到看似正常的日志不要忽略:INFO级别的日志往往藏着边界处理的漏洞,追上下文比看日志级别更重要,很多时候"正常"日志背后藏着的是业务逻辑的边界漏洞;
- 排查批量同类型问题先找共性:先全局扫描找共性的逻辑点,再逐个击破,比一个个接口改效率高3倍以上,还不会漏改;
- 每次排查完都要沉淀最小验证清单:把踩过的坑变成可复用的工具,避免下次再踩同样的坑。
如果你也在用AI编码工具辅助开发,不妨试试把异常上下文喂给它先做全局扫描,能省下不少找代码的时间。