prompt compression techniques

Prompt 压缩技术:让上下文窗口利用率提升 50%

上下文窗口的"房价"问题 2026 年,虽然主流模型的上下文窗口已达到 128K-1M tokens,但"窗口越大越不够用"——RAG 检索结果、工具调用返回、对话历史、知识库内容,每个环节都在争抢窗口空间。Prompt 压缩技术就像是在有限的土地上建造高层建筑,让每一个 token 都发挥最大价值。 一、Prompt 压缩的价值 1.1 成本与性能双优化 优化维度 压缩前 压缩后 改善 输入 Token 数 8000 4000 -50% API 成本(/千次) $24 $12 -50% 响应延迟 3.2s 1.8s -44% 上下文利用率 40% 75% +87.5% 信息保留率 100% 92-97% -3~8% 1.2 压缩策略分类 Prompt 压缩 ├── 无损压缩 │ ├── 符号化压缩(缩写、代码化) │ ├── 结构化压缩(JSON→紧凑格式) │ └── 去冗余压缩(删除重复信息) ├── 有损压缩 │ ├── 语义压缩(LLM 总结) │ ├── 选择性保留(截断低重要性内容) │ └── 信息蒸馏(提取关键信息) └── 混合压缩 └── 分层压缩策略 二、无损压缩技术 2.1 符号化压缩 class SymbolicCompressor: """符号化压缩——用短符号替代长文本""" SYMBOL_MAP = { # 常见指令缩写 "请分析以下内容并给出": "分析:", "请根据以上信息回答": "回答:", "以下是相关的背景信息": "背景:", "请注意以下重要事项": "注意:", # 角色缩写 "你是一个专业的": "角色:", "你的核心职责是": "职责:", # 格式缩写 "请用Markdown表格格式输出": "→MD表格", "请用JSON格式输出": "→JSON", "请用列表格式输出": "→列表", # 常见短语 "需要注意的是": "⚠", "重要提醒": "‼", "例如": "如", "也就是说": "即", } def compress(self, prompt: str) -> str: for full, symbol in self.SYMBOL_MAP.items(): prompt = prompt.replace(full, symbol) return prompt def decompress_guide(self) -> str: """生成符号说明(添加到System Prompt)""" guide = "符号说明: " for full, symbol in self.SYMBOL_MAP.items(): guide += f"{symbol}={full[:4]}.. " return guide 2.2 结构化压缩 class StructuralCompressor: """结构化压缩——压缩冗余的格式""" def compress_table(self, markdown_table: str) -> str: """压缩 Markdown 表格""" lines = markdown_table.strip().split('\n') if len(lines) < 3: return markdown_table # 提取表头和数据 headers = [h.strip() for h in lines[0].split('|')[1:-1]] data_rows = [] for line in lines[2:]: # 跳过分隔行 cells = [c.strip() for c in line.split('|')[1:-1]] data_rows.append(cells) # 紧凑格式:用 | 分隔,不用对齐 compact = '|'.join(headers) + '\n' for row in data_rows: compact += '|'.join(row) + '\n' return compact def compress_json(self, json_str: str) -> str: """压缩 JSON""" import json data = json.loads(json_str) return json.dumps(data, ensure_ascii=False, separators=(',', ':')) def compress_list(self, markdown_list: str) -> str: """压缩列表""" lines = markdown_list.strip().split('\n') items = [l.lstrip('- *').strip() for l in lines if l.strip()] return '; '.join(items) 2.3 去冗余压缩 class RedundancyRemover: """去冗余压缩""" def compress(self, prompt: str) -> str: # 1. 移除重复段落 prompt = self._remove_duplicate_paragraphs(prompt) # 2. 移除重复句子 prompt = self._remove_duplicate_sentences(prompt) # 3. 移除空白行 prompt = self._remove_blank_lines(prompt) # 4. 合并连续空格 import re prompt = re.sub(r' {2,}', ' ', prompt) return prompt def _remove_duplicate_paragraphs(self, text: str) -> str: paragraphs = text.split('\n\n') seen = set() unique = [] for p in paragraphs: normalized = p.strip().lower() if normalized and normalized not in seen: seen.add(normalized) unique.append(p) return '\n\n'.join(unique) def _remove_duplicate_sentences(self, text: str) -> str: import re sentences = re.split(r'(?<=[。.!?!?])\s+', text) seen = set() unique = [] for s in sentences: if s.strip() and s.strip() not in seen: seen.add(s.strip()) unique.append(s) return ' '.join(unique) 三、有损压缩技术 3.1 LLM 语义压缩 class SemanticCompressor: """使用 LLM 进行语义压缩""" COMPRESSION_PROMPT = """请压缩以下文本,要求: 1. 保留所有关键信息和数据 2. 保留逻辑结构和因果关系 3. 移除冗余描述和过渡语句 4. 用更简洁的表达替代冗长表达 5. 保持事实准确性 原始文本({original_tokens} tokens): {text} 输出压缩后的文本,目标:{target_tokens} tokens以内。""" def compress(self, text: str, target_ratio: float = 0.5, llm_client=None) -> str: original_tokens = self._estimate_tokens(text) target_tokens = int(original_tokens * target_ratio) prompt = self.COMPRESSION_PROMPT.format( original_tokens=original_tokens, text=text, target_tokens=target_tokens ) compressed = llm_client.generate(prompt) return compressed def _estimate_tokens(self, text: str) -> int: # 粗略估算 chinese_chars = sum(1 for c in text if '\u4e00' <= c <= '\u9fff') other_chars = len(text) - chinese_chars return chinese_chars * 2 + other_chars // 4 3.2 选择性保留压缩 class SelectiveCompressor: """选择性保留——基于重要性的压缩""" def compress(self, text: str, target_ratio: float = 0.5) -> str: # 1. 分割为句子 sentences = self._split_sentences(text) # 2. 计算每个句子的重要性分数 scored = self._score_sentences(sentences) # 3. 保留高重要性句子 target_count = int(len(sentences) * target_ratio) top_sentences = sorted(scored, key=lambda x: -x[1])[:target_count] # 4. 按原顺序排列 top_sentences.sort(key=lambda x: x[2]) # 按原始位置排序 return ' '.join(s[0] for s in top_sentences) def _score_sentences(self, sentences: list) -> list: """使用 TextRank 思想计算句子重要性""" # 基于句子间相似度构建图 n = len(sentences) scores = [1.0] * n for iteration in range(10): # 迭代计算 new_scores = [] for i, sent in enumerate(sentences): score = 0.15 # 基础分 for j, other in enumerate(sentences): if i != j: sim = self._sentence_similarity(sent, other) score += 0.85 * sim * scores[j] / max( sum(self._sentence_similarity(other, s2) for k, s2 in enumerate(sentences) if k != j), 1e-8 ) new_scores.append(score) scores = new_scores return [(sentences[i], scores[i], i) for i in range(n)] def _sentence_similarity(self, s1: str, s2: str) -> float: """计算两个句子的相似度""" words1 = set(s1.split()) words2 = set(s2.split()) intersection = words1 & words2 union = words1 | words2 return len(intersection) / max(len(union), 1) 3.3 信息蒸馏 class InformationDistiller: """信息蒸馏——提取关键信息,丢弃细节""" DISTILL_PROMPT = """从以下文本中提取关键信息,使用紧凑格式输出。 输出格式: - 主题:[1-2句话] - 关键事实:[每条1行,最多5条] - 数据:[数值和单位] - 结论:[1句话] 文本: {text}""" def distill(self, text: str, llm_client) -> str: prompt = self.DISTILL_PROMPT.format(text=text) return llm_client.generate(prompt) 四、分层压缩策略 class LayeredCompressor: """分层压缩策略——不同内容用不同压缩方法""" def __init__(self, llm_client): self.llm = llm_client self.symbolic = SymbolicCompressor() self.structural = StructuralCompressor() self.redundancy = RedundancyRemover() self.semantic = SemanticCompressor() self.selective = SelectiveCompressor() self.distiller = InformationDistiller(llm_client) def compress(self, prompt: str, target_ratio: float = 0.5) -> str: """分层压缩""" original_tokens = self._estimate_tokens(prompt) target_tokens = int(original_tokens * target_ratio) # Layer 1: 无损压缩(总是执行) prompt = self.symbolic.compress(prompt) prompt = self.structural.compress_json(prompt) prompt = self.redundancy.compress(prompt) current_tokens = self._estimate_tokens(prompt) if current_tokens <= target_tokens: return prompt # 无损压缩已达标 # Layer 2: 内容分类 sections = self._classify_sections(prompt) # Layer 3: 按类别压缩 compressed_sections = [] for section_type, content in sections: if section_type == 'rules': # 规则类:仅做符号压缩 compressed_sections.append(self.symbolic.compress(content)) elif section_type == 'knowledge': # 知识类:语义压缩 compressed_sections.append( self.semantic.compress(content, 0.4, self.llm) ) elif section_type == 'examples': # 示例类:选择性保留 compressed_sections.append( self.selective.compress(content, 0.6) ) elif section_type == 'context': # 上下文类:信息蒸馏 compressed_sections.append( self.distiller.distill(content, self.llm) ) else: compressed_sections.append(content) result = '\n\n'.join(compressed_sections) # Layer 4: 如果仍超标,全局压缩 if self._estimate_tokens(result) > target_tokens: result = self.semantic.compress(result, target_tokens / self._estimate_tokens(result), self.llm) return result def _classify_sections(self, prompt: str) -> list: """将 Prompt 分为不同类型的段落""" sections = [] current_section = "" current_type = "other" for line in prompt.split('\n'): if line.startswith('规则') or line.startswith('约束'): if current_section: sections.append((current_type, current_section)) current_section = line + '\n' current_type = 'rules' elif line.startswith('知识') or line.startswith('背景'): if current_section: sections.append((current_type, current_section)) current_section = line + '\n' current_type = 'knowledge' elif line.startswith('示例') or line.startswith('例子'): if current_section: sections.append((current_type, current_section)) current_section = line + '\n' current_type = 'examples' elif line.startswith('上下文') or line.startswith('历史'): if current_section: sections.append((current_type, current_section)) current_section = line + '\n' current_type = 'context' else: current_section += line + '\n' if current_section: sections.append((current_type, current_section)) return sections 五、对话历史压缩 class ConversationHistoryCompressor: """对话历史压缩——长对话的上下文管理""" def __init__(self, llm_client, max_history_tokens: int = 4000): self.llm = llm_client self.max_tokens = max_history_tokens def compress_history(self, messages: list) -> list: """压缩对话历史""" total_tokens = sum(self._estimate_tokens(m['content']) for m in messages) if total_tokens <= self.max_tokens: return messages # 不需要压缩 # 策略:保留最近 N 轮 + 压缩早期对话 recent_count = min(6, len(messages)) # 保留最近3轮 recent = messages[-recent_count:] old = messages[:-recent_count] # 压缩早期对话 summary = self._summarize_conversation(old) # 构建压缩后的历史 compressed = [ {"role": "system", "content": f"对话摘要:{summary}"}, *recent ] return compressed def _summarize_conversation(self, messages: list) -> str: """总结早期对话""" conversation_text = '\n'.join( f"{m['role']}: {m['content'][:200]}" for m in messages ) prompt = f"""请总结以下对话的关键信息,保留: 1. 用户的核心需求和偏好 2. 已达成的结论和决定 3. 未解决的问题 4. 重要的事实和数据 对话内容: {conversation_text} 总结(不超过200字):""" return self.llm.generate(prompt) 六、压缩效果评估 class CompressionEvaluator: """压缩效果评估器""" def evaluate(self, original: str, compressed: str, test_cases: list, llm_client) -> dict: results = { 'compression_ratio': len(compressed) / len(original), 'token_reduction': 1 - self._tokens(compressed) / self._tokens(original), } # 信息保留率评估 info_retention = self._evaluate_info_retention(original, compressed, llm_client) results['info_retention'] = info_retention # 任务效果评估 original_scores = [] compressed_scores = [] for case in test_cases: # 使用原始 Prompt original_response = llm_client.generate(original + case['input']) original_scores.append(self._score(original_response, case['expected'])) # 使用压缩 Prompt compressed_response = llm_client.generate(compressed + case['input']) compressed_scores.append(self._score(compressed_response, case['expected'])) results['original_accuracy'] = sum(original_scores) / len(original_scores) results['compressed_accuracy'] = sum(compressed_scores) / len(compressed_scores) results['accuracy_drop'] = results['original_accuracy'] - results['compressed_accuracy'] # 成本节省 results['cost_saving'] = results['token_reduction'] return results 压缩效果实测数据 压缩方法 压缩率 信息保留 准确率变化 延迟改善 符号压缩 15% 100% 0% +10% 去冗余 20% 100% 0% +15% 语义压缩 45% 94% -3% +40% 选择性保留 50% 90% -5% +45% 信息蒸馏 65% 85% -8% +55% 分层压缩 50% 96% -2% +44% 七、最佳实践 先无损后有损:先尝试无损压缩,不够再考虑有损 分层压缩最优:不同内容用不同策略,综合效果最好 规则不可压缩:System Prompt 中的规则和约束不应被有损压缩 压缩vs精简:很多时候重新设计比压缩更有效 监控压缩质量:定期评估压缩后的任务效果 缓存压缩结果:相同输入的压缩结果可以缓存 结语 Prompt 压缩是在信息密度和效果之间寻找最优平衡点的艺术。2026 年的工具链已经足够成熟,可以实现接近无损的 50% 压缩——这意味着同样的上下文窗口可以容纳两倍的信息,同样的预算可以处理两倍的请求。 ...

2026-06-28 · 6 min · 1189 words · 硅基 AGI 探索者
prompt compression

Prompt压缩技术

概述 Prompt压缩技术是AI智能体领域中Prompt压缩技术的重要主题。本文将从多个角度深入分析这一话题,为读者提供系统性的认知框架和实践参考。 核心概念 基本定义 在深入讨论之前,我们需要明确几个核心概念。AI智能体是指能够感知环境、理解指令、规划行动并调用工具完成任务的AI系统。与传统的聊天机器人不同,智能体具有自主性、目标导向性和工具使用能力。 Prompt压缩技术涉及的关键技术包括: 大语言模型:作为智能体的认知引擎,负责理解、推理和生成 工具调用:通过Function Calling或MCP协议与外部系统交互 记忆系统:短期记忆处理当前对话,长期记忆存储历史经验 规划引擎:将复杂任务分解为可执行的子步骤 技术原理 从技术层面看,Prompt压缩技术的核心在于如何让AI系统更好地理解和执行人类意图。这涉及多个技术环节的协同: 首先是感知层,智能体需要准确理解用户的自然语言指令,提取关键信息和约束条件。其次是规划层,将高层目标分解为具体的执行步骤。然后是执行层,调用合适的工具完成每个步骤。最后是反馈层,根据执行结果调整后续策略。 实践分析 当前现状 在Prompt工程领域,当前的技术实践呈现出几个明显特征: 工程化程度提升:从实验室原型到生产级系统,工程能力成为关键差异化因素 评估体系完善:越来越多标准化的评测基准被提出,帮助开发者量化能力边界 开源生态繁荣:开源框架和工具链的成熟降低了开发门槛 安全意识增强:对AI安全和对齐问题的重视程度显著提升 关键挑战 尽管进展显著,Prompt压缩技术仍面临几个核心挑战: 技术挑战: 大模型的幻觉问题在智能体场景下被放大,因为智能体需要做出实际决策 多步推理中的错误累积效应导致长程任务成功率下降 工具调用的可靠性受外部API稳定性影响 工程挑战: 智能体的可观测性不足,调试和排错困难 成本控制与性能优化的平衡 从单机到分布式部署的架构复杂性 安全挑战: Prompt注入等攻击手段不断进化 智能体权限管理需要更精细化的控制 数据隐私保护在多Agent协作场景下更加复杂 优化策略 针对上述挑战,以下是几个关键优化方向: 技术优化 分而治之:将复杂任务分解为可独立验证的子任务,降低单步错误影响 多路投票:对关键决策使用多次采样投票机制,提高可靠性 渐进式信任:智能体权限从最小化开始,根据表现逐步扩展 人在回路:高风险决策保留人工审核环节 工程优化 可观测性优先:建立完善的日志、指标和追踪体系 灰度发布:新版本智能体先在小流量环境验证 自动化测试:构建端到端测试套件,防止回归 成本监控:实时追踪Token消耗和API调用成本 案例研究 为了更具体地说明Prompt压缩技术的实践价值,我们来看一个典型场景: 某科技公司在内部IT运维中部署了AI智能体,负责处理员工的工单请求。智能体需要理解员工的自然语言描述,判断问题类型,查询知识库,执行修复操作或转接人工。 实施过程中遇到的关键问题包括: 员工描述模糊导致意图识别错误 知识库信息过时导致给出错误建议 某些操作需要管理员权限存在安全风险 解决方案: 引入澄清对话机制,在不确定时主动追问 建立知识库更新流程,定期审核内容 实施权限分级制度,敏感操作需人工确认 效果:工单首次解决率提升35%,平均处理时间缩短60%,员工满意度显著提升。 未来趋势 Prompt压缩技术的发展趋势值得关注: 标准化:MCP等开放协议将推动工具接口标准化,降低集成成本 垂直化:针对特定行业和场景的专用智能体将大量涌现 协作化:多智能体协作将成为复杂任务的标准解决方案 自主化:智能体的自主决策能力将持续提升,但需要配套的安全机制 结论 Prompt压缩技术是AI智能体技术发展中的重要一环。无论是技术原理的深入理解,还是实践中的工程优化,都需要系统性思维。对于开发者和企业而言,关键在于: 理解技术能力和边界,避免过度期待 建立系统化的评估和监控体系 在创新和安全之间找到平衡 持续学习和适应快速变化的技术生态 硅基AGI探索者将持续关注Prompt工程领域的最新进展,为读者提供深度分析和实践指导。— ...

2026-06-27 · 1 min · 88 words · 硅基 AGI 探索者
鲁ICP备2026018361号