Skip to content

01 BinRag 项目口述介绍(字节面试版) ​

怎么用这篇:

  1. 先读「一、先认清形势」——搞清楚面试官会怎么给这个项目打分,避免用力过猛或过度自谦。
  2. 背「二、30 秒版」+「三、2 分钟版」——这两段是必须条件反射说出来的。
  3. 「四、5 分钟架构版」用于白板/深挖场景;「五」把简历四条 bullet 逐条展开。
  4. 「六、vibe coding 怎么坦白」是这篇文档最重要的部分——这个项目是 AI 辅助写的,一定要有准备好的说法。
  5. 「七」是数字卡,全部与代码一致,被追问时直接报数。没有实测的效果数字一律不要编(详见 08 篇)。

一、先认清形势:面试官会怎么评价这个项目 ​

先说结论:这是一个"广度很夸张、单点深度一般"的项目,而这个特点在字节的面试里是双刃剑。

加分项(要主动展示)

事实为什么加分
全栈闭环:多格式解析 → 分块 → 向量+BM25 混合检索 → 重排 → 上下文组装 → SSE 流式 → 引用可溯源面试官最喜欢"能把链路讲完整"的候选人
不是 demo 级调库:BM25 是自己写的倒排索引(k1=1.2 / b=0.75 / IDF 公式都在 internal/retriever/bm25.go),RRF 融合是自己实现的证明你理解算法,不是只会 pip install
有工程化:异步入库 worker 池 + 重试退避 + 重启恢复、OIDC 登录、MCP 协议对外、Docker/CI、双形态部署说明你有"上线思维"而不是"作业思维"
有评估体系:cmd/eval Recall@K + LLM-as-Judge,另有一个独立 Python RAGAS 服务「你怎么知道效果变好了」这个必问题有答案
做过两轮系统性代码 review 并修复(docs/33-review-2026-08/report.md:6 条 P0 + 12 条 P1;docs/34-review-p1-fix/)这是你对抗"这是 AI 写的"这一质疑的最强证据
405 个 Go 测试 / 63 个测试文件、前端 vitest 37 例、Python pytest 86 例有测试意识,且可以说出测试覆盖了哪些边界

减分风险(要提前想好怎么接)

风险面试官的潜台词你的应对
是 AI 辅助(vibe coding)完成的"细节你懂吗?"见第六节的话术:文档驱动 + 自己定验收标准 + 两轮 review 修复
没有真实用户、没有线上数据"效果如何证明?"承认没有真实流量;拿评估框架 + 具体缺陷的修复前后对比来说话
有已知的实现缺陷(BM25 重启失效、BM25 独有命中正文为空等)"你是不是不知道?"主动说,并给出改法。主动暴露 = 你在掌控,被问出来 = 你被抓包
没有 metrics / trace(全仓无 Prometheus/OTel)"线上怎么排查?"承认只有 slog 日志 + MCP 审计,说清你会怎么补

一句话定位(心里默念):"我做了一个能跑通的、链路完整的、自己知道哪里不足的企业文档 RAG 系统。它的算法部分我理解到公式一级,工程部分我做过两轮 review 修复,它的效果验证框架已落地但没有大规模真实数据。"


二、30 秒电梯版(逐字稿,必须背) ​

"BinRag 是一个企业级文档知识库的 RAG 问答系统,我用 Go 写的。 它的核心链路是:多格式文档(PDF/DOCX/Excel/HTML 等)异步入库,经过分块和 Embedding 存到 Qdrant,同时把 chunk 灌进我自己实现的 BM25 内存倒排索引;问答时检索走向量 + BM25 双路并行,用加权 RRF 融合,再过一层 cross-encoder 重排,然后按 token 预算组装上下文,用 SSE 流式吐出回答和引用来源。 部署形态上它是一个 Go 二进制:Web 版直接把 Vue 前端 embed 进去,桌面版用 Wails 起一个内嵌后端,两种形态共用同一套装配代码;对外还开了一个 MCP Server,把检索和问答能力以 6 个只读 Tool 暴露给外部 Agent 调用。 整个项目我做了三轮:先按 spec/plan/task/checklist 规格驱动开发,中间跑了一次全量代码 review 修掉 6 个 P0 和十几项 P1,最后补了一个独立的 RAGAS 评估服务。"

