逐日AI

面试题库

共 328 题,当前筛选 2 题。

14 天 RAG:从检索到可信回答

D11 高级索引:父子文档、摘要索引、上下文检索,以及树状聚合与图检索的取舍

  • 父子索引和上下文检索都在补『块被切碎』这个问题,它们的差别到底在哪?Parent-child indexing and contextual retrieval both patch the same problem — chunks losing their context. What actually distinguishes them?
    国内高频海外高频进阶#indexing#contextual-retrieval#chunking

    分析过程 · 先想清楚再作答

    1. 这题的题眼是『补的是哪一半』。答成『一个是切块技巧、一个是加提示词』就是在描述实现,面试官想听的是它们各自作用在检索管道的哪一段。
    2. 拆的办法是把管道分成两段问:检索时看到什么、生成时看到什么。父子索引改的是**生成侧**——检索单位还是小块,只是命中之后把上下文单位换成大块;上下文检索改的是**检索侧**——块头拼进去是为了让这一块能被检索到,模型生成时并不需要它。
    3. 结论:父子索引解决『找到了但看不全』,上下文检索解决『看得全但找不到』。前者不改变谁被检索到,后者不改变模型看到多少。它们正交,可以叠加。
    4. 这个差别还决定了它们各自要用什么指标去量:上下文检索动的是名次,用召回率和 nDCG 量得到;父子索引动的是『材料够不够答』,召回率这种二值指标量不出来。我们那份 20 题评估集单文档档已经 100% 饱和,父子索引在表里跟基线持平——那不是它没用,是尺子量不了它。
    5. 顺着这条差异能推出一个立刻能用的优化:既然块头只服务检索,就不该进上下文。它进了上下文就是在每一次查询里白占预算,而且这笔钱是长期的。我们的实验里把这个开关一改,五列指标一个不变,600 token 的预算里多装进了 36 个 token。
    6. 代价也不同:父子索引的代价是索引条目变多、每次装进上下文的东西变大;上下文检索的代价是一次性要给每块调一次模型,加上索引 token 永久变大。前者是空间,后者是时间加空间。
    7. 可预期的追问是『那我全都上』。答案是先看失败案例:日志里是『材料不完整』多,还是『压根没检索到』多。没有对应的失败模式就不该上,这两个手法都不是免费的。

    How to reason about it · think before answering

    1. The hinge is which half of the pipeline each one fixes. Answering 'one is a chunking trick, the other adds a prompt' just describes implementations; the interviewer wants to know where each acts.
    2. Split the pipeline in two and ask separately: what does the retriever see, and what does the generator see. Parent-child changes the generation side — retrieval still runs on small chunks, but a hit is swapped for its parent. Contextual retrieval changes the retrieval side — the header exists so the chunk can be found at all, and the generator does not need it.
    3. Conclusion: parent-child fixes 'found it but can't read it'; contextual retrieval fixes 'readable but never found'. Neither changes what the other changes, so they compose.
    4. That difference also dictates which metric can see each one. Contextual retrieval moves rank, so recall and nDCG catch it. Parent-child moves 'is the evidence sufficient to answer', which a binary recall metric cannot see. Our 20-question set is already saturated at 100% on single-document questions, so parent-child comes out level with the baseline — that is the ruler failing, not the technique.
    5. That difference yields a free optimization: since the header only serves retrieval, keep it out of the context window. Leaving it in pays rent on every single query. Flipping that one switch in our lab freed 36 tokens inside a 600-token budget with every metric unchanged.
    6. The costs differ too. Parent-child costs index entries and a bigger context unit. Contextual retrieval costs one model call per chunk up front plus a permanently larger index. One is space; the other is time and space.
    7. Expect the follow-up 'why not both'. Look at the failure logs first: are you mostly seeing incomplete evidence, or nothing retrieved at all? Without the matching failure mode, neither is worth its price.

    答题要点

    • 父子索引作用在生成侧:检索单位是小块,上下文单位换成父块,解决『找到了但看不全』。
    • 上下文检索作用在检索侧:块头让块能被检索到,解决『看得全但找不到』。
    • 两者正交可叠加;块头只该进索引不该进上下文,否则每次查询都在为它付钱。
    • 父子索引的代价是索引条目与上下文单位变大;上下文检索的代价是一次性建索引调用加永久变大的索引。
    • 选哪个看失败案例:材料不完整选前者,压根没检索到选后者。

    Key points

    • Parent-child acts on the generation side: retrieve small, swap in the parent for context. It fixes 'found but unreadable'.
    • Contextual retrieval acts on the retrieval side: the header makes the chunk findable. It fixes 'readable but never found'.
    • They are orthogonal and compose; keep the header in the index only, never in the context window.
    • Parent-child costs more index entries and a larger context unit; contextual retrieval costs one call per chunk plus a permanently larger index.
    • Pick based on the observed failure: incomplete evidence points to the former, zero retrieval to the latter.
  • 上下文检索要给每个块调一次模型,这笔一次性成本怎么估?有哪些办法能压下来?Contextual retrieval needs one model call per chunk. How do you estimate that one-off cost, and what levers bring it down?
    国内高频海外高频深入#contextual-retrieval#prompt-caching#cost

    分析过程 · 先想清楚再作答

    1. 这题考的是你有没有真的算过账。只会说『用提示词缓存就便宜了』属于听过没做过——面试官会追问缓存到底省在哪一项上。
    2. 先把成本拆开:一次性 = 每块的输入 + 输出 + 全量 embedding;每次查询 = 块头在重排和上下文里各被读一遍。**这两笔要分开记**,因为它们随业务量的增长方式完全不同。
    3. 一次性那笔的主项是『同一篇文档被重复读了多少遍』。一篇切成 n 块就要读 n 遍,这是成本的大头。提示词缓存省的正是这一项:把整篇放在提示词最前面并标记为可缓存,第一块付一次缓存写入,后面 n-1 块只付缓存读取,而读取价通常比输入价低一个数量级。
    4. 顺序不能反:缓存按前缀匹配,整篇必须在前、块内容在后。把变化的块放前面,前缀次次都变,缓存一次都不会命中——这是最常见的翻车点。
    5. 我们的实测:30 篇、134 块,不开缓存输入 103017 token,开缓存后拆成写入 17340 加读取 60137,一次性成本降约 29%。**块切得越碎这个比例越高**,因为重复读的次数更多。
    6. 结论反直觉但很实用:一次性那笔是小钱,摊到 217 次查询就降到每次查询成本的一成以下;真正的长期账是每次查询多出来的那几十个 token(我们量到 +12.3%)。所以压成本的第一优先级不是压建索引,而是让块头别进上下文、别过长、别对全库无差别地生成。
    7. 最后一条是加分项:花这笔钱之前先确认你的评估环境**测得出**收益。我们的离线环境里向量路对召回的独立贡献实测为 0,所以它根本没法回答『块头对向量侧有没有用』——在这种环境里做的 A/B 会给你一个看起来有数字支撑的错误结论。

    How to reason about it · think before answering

    1. This checks whether you have actually done the arithmetic. Saying 'prompt caching makes it cheap' without knowing which line item it touches is a tell.
    2. Split the bill first: one-off = per-chunk input + output + full re-embedding; per-query = the header read twice, once by the reranker and once in the context. Keep them separate, because they scale with completely different things.
    3. The dominant term on the one-off side is how many times the same document is re-read. A doc split into n chunks is read n times. Prompt caching attacks exactly that: put the whole document first and mark it cacheable, pay a cache write once, then cache reads for the remaining n-1, typically an order of magnitude cheaper than input.
    4. Order matters. Caching is prefix-matched, so the document must come first and the chunk after. Put the varying part first and the prefix changes every call — zero cache hits. This is the most common way people get it wrong.
    5. Our measurement: 30 docs, 134 chunks. Without caching, 103017 input tokens; with caching, 17340 written plus 60137 read, cutting the one-off cost by roughly 29%. The finer the chunks, the bigger the saving, because re-reads multiply.
    6. The counter-intuitive part is the useful part: the one-off cost amortizes below 10% of per-query cost after about 217 queries. The lasting bill is the extra tokens every query carries (we measured +12.3%). So the first lever is not cheaper index building — it is keeping the header out of the context, keeping it short, and not generating it for the whole corpus indiscriminately.
    7. A bonus point: before spending any of it, confirm your evaluation setup can actually detect the benefit. In our offline harness the vector route contributed exactly zero unique answer documents, so it cannot answer whether headers help embeddings at all — an A/B run there hands you a wrong conclusion that looks numerically supported.

    答题要点

    • 把账拆成一次性(每块的输入输出 + 全量 embedding)和每次查询(块头在重排与上下文里各读一遍)两笔。
    • 一次性的大头是同一篇被重复读 n 遍;提示词缓存把它压成一次写入加 n-1 次读取。
    • 缓存按前缀匹配,整篇必须放在提示词最前面,块内容在后,顺序反了一次都不会命中。
    • 实测 30 篇 134 块,一次性成本降约 29%,块越碎省得越多。
    • 长期账在每次查询:块头别进上下文、控制长度、只对真正需要的文档生成。

    Key points

    • Split into one-off (per-chunk input/output plus re-embedding) and per-query (header read by both reranker and generator).
    • The one-off is dominated by re-reading each document n times; caching turns that into one write plus n-1 reads.
    • Caching is prefix-matched: the full document must come first, the chunk after, or you get zero hits.
    • Measured on 30 docs / 134 chunks, caching cut the one-off cost by about 29%, and finer chunks save more.
    • The lasting cost is per query: keep headers out of the context window, keep them short, and generate them selectively.