LeetCode 题解检索:上线前补齐校验、观测与回退
用 Notebook 把向量检索和题解生成串起来,足以验证想法;要提供给用户,还要处理检索范围、超时、输出渲染和失败回退。这里讨论的是一个题解辅助功能,而不是用模型替代算法判题。
检索先过滤,再排序
算法题之间很容易因为相似的循环、数组或哈希表描述而互相误召回。题目 ID 已知时,优先按题目 ID 精确取资料;只有在“相似题推荐”场景再做向量检索,并使用语言、主题标签、难度和资料版本过滤候选集。
向量分数只是排序信号,不是正确性证明。将检索到的资料来源、版本和分数保留在服务端日志或调试信息中,便于发现题库内容过期和标签错误。
flowchart LR A[题目与代码] --> B[题目元数据过滤] B --> C[检索候选资料] C --> D[拼装有限上下文] D --> E[模型解释] E --> F[渲染与安全处理] C -->|超时或无结果| G[题库基础说明]输出不要靠“修公式”兜底
模型输出应限制为受控 Markdown 子集,前端使用成熟的 Markdown 渲染器并关闭危险 HTML。LaTex 公式交给渲染器处理;对缺少分隔符的文本,宁可按普通文本显示,也不要用正则自动补括号或补$,这类修复很容易改变内容。
模型调用、检索调用分别设置超时。检索超时可以跳过增强资料;模型超时则返回题库中的基础解法和测试结果,并说明“智能解释暂不可用”。
func (s *Service) Explain(ctx context.Context, q Question, code string) (string, error) { docs, err := s.retriever.Search(ctx, q.ID, q.Tags, q.Language) if err != nil { docs = nil // 检索失败不阻塞基本题解 } text, err := s.llm.Explain(ctx, q, code, docs) if err != nil { return s.catalog.BasicExplanation(q.ID), nil } return s.renderer.Sanitize(text), nil }上线前至少覆盖:无检索结果、检索超时、重复资料、模型返回空内容、包含 HTML 的 Markdown 和客户端取消。性能测试报告应同时给出题库规模、索引设置、硬件、并发模式和输入长度,否则延迟数字没有可比性。
原型的价值是验证功能路径;服务化的工作,是让每个依赖失效时都只影响增强能力,而不是影响题目本身。