备注(这段为什么这么讲)

  • 前两句给是什么 + 核心链路,让面试官 10 秒内建立地图。
  • 第三句给技术记忆点:双路 RRF、自研 BM25、SSE、单二进制双形态、MCP——这些都是"能接着往下问"的钩子,你希望他问你准备过的东西。
  • 最后一句主动交代开发方式("三轮、规格驱动、review 修复"),把 vibe coding 的质疑在开场就化解掉。
  • 不要说:"这是一个基于大模型的项目"(太虚)、"我用了 LangChain"(不是事实,Go 项目)。

三、2 分钟标准版(逐字稿,按简历四条线展开) ​

"我按简历上的四条线讲。

第一条是混合检索与精排。 检索层我做了两条并行通路:一条是向量语义检索,走 Qdrant 的 gRPC,用 Qdrant 新版 Query API;另一条是 BM25 关键词检索——这条我不是调库,是自己写的倒排索引,k1 取 1.2、b 取 0.75,IDF 用的是 log((N-df+0.5)/(df+0.5)+1) 这个非负变体,中文按 bigram 切、英文按词切,大小写归一。两路结果各取 Top-10,用 加权 RRF 融合,公式是 score(d) = Σ weight / (k + rank + 1),k 取 60,向量权重 0.7、BM25 权重 0.3,这两个权重在配置校验里强制和为 1。融合完再过一层 cross-encoder 重排——我接的是 /v1/rerank 风格的标准接口,兼容 Jina、Cohere、bge-reranker 这些,另外还做了一路"用通用大模型逐条打分"的降级模式,给没有专用 rerank 端点的场景用。

第二条是文档处理管道。 加载器支持 PDF、DOCX、Excel、CSV、HTML、Markdown、TXT,另外还扩了图片、音频、视频;解析统一成一个 Block 结构。分块有三种策略:固定大小、递归字符、Markdown 标题,默认 chunk_size 512、overlap 50,PDF 走按页分块、多媒体按时间戳分块,保证引用能定位到页码或视频时间点。分块的 token 数是自己估算的——中文按 2 token、英文按词。入库是异步的:上传接口落盘 + 建任务就返回 task_id,由 worker 池轮询领取,默认 5 个 worker,失败按 2s/4s/8s 指数退避重试 3 次(退避时间写在任务的 updated_at 里,让轮询自然跳过),重启时把残留的 processing 任务重置回 pending 续跑。

第三条是 LLM 问答链路。 一次问答的顺序是:读多轮历史 → Query 改写消解指代 → 检索 → 按 token 预算组装上下文(预算 2048 token、最多 5 条引用)→ 生成。流式走 SSE,事件序列固定是 sources 先发、然后 chunk 增量、最后 done,出错发 error;引用来源里带文件名、标题路径、页码、视频时间戳和锚点,前端点开能定位到原文。除了基础链路,我还实现了多查询改写、问题分解、Step-Back、HyDE 和 LLM 自动路由,都是通过三级策略配置(请求 > 知识库 > 全局)来开的,默认只开最基础的。

第四条是 MCP Server。 我在同一个进程里挂了一个 /mcp 端点,用 streamable HTTP 传输,对外开放 6 个只读 Tool:列知识库、查知识库详情、纯检索、RAG 问答、列文档、查任务状态。认证是 Bearer API Key 走 SHA-256 校验,认证失败返 HTTP 401,授权失败返 JSON-RPC 的 -32001,而且越权和不存在返回同一句消息,不泄露资源是否存在。每次调用异步写审计表,参数截断 2000 字符,审计队列满了只告警不阻塞主请求。

