题解生成中的长文本处理:上下文窗口管理与分段理解策略

题解生成中的长文本处理:上下文窗口管理与分段理解策略 题解生成中的长文本处理上下文窗口管理与分段理解策略一、当一道题的题解超出了模型的上下文窗口使用 LLM 生成算法题解时理想情况是把题目描述、样例、约束条件一并丢给模型然后拿到一份完整的题解。现实却没这么简单。有些题目描述本身就超过 2000 字加上样例和约束条件总 token 数轻松突破 4K。如果题目还涉及到复杂的图结构或依赖外部知识库如特定算法的背景介绍上下文窗口很容易被塞满。当输入超过模型的上下文上限时模型要么截断要么丢失关键信息导致题解质量急剧下降。更麻烦的是你还希望模型在生成题解的同时能参考历史对话中的纠错反馈。这意味着输入文本的规模只增不减。如何在不丢失关键信息的前提下管理长文本是这道工程题的核心。二、信息密度模型不是所有内容都同等重要解决长文本问题的第一步是承认一个前提题目描述中不同部分的「信息密度」是不同的。flowchart TD subgraph 高密度信息 A[约束条件: 1 ≤ n ≤ 10^5] B[时间复杂度要求: O(n log n)] C[特殊条件: 数组已部分有序] end subgraph 中密度信息 D[题目描述正文] E[输入输出格式说明] end subgraph 低密度信息 F[背景故事描述] G[示例的详细解释文字] H[提示与备注] end A -- I[必须保留] B -- I C -- I D -- J[可摘要] E -- J F -- K[可裁剪] G -- K H -- K基于这个分类我们可以设计一套分层摘要策略约束条件、时间复杂度要求原样保留不进行任何压缩。题目描述正文用轻量模型做摘要提取核心算法需求。样例输入输出保留数值丢弃解释性文字。背景故事、提示直接裁剪仅在首次生成时作为补充信息注入。三、实现带摘要缓存的长文本管理器from dataclasses import dataclass, field from typing import Optional import hashlib import json dataclass class TextSegment: 文本片段标记内容、类别与重要性 content: str category: str # constraint | description | example | hint priority: int # 1必须保留2可摘要3可裁剪 summary: Optional[str] None # 摘要缓存 class LongTextManager: 长文本管理器负责对题目描述进行分层压缩 设计思路 1. 将输入文本按类别拆分为多个片段。 2. 根据优先级决定保留、摘要还是裁剪。 3. 使用哈希做缓存避免对相同内容重复摘要。 4. 输出在 token 预算内的精简文本。 def __init__(self, max_tokens: int 4096): self.max_tokens max_tokens self._summary_cache: dict[str, str] {} # 粗略估计中文约 1.5 字符/token预留安全边界 self._chars_per_token 1.5 def process( self, segments: list[TextSegment], enable_summary: bool True, ) - str: 处理文本片段返回压缩后的文本 # 第一阶段高优先级内容原样保留 result_parts: list[str] [] remaining self.max_tokens for seg in segments: if seg.priority 1: result_parts.append(seg.content) remaining - self._estimate_tokens(seg.content) elif seg.priority 2 and enable_summary: summary self._get_summary(seg) result_parts.append(summary) remaining - self._estimate_tokens(summary) # priority 3 的内容直接跳过 # 第二阶段如果仍然超出限制对 priority2 做进一步压缩 while remaining 0 and result_parts: # 从末尾开始逐步移除低优内容 popped result_parts.pop() remaining self._estimate_tokens(popped) return \n\n.join(result_parts) def _get_summary(self, seg: TextSegment) - str: 获取文本摘要带缓存 cache_key hashlib.md5(seg.content.encode()).hexdigest() if cache_key in self._summary_cache: return self._summary_cache[cache_key] # 简易规则摘要提取首段 关键词 # 生产环境此处应调用轻量 LLM 做智能摘要 lines seg.content.strip().split(\n) # 取前三行作为快速摘要 quick \n.join(lines[:3]) if len(lines) 3: quick f\n共 {len(lines)} 行已省略后续内容 self._summary_cache[cache_key] quick return quick def _estimate_tokens(self, text: str) - int: 估算文本的 token 数量 return int(len(text) / self._chars_per_token) class ProblemContextBuilder: 题目上下文构建器将题目信息组装为 LLM 可消费的格式 staticmethod def build_prompt( problem: dict, manager: LongTextManager, ) - str: 构建 prompt将原始题目转换为分段后的压缩文本 segments [ TextSegment( contentf约束条件{problem.get(constraints, 无)}, categoryconstraint, priority1, ), TextSegment( contentf题目描述{problem.get(description, )}, categorydescription, priority2, ), TextSegment( contentf样例{json.dumps(problem.get(examples, []), ensure_asciiFalse)}, categoryexample, priority1, ), TextSegment( contentf提示{problem.get(hints, 无)}, categoryhint, priority3, ), ] compressed manager.process(segments) return f请根据以下题目信息生成题解 {compressed} 要求 1. 给出完整代码实现 2. 分析时间与空间复杂度 3. 解释核心思路 # ---- 使用示例 ---- if __name__ __main__: problem { constraints: 1 ≤ n ≤ 10^5, -10^9 ≤ nums[i] ≤ 10^9, description: ( 给定一个整数数组 nums 和一个目标值 target 请你在数组中找出和为目标值的那两个整数 并返回它们的数组下标。你可以假设每种输入 只会对应一个答案。但是数组中同一个元素 不能使用两遍。 * 20 # 模拟长文本 ), examples: [ {input: nums[2,7,11,15], target9, output: [0,1]} ], hints: 可以使用哈希表优化到 O(n), } manager LongTextManager(max_tokens2048) prompt ProblemContextBuilder.build_prompt(problem, manager) print(fPrompt 长度: {len(prompt)} 字符)四、边界分析与权衡4.1 简单规则摘要 vs LLM 摘要当前实现使用取前三行的规则摘要。这做法的优点是零延迟、零成本缺点是摘要质量不稳定。对于复杂题目描述可能需要调用轻量 LLM如 7B 模型做真正的语义摘要。这是一个典型的成本-质量权衡。4.2 上下文窗口的碎片化分层压缩后文本的非连续性会影响模型对上下文的理解。约束条件独立于描述文字可能导致模型忽略了两者之间的隐含关系如约束条件暗示了算法选择。缓解方案是在片段间加入衔接提示语。4.3 Token 估算的误差_estimate_tokens使用固定的字符/token 比例。对于中英文混合文本这个估算可能有 20%-30% 的偏差。生产环境应该使用模型对应的 tokenizer 做精确计数。4.4 多轮对话的上下文膨胀随着对话轮次增加历史消息也会占用上下文窗口。需要设计消息淘汰策略——保留最近的纠错反馈丢弃较早的一般性对话。五、总结长文本处理不是模型的问题——模型的能力上限就在那里。工程化的思路是在模型能力不变的前提下通过分层管理、优先级调度、缓存复用等手段让有限的上下文窗口装下尽可能多的有价值信息。这本质上是一种信息密度优化与搜索引擎的摘要生成、推荐系统的特征筛选面临同样的挑战。