LlamaIndex 响应合成器解析:CompactAndAccumulate 的压缩累积机制与实战配置

发布时间:2026/9/10 8:51:19
LlamaIndex 响应合成器解析:CompactAndAccumulate 的压缩累积机制与实战配置 LlamaIndex 响应合成器解析CompactAndAccumulate 的压缩累积机制与实战配置【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_indexCompactAndAccumulate 是 LlamaIndex 核心库中compact_accumulate响应模式的实现类它先把检索到的多个文本块text chunks重新打包repack成更贴合 LLM 上下文窗口的合并块再对每个合并块分别生成答案并拼接输出从而在保留 Accumulate「逐块回答、信息不丢失」特性的同时显著减少 LLM 调用次数。阅读本文后你将掌握CompactAndAccumulate的完整工作流程、底层repack实现原理、四种调用形态同步/异步 × 文本/多模态以及如何通过response_mode参数在真实查询引擎中启用它。一、什么是 CompactAndAccumulate在 LlamaIndex 的响应合成器Response Synthesizer家族中Accumulate模式会为每一个文本块单独调用一次 LLM 并拼接所有回答代价是当文本块数量多时会产生大量 LLM 调用而CompactAndAccumulate在累积之前先做一步「压缩」把多个小文本块合并为数量更少、更充分填充上下文窗口的大块再对每个大块累积回答。官方 API 文档中的类定义如下见 compact_accumulate.md其成员为CompactAndAccumulate对应源码模块llama_index.core.response_synthesizers.compact_and_accumulate::: llama_index.core.response_synthesizers.compact_and_accumulate options: members: - CompactAndAccumulateCompactAndAccumulate的源码类注释只有一句话Accumulate responses across compact text chunks.对压缩后的文本块累积回答。它直接继承自Accumulate见 accumulate.py核心差异在于调用父类方法之前先用PromptHelper.repack对输入文本块做上下文窗口感知的合并。在 type.py 中ResponseMode.COMPACT_ACCUMULATE compact_accumulate的枚举文档对它的定位描述得非常明确Compact and accumulate mode first combine text chunks into larger consolidated chunks that more fully utilize the available context window, then accumulate answers for each of them and finally return the concatenation. This mode is faster than accumulate since we make fewer calls to the LLM.即先合并文本块以更充分利用上下文窗口再对每个合并块累积答案并拼接返回因此比纯 Accumulate 更快LLM 调用更少。二、工作原理repack 压缩 逐块累积CompactAndAccumulate的核心逻辑分为两步可以在 compact_and_accumulate.py 中看到完整实现。2.1 第一步用 PromptHelper.repack 压缩文本块以同步文本路径get_response为例def get_response( self, query_str: str, text_chunks: Sequence[str], separator: str \n---------------------\n, **response_kwargs: Any, ) - RESPONSE_TEXT_TYPE: Get compact response. text_qa_template self._text_qa_template.partial_format(query_strquery_str) with temp_set_attrs(self._prompt_helper): new_texts self._prompt_helper.repack( text_qa_template, text_chunks, llmself._llm ) return super().get_response( query_strquery_str, text_chunksnew_texts, separatorseparator, **response_kwargs, )关键点有两处partial_format(query_strquery_str)先把 QA 模板中的查询占位符{query_str}填充为真实查询得到携带查询上下文的模板供后续计算可用 token 空间使用。temp_set_attrs(self._prompt_helper)在临时修改PromptHelper属性默认修改其num_output为 0的上下文中调用repack确保打包计算只考虑输入/输出限制而不为生成结果预留 token结束后自动还原。repack的底层实现位于 prompt_helper.pydef repack(self, prompt, text_chunks, paddingDEFAULT_PADDING, llmNone, toolsNone): text_splitter self.get_text_splitter_given_prompt( prompt, paddingpadding, llmllm, toolstools ) combined_str \n\n.join([c.strip() for c in text_chunks if c.strip()]) return text_splitter.split_text(combined_str)它的做法是先调用get_text_splitter_given_prompt计算「在给定提示模板与 LLM 元数据context_window、num_output下单块可用的最大 token 数」得到一个按 token 计数的TokenTextSplitter然后把所有文本块以\n\n连接成一个长字符串最后按可用 chunk size 重新切分。这样原本零散的小块就被打包成了数量更少、几乎填满上下文窗口的「合并块」。2.2 第二步委托父类 Accumulate 逐块累积压缩完成后CompactAndAccumulate直接把new_texts传给父类Accumulate的get_response由父类完成累积。Accumulate的实现要点见 accumulate.pydef get_response(self, query_str, text_chunks, separator\n---------------------\n, **response_kwargs): if self._streaming: raise ValueError(Unable to stream in Accumulate response mode) tasks [ self._give_responses(query_str, text_chunk, use_asyncself._use_async, **response_kwargs) for text_chunk in text_chunks ] outputs self.flatten_list(tasks) if self._use_async: outputs run_async_tasks(outputs) return self._format_response(outputs, separator)对每个文本块调用_give_responses内部会再次对该块做一次repack块仍可能超限随后用llm.predict或llm.structured_predict生成回答所有块的回答结果通过flatten_list展平_format_response将每个回答格式化为Response {序号}: {内容}空回答显示为Empty Response各块之间用默认分隔符\n---------------------\n连接。因此最终返回的字符串结构形如Response 1: 第一个合并块的回答 --------------------- Response 2: 第二个合并块的回答三、四种调用形态与多模态支持CompactAndAccumulate提供了完整的同步/异步、文本/消息多模态矩阵四个方法在 compact_and_accumulate.py 中均有实现行为完全对称方法输入类型用途get_response(query_str, text_chunks, separator, **response_kwargs)纯文本块同步生成累积回答aget_response(...)纯文本块异步生成累积回答get_response_from_messages(query_str, message_chunks, separator, **response_kwargs)ChatMessage块同步处理含多模态内容文本/图片块的消息aget_response_from_messages(...)ChatMessage块异步处理多模态消息文本路径与消息路径的差异在于文本路径使用_prompt_helperPromptHelper与_text_qa_template默认DEFAULT_TEXT_QA_PROMPT_SEL消息路径使用_chat_prompt_helperChatPromptHelper与_chat_content_qa_template默认CHAT_CONTENT_QA_PROMPT并将输入list(message_chunks)交给repack重新打包。Accumulate的构造函数参数CompactAndAccumulate继承自它包括llm、callback_manager、prompt_helper、chat_prompt_helper、text_qa_template、chat_content_qa_template、output_cls结构化输出类型、streaming、use_async、multimodal。注意streamingTrue时会在调用时报ValueError(Unable to stream in Accumulate response mode)——累积模式本身不支持流式输出。四、源码测试如何验证压缩行为仓库的单元测试 test_compact_and_accumulate.py 精确刻画了「压缩」的效果是理解该机制最直观的佐证用两个节点context information1、context information2测试默认上下文足够大时repack会把它们合并为一个块父类Accumulate.get_response收到的text_chunks为[context information1\n\ncontext information2]仅触发 1 次 LLM 调用通过PromptHelper(context_windowprompt_tokens DEFAULT_PADDING 3, num_output0, chunk_overlap_ratio0)收紧上下文窗口后同一份文本被切成 3 块触发 3 次 LLM 调用text_chunks变为[context information1, context, information2]多模态测试文本节点 图片节点验证了get_response_from_messages路径ChatPromptHelper收紧窗口后原本合并的[TextBlock ImageBlock]会被拆分为单独的文本消息与图片消息分别触发独立 LLM 调用异步测试test_asynthesize确认aget_response/aget_response_from_messages与同步版本行为一致。测试同时验证了streamingTrue时synthesize与asynthesize都会抛出ValueError匹配信息为Unable to stream。五、如何在查询引擎中启用 compact_accumulate 模式CompactAndAccumulate的推荐使用方式不是直接实例化而是通过工厂函数get_response_synthesizer见 factory.py当response_mode ResponseMode.COMPACT_ACCUMULATE时返回该类的实例from llama_index.core import get_response_synthesizer from llama_index.core.response_synthesizers import ResponseMode synthesizer get_response_synthesizer( response_modeResponseMode.COMPACT_ACCUMULATE, # 可选llm..., text_qa_template..., output_cls..., streamingFalse ... ) response synthesizer.synthesize(query你的问题, nodesnodes)在端到端检索问答场景中更常见的做法是把response_mode直接传给查询引擎。以 retriever_query_engine.py 中的RetrieverQueryEngine为例response_mode参数默认值为ResponseMode.COMPACT改为COMPACT_ACCUMULATE即可让整个检索问答链路使用压缩累积策略from llama_index.core import VectorStoreIndex index VectorStoreIndex.from_documents(documents) query_engine index.as_query_engine(response_modecompact_accumulate) response query_engine.query(你的问题) print(response)也可在QueryEngine构造时传入response_synthesizer由get_response_synthesizer生成获得更细粒度的模板与 LLM 控制。六、选型建议何时使用 compact_accumulate结合ResponseMode各枚举的官方语义见 type.py可以做如下选型判断accumulate每个文本块独立回答、零信息合并答案间相互独立但 LLM 调用次数最多compact_accumulate先按上下文窗口合并块再逐块累积回答仍是分块拼接不跨块精炼但调用次数明显少于accumulate适合文本块小而多的场景compactCompactAndRefine同样先压缩合并但在合并块之间执行 refine 精炼输出是单一连贯答案代价是块数多时调用仍较频繁tree_summarize以自底向上的树形结构汇总输出单一摘要适合需要全局综合的场景。如果你的下游任务需要「逐块可溯源的多段回答」例如逐章点评、逐条列举检索结果的要点且希望控制成本compact_accumulate是accumulate的高效替代如果需要一段整体性总结则应优先考虑compact或tree_summarize。七、小结CompactAndAccumulate是 LlamaIndex 响应合成器家族中「效率优先、逐块输出」的代表实现它以PromptHelper.repacktoken 级TokenTextSplitter 可用上下文窗口计算为压缩引擎把检索块合并为高密度填充的合并块再交由父类Accumulate完成逐块生成与拼接。仓库中的 factory.py 提供了ResponseMode.COMPACT_ACCUMULATE工厂入口test_compact_and_accumulate.py 则从文本、多模态、同步、异步四个维度验证了压缩与拆分的确定性行为。需要说明的是该模式不支持流式输出streamingTrue会抛ValueError在启用前请确认你的 LLM 调用与输出格式预期与该行为一致。【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询