最后补一句工程侧:整个系统是单一 Go 二进制,前端产物用 go:embed 打进去,Web 和 Wails 桌面版共用同一套装配包;数据库 Qdrant 和 PostgreSQL 用 docker compose 一键起,有 GH Actions 做多平台交叉编译和镜像发布。评估上我写了独立的 cmd/eval,数据集驱动算 Recall@K,再用 LLM-as-Judge 打准确性和忠实度分。"

备注(这段怎么练)

  • 四条线顺序不要乱:检索 → 入库 → 问答 → MCP。这是从"最难的技术点"往"最外围的能力"讲,先立于不败。
  • 每条线都埋了钩子:加权 RRF、自研 BM25、token 估算、退避重试、事件序列、-32001 统一消息。面试官一定会挑一个往下问,这些都在 02-07 篇里备好了。
  • 语速控制:2 分钟版本大约 900 字,正常语速正好。别背成流水账,每讲完一条停半秒,给对方插话的机会——他插话问的地方就是你该重点发力的地方。
  • 没把握的数字宁可不报。比如"5 个 worker"是 configs/config.yaml 里的值,代码默认值是 2,如果被追问就答:"配置默认是 2,我们部署配置里调成 5,因为它主要受 Embedding API 的 QPS 限制。"

四、5 分钟架构版(白板场景) ​

4.1 逐字稿(配合画图) ​

"我先画两条链路,一条入库、一条问答,然后讲它们共享的东西。

入库链路:HTTP 上传接口收到 multipart,先校验类型和大小(单文件上限配置 1GB),把文件落到本地磁盘,然后在 PostgreSQL 里插一条 document 记录和一条 ingest_task,状态 pending,立刻返回 task_id——所以上传接口是 O(1) 的,不阻塞。后台有一个 worker 池,每个 worker 每 500ms 轮询一次,用一条 UPDATE ... WHERE id IN (SELECT ... WHERE status='pending' AND updated_at <= now()) 的原子语句批量认领任务,这样多个 worker 不会抢到同一条。认领后依次做:Load 解析 → 可读性校验(少于 20 个字符就判定扫描件/空文档直接拒绝,防止污染知识库)→ Chunk 分块 → Embedding 批量向量化 → Upsert 到 Qdrant,同时把 chunk 正文灌进 BM25 内存索引。任何一步失败,任务回到 pending 并 retry_count+1,退避时间写在 updated_at 里实现延迟重试;超过 3 次就置 failed,同时把文档状态同步成 failed。

问答链路:请求进来先做知识库范围解析——系统级 Key 可以不指定,登录用户不指定就展开成他名下的全部知识库,这一步是防跨租户越权的关键。然后 RAG 引擎执行:读历史(最多 10 条)→ Query 改写,用一次低温 LLM 调用把"它支持什么格式"这种带指代的问题改写成自包含查询 → 检索,就是我刚才说的双路 RRF + 重排 → 组装上下文,按 token 预算截断,每条上下文渲染成 [编号](来源:文件名/标题)正文 的格式,引用编号就是后面 sources 的下标 → 生成。流式的话,先把 sources 事件发出去,再增量发 chunk,最后发 done。

两条链路共享的东西:一个是装配层,internal/app 把存储、worker、引擎、路由装到一起,Web 和桌面两种形态都调它,保证行为一致;另一个是存储,Qdrant 存 chunk 向量和 payload,PostgreSQL 存知识库、文档、任务、API Key、对话历史和审计。第三个是对外协议,REST API、SSE、MCP 三条出口复用同一套认证和权限。

检索的核心设计决定有三个:一,用单集合 + payload 里的 kb_id 过滤做多租户隔离,而不是一个知识库一个集合,因为集合数量会随租户数爆炸;二,向量和 BM25 用 RRF 融合而不是把分数加权求和,因为 BM25 分数和余弦相似度量纲完全不同,RRF 只用排名,天然免疫量纲问题;三,重排放在融合之后统一做一次,不是每路各排一次,避免重复调用重排服务。"

4.2 架构图(可以照着画在纸上) ​

入库(异步)
  上传 → 落盘 + task(pending) → 返回 task_id
                                 ↓ 500ms 轮询 / 原子认领
  worker×N → Loader 解析(Block) → 可分块性校验 → Chunker(3策略)
           → Embedder(批量) → Qdrant.Upsert ─┬─→ BM25 内存索引 Add
                                              └─→ PG: 任务/文档状态更新
  失败 → pending + retry_count++(退避写在 updated_at)→ 超 3 次 failed

问答(同步/SSE)
  请求 → 知识库范围解析(防越权) → 历史(≤10) → Query 改写(LLM,低温)
       → 检索: 向量∥BM25 → 加权 RRF(k=60, 0.7/0.3) → Cross-encoder 重排
       → 上下文组装(≤2048 token, ≤5 条, 带[编号])
       → SSE: sources → chunk×N → done     (或 error)
       → 落历史(PG)

出口:REST(/api/v1/*) / SSE(/api/v1/chat?stream=1) / MCP(/mcp,6 个只读 Tool)
共享:internal/app 装配 + 同一套认证(API Key SHA-256 / 会话 JWT) + 同一套权限

备注:画图时把"失败/降级"画成箭头(重试退避、rerank 降级、数据源降级),这是面试官判断你有没有生产思维的关键位置。


五、简历四条 bullet 的逐条展开话术 ​

每条准备 60–90 秒。面试官可能直接指着简历念一条:"这条具体说说"。

bullet 1:混合检索与精排 ​

"做混合检索的动机很直接:纯向量检索在专有名词、编号、错误码这类查询上会掉——比如用户搜 ERR_4032,Embedding 模型很可能把它映射到一个语义相近但内容无关的段落;而 BM25 对这种精确 token 匹配几乎是必然命中。反过来纯 BM25 又不懂同义词和语义改写。所以两路都要,问题只剩怎么合。 我选 RRF 而不是加权分数求和,因为两种分数的量纲不可比:余弦相似度在 0~1,BM25 是无上界的实数,直接加权需要先归一化,而归一化本身又要引入 min-max 或者 z-score 的假设。RRF 只看排名,公式是 weight/(k+rank+1),k=60 起到"削弱头部极端优势"的作用——k 越大,第 1 名和第 2 名的分数差越小,融合越平滑。 精排这一层我用 cross-encoder:它把 query 和文档拼在一起过一遍模型,能建模二者之间的交互,比双塔的向量内积精度高;代价是不能预计算、只能对少量候选在线算,所以只能放在召回之后。"

bullet 2:完整文档处理管道 ​

"这条的重点是异步 + 可恢复。同步做的只有三件事:校验、落盘、建任务,剩下的全部交给 worker。这样上传接口不会被一个 200MB 的 PDF 拖住。 失败处理上我做了四件事:一是重试,2s/4s/8s 指数退避、最多 3 次,退避是写在 updated_at 里让轮询自然跳过的,不需要额外的调度器;二是重启恢复,服务启动时先把所有 processing 状态的任务重置成 pending——因为进程被杀时任务会卡在 processing;三是幂等,重新入库同一文档前先按 document_id 删掉旧的向量和 BM25 记录,避免重试产生孤儿 chunk;四是可读性校验,解析出来正文少于 20 个字符就判定是扫描件或空文档并拒绝入库,否则会往知识库里灌一堆空白 chunk,这是我在真实测试里踩出来的。"

bullet 3:LLM 问答链路 ​

"三个关键点。Query 改写解决多轮指代:用户第二句问"那它支持哪些格式",不改写直接检索必然跑偏,所以我用一次低温 LLM 调用、把最近 10 条历史一起喂进去,让它输出自包含查询;这一步失败不影响主链路,降级用原问题。 上下文组装的核心是预算:我限制 2048 token、最多 5 条,因为上下文不是越多越好——噪声 chunk 会稀释关键信息、也会让模型更容易产生幻觉;每条上下文我渲染成带编号和来源的形式,编号和最后返回的 sources 数组下标严格对应,前端点引用能直接定位。 流式的顺序是我特意设计的:先发 sources 再发正文。因为检索在生成之前就完成了,先把引用推给前端,用户能立刻看到"我命中了哪几篇文档",感知延迟比等第一个 token 更低。断连我靠 context 取消感知,取消后不落历史也不发 done,避免写进半截回答。"

bullet 4:MCP Server ​

"MCP 是 Anthropic 推的模型上下文协议,本质是让外部 Agent 用标准方式发现和调用能力。我做的这个 Server 用 streamable HTTP 传输,和主服务同进程,所以复用同一套认证和权限,不需要再维护一套网关。 开放了 6 个只读 Tool:列知识库、查知识库详情、纯检索、RAG 问答、列文档、查任务状态。只读是刻意的——外部 Agent 的提示词可能被污染,给它写权限等于把知识库暴露给不可信输入。 权限上做了两层:部署级开关 + 凭据级开关;授权失败和资源不存在都返回 -32001 且消息一致,这样调用方无法通过错误码探测某个知识库是否存在。每次调用异步落审计表,参数截断 2000 字符,审计写失败只告警,不能因为审计拖垮主流程。"


六、vibe coding 怎么坦白(最重要的一节) ​

6.1 先明确:不要撒谎,也不要自贬 ​

面试官问"这个是 AI 写的吧"的时候,他真正想验证的是三件事:

  1. 你能不能讲清代码里每一处的取舍(理解深度)
  2. 你有没有能力判断 AI 写的东西对不对(评审能力)
  3. 你在这件事里的角色是"提需求的人"还是"负责的人"(ownership)

你不需要否认用 AI——2026 年否认反而是不专业。你要做的是把叙事从"AI 帮我写代码"转成"我用工程约束驱动 AI 完成实现,并对结果负责"。

6.2 推荐话术(可以背) ​

"这个项目我确实大量用了 AI 辅助编码,我讲一下我的工作方式,因为它决定了这个项目的质量。 我的做法是先写规格再写代码:每个阶段我先写四份文档——spec.md 写需求和验收标准,plan.md 写技术方案和接口设计,task.md 拆任务,checklist.md 写可验证的验收项。四份文档齐了我才开始让 AI 实现,实现完我拿 checklist 一条条对——比如"上传一个含 <script> 的 Markdown,前端渲染不能执行脚本",这种验收项是我写的,不是 AI 写的。 第二个动作是我在中途做了一次全量代码 review,报告在 docs/33-review-2026-08/report.md:4 个模块并行检查,找出 6 个 P0 和 12 项标号 P1(另有两项 spec 与实现的 gap)——比如前端的 Markdown 渲染直接 v-html 没消毒,存在存储型 XSS;评估模块的忠实度指标把 sources 传成了 nil,等于一直在评判空资料;还有一堆"配置声明了但没接线"的问题,比如 reranker.top_n、web_search.qps。然后我做了两轮修复,第二轮在 docs/34-review-p1-fix/,包括给 worker 加重试退避、给重复入库加补偿删除。 所以我的定位是:架构、验收标准、评审和修复是我做的,AI 是执行效率的放大器。也正因为如此,这个项目里有几个我还没解决的技术债我能说得很清楚,比如说 BM25 是纯内存索引、没有做启动回灌,服务重启后混合检索会静默退化成纯向量检索——这个是我自己 review 时发现的。"

6.3 备注(这段为什么有效) ​

  • "我先写 spec 和 checklist" → 直接证明是你主导,而不是 AI 主导。
  • 两轮 review 的文档是硬证据:字节面试官吃"有据可查"这一套。如果他追问,你可以报具体条目(P0-1 前端 XSS、P0-3 eval 忠实度传 nil、P0-6 启动失败泄漏 Qdrant 连接)。
  • 主动抛出 BM25 重启失效:这是"深度自我审视"的证据,也提前把最锋利的一刀自己接住了(03 篇 Q9 备了完整答法)。
  • 要避免的措辞:"AI 写的我不太清楚"、"这个是 AI 生成的代码我没细看"——这两句直接出局。

6.4 如果被继续逼问:"那你到底懂多少?" ​

不要吹。给一个分层回答:

"我分三层说。算法层我理解到公式和参数一级:BM25 的 k1/b/IDF 怎么来的、RRF 为什么用排名而不是分数、cross-encoder 和双塔的区别、token 预算是怎么截断的,这些我能现场推。工程层我能讲清每个并发点、每个降级路径和失败退避的实现方式。但是有几类细节我说不到源码级:多媒体那块的 ffmpeg 抽帧参数、Wails 桌面壳的打包细节、PostgreSQL 建表迁移的每一列——这些是 AI 生成、我只做了行为验证的部分。如果需要我可以在面试后补上。"

这段话的作用:主动划出能力边界,剩下的部分反而可信。面试官最怕的是"什么都说会、一问就空"。


七、必须条件反射报出的 12 个数字(全部经代码核对) ​

项值位置 / 备注
检索 Top-K(两路各取)10retriever.top_k 默认 10(部署示例里曾调到 2);RAG 最终引用取 5(rag.top_k / max_chunks)
RRF 常数 k60retriever.rrf_k;多查询融合路径里是硬编码 60
RRF 权重向量 0.7 / BM25 0.3配置校验强制和为 1(容差 0.001)
BM25 参数k1 = 1.2,b = 0.75硬编码常量,internal/retriever/bm25.go
BM25 IDFlog((N−df+0.5)/(df+0.5)+1)非负变体
中文分词bigram(生产装配额外开 unigram)单字查询靠 unigram 兜底
chunk_size / overlap512 / 50(部署配置里写成 500)code 默认 512,configs/config.yaml 是 500
上下文预算2048 token / 最多 5 条rag.max_context_tokens / max_chunks
Worker 并发 / 重试5(配置)/ 代码默认 2;重试 3 次,退避 2s→4s→8s轮询间隔 500ms;退避写在 updated_at
入库 worker 失败退避的算法time.Second << retryCount(先自增再位移)→ 首次失败即 2s注意与 Embedding/重排的 1s/2s/4s 退避不是同一套
扫描件判定阈值可读字符 < 20 拒绝入库loader.min_readable_chars
重排/v1/rerank,超时 30s,重试 3 次,QPS 限流 10,top_n 5失败降级返回原序
MCP6 个只读 Tool,审计参数截断 2000 字符,越权返回 -32001默认关闭,需显式开启
测试规模Go 63 个测试文件 / 405 个测试函数;前端 vitest 37 例;Python pytest 86 例统计口径见 07 篇

备注:这些数字是"弹药",但不要主动一次性全倒出来。面试官问到哪一层,报哪一层的数字。


八、开场 10 分钟最可能出现的 5 个问题(附一句话答法) ​

Q:这个项目团队几个人?你负责什么?

"个人项目,从需求、架构、实现到部署都是我一个人。我用规格驱动的流程做:每个阶段先写 spec/plan/task/checklist 四份文档再实现,所以我能说清每一处的设计意图;实现过程大量用 AI 辅助,但验收标准、代码评审和缺陷修复是我做的。"

Q:为什么用 Go,不用 Python?RAG 生态明明在 Python。

"选 Go 的直接原因是部署:RAG 系统的重活(并发检索、worker 池、SSE 长连接、MCP 服务)都是后端并发场景,Go 的 goroutine 和单二进制部署很合适;一个 Go 二进制能同时承载前端产物、REST/SSE/MCP 三种出口,桌面版还能用 Wails 复用同一套后端。代价我也认:LangChain、RAGAS 这些生态在 Python,所以我的做法是核心链路自己实现(混合检索、RRF、分块都是自研),而评测用 Python 生态——我单独起了一个 RAGAS 微服务,Go 侧通过反向代理把请求转过去。这是有意识的取舍,不是不知道生态在哪。"

Q:这个项目最难的点是什么?

"分两块。技术难度最高的是融合和截断的取舍:两路召回怎么合、上下文怎么裁,每一个决定都直接影响回答质量,而且没有标准答案,我是靠自己的评估 CLI 来做对比。工程上最难的是异步入库的可靠性:任务要能重试、要能重启续跑、要能幂等,还要防多个 worker 抢同一条任务——我最后是用一条带 RETURNING 的原子 UPDATE 解决的,比先 SELECT 再 UPDATE 要安全得多。"

Q:上线了吗?有多少数据?

"没有真实用户流量,这是我这个项目最大的短板,我不回避。我的数据都是自己构造的测试文档和评估集,所以任何效果数字我都不会当成生产结论来讲。 唯一一组真实跑出来的效果数字,是 RAGAS 四个指标在一次7 条样本的冒烟验收上的结果——faithfulness 1.0、answer_relevancy 0.78、context_precision 0.83、context_recall 0.95。我会主动带上'7 条样本'这个限定,因为它只能证明链路是通的、不能说明效果好;而 Recall@K 的基线我确实还没跑。 我把力气花在把评估框架搭起来:数据集驱动的 Recall@K + LLM-as-Judge 的准确性和忠实度,加上独立的 RAGAS 服务,这样一旦有真实数据,调参是有依据的。"

Q:你觉得这个项目最大的问题是什么?(必问,一定要有准备)

"三个,按优先级:一,BM25 索引是纯内存的、启动没有回灌,服务重启后混合检索会静默退化成纯向量检索,只有日志里 method 字段从 hybrid 变 vector 能看出来,这是功能级缺陷;二,召回没有 oversample,两路都用同一个 topK,融合后再截断,导致重排只能在很小的候选池里排序,没法把"向量排 30 名但语义更相关"的文档捞回来;三,没有可观测性,全仓没有 metrics 和 trace,线上排查只能看 slog 日志。这三个我都有明确的改法,但确实还没做。"


九、雷区清单(说错就掉分) ​

别说为什么改说
"向量检索就是最准的"显得不懂混合检索的动机"向量对语义好,但对精确 token(编号/错误码/专有名词)会漏,所以要 BM25 补"
"RRF 就是把分数加权相加"概念错,RRF 只用排名"RRF 用 weight/(k+rank+1) 累加排名贡献,正因为不碰原始分数,才免疫量纲差异"
"cross-encoder 比向量快"反了"cross-encoder 精度高但贵,只能对少量候选在线跑,所以放召回之后"
"上下文给得越多越好"典型新人观点"上下文要按预算控制,噪声 chunk 会稀释关键信息、增加幻觉"
"我们实测召回提升了 X%"没有真实基线,一追就崩正确的说法是:"RAGAS 有一组 7 条样本的真实结果(faith 1.0 / relevancy 0.78 / precision 0.83 / recall 0.95),但样本量太小,只能证明链路通;Recall@K 我没有实测基线,不编。"
"BM25 用了 Elasticsearch"事实错误,是自研"BM25 是我自己实现的倒排索引"
"MCP 就是给人用的 API"不懂协议动机"MCP 是让 Agent 自描述发现并调用能力的协议,Tool 带 JSON Schema,模型据此决定调用"
"这个项目所有东西我都精通"一追问就破用 6.4 的分层回答法主动划边界

十、口述稿的练习方法(给你自己的操作建议) ​

  1. 第 1 遍:照着「三、2 分钟版」念出来,用手机录音,听自己有没有卡壳的地方——卡壳处就是理解薄弱处,去 02–07 篇对应章节补。
  2. 第 2 遍:不看稿,对着白板画「4.2 架构图」并同步讲解,控制在 5 分钟内。
  3. 第 3 遍:找个人(或对着镜子)让他随机念简历上的一条 bullet,你即时展开 60 秒。
  4. 第 4 遍:只练第七节的 12 个数字 + 第八节的 5 个问题,做到不用想。
  5. 考前一晚:只读 09 速背卡片,不再看长文。

持续学习,持续构建。