🚀 快速安装
复制以下命令并运行,立即安装此 Skill:
npx @anthropic-ai/skills install supercent-io/skills-template/prompt-repetition
💡 提示:需要 Node.js 和 NPM
解决的问题
LLM 被训练为因果语言模型,其中每个 token 仅能关注之前的 tokens。这导致了:
- 上下文-问题错位:模型在处理上下文时,还不知道后续的问题是什么
- 选项优先的多选题困境:当先看到选项时,无法充分理解提问的上下文
- 位置/索引识别困难:在长列表中,针对特定位置信息的注意力权重会减弱
提示词重复技术使第二次处理能够参考第一次处理的完整结果,从而模拟了双向注意力的部分优势。
何时使用此技能
- 使用轻量级模型时:如 claude-haiku, gemini-flash, gpt-4o-mini 等
- 选项优先的多选题:答案选项出现在问题之前的选择题
- 长上下文 + 问题:需要在长文本中搜索特定信息时
- 索引/位置任务:在库存或列表中基于位置的查询
- NPC 对话:为游戏 AI 角色保持对话一致性
- 非推理任务:不需要使用思维链的任务
工作原理
因果注意力的局限性
[上下文] → [问题]
↓
在处理上下文 tokens 时,无法参考后续的问题内容
当问题 tokens 出现时,上下文的注意力权重已经确定
提示词重复如何解决这个问题
[第一次处理] [第二次处理]
上下文 → 问题 → 上下文' → 问题'
↑ ↑
可以引用第一次处理的完整内容
在第二次重复中,模型重新处理整个第一次提示的信息,并加强对关键概念的注意力权重,从而提升性能。
注意:这并非改变模型架构以实现双向注意力,而是一种通过提示工程来缓解因果模型局限性的技术。
研究成果 (Google Research 2025)
| 指标 | 结果 |
|---|---|
| 显著提升 (p < 0.1) | 47 / 70 个基准测试 |
| 性能下降 | 0 个 |
| 无显著变化 | 23 个 |
| 提升率 | 67% |
最显著的提升: Gemini 2.0 Flash-Lite 在 NameIndex 任务上:21.33% → 97.33% (+76 个百分点)
测试过的模型
- Gemini 2.0 Flash / Flash Lite
- GPT-4o / GPT-4o-mini
- Claude 3.7 Sonnet / Claude 3 Haiku
- Deepseek V3
测试过的基准
- ARC (Challenge) – 科学推理
- OpenBookQA – 开放域问答
- GSM8K – 数学问题
- MMLU-Pro – 多任务语言理解
- MATH – 数学问题求解
- NameIndex / MiddleMatch – 自定义位置任务
应用步骤
步骤 1:确认自动应用的目标模型
| 提供商 | 自动应用的模型 | 排除的模型 |
|---|---|---|
| Claude | haiku 系列 | opus, sonnet |
| Gemini | flash, flash-lite | pro, ultra |
| OpenAI | gpt-4o-mini, gpt-low | gpt-4o, gpt-4 |
步骤 2:根据任务类型确定重复次数
| 任务类型 | 关键词模式 | 重复次数 | 预期提升 |
|---|---|---|---|
| 选项优先的多选题 | 选项 A. B. C. D. 先出现 |
2× | +15-40 个百分点 |
| 索引/位置任务 | slot, position, index, 第N个 |
3× | +50-76 个百分点 |
| 上下文 + 问题 | 一般性问题 | 2× | +5-15 个百分点 |
| 包含思维链 | step by step, think through |
0× (不应用) | ~0% |
步骤 3:检查 Token 限制
# 自动应用前检查上下文限制
max_context = model_context_window * 0.8 # 80% 的安全余量
if len(prompt_tokens) * repetitions > max_context:
repetitions = max(1, int(max_context / len(prompt_tokens)))
步骤 4:提示词转换
def apply_prompt_repetition(prompt: str, times: int = 2) -> str:
"""将提示词重复指定的次数
参数:
prompt: 原始提示词
times: 重复次数(默认 2)
返回:
重复后的提示词
"""
if times <= 1:
return prompt
return "\n\n".join([prompt] * times)
实践示例
示例 1:选项优先的多选题(效果最显著)
应用前:
A. 巴黎
B. 伦敦
C. 柏林
D. 马德里
哪个城市是法国的首都?
请回复一个字母。
应用后(重复 ×2):
A. 巴黎
B. 伦敦
C. 柏林
D. 马德里
哪个城市是法国的首都?
请回复一个字母。
A. 巴黎
B. 伦敦
C. 柏林
D. 马德里
哪个城市是法国的首都?
请回复一个字母。
预期输出:
A
准确率:原始 78% → 重复后 93% (+15 个百分点)
示例 2:索引/位置任务(效果最大化)
应用前:
库存清单:
1. 铁剑
2. 皮革护甲
3. 治疗药水 (x5)
4. 魔法杖
...
25. 龙鳞
...
50. 古代地图
第 25 个槽位是什么物品?
应用后(重复 ×3):
提示词完整重复 3 次
预期输出:
龙鳞
准确率:原始 21% → 重复后 97% (+76 个百分点)
示例 3:工具调用提示处理
注意:包含工具调用指令的提示词也会被完整重复。为了简化实现和保证一致性,采用了完整重复的方法。
应用前:
使用计算器工具计算 234 * 567。
结果是多少?
应用后(重复 ×2):
使用计算器工具计算 234 * 567。
结果是多少?
使用计算器工具计算 234 * 567。
结果是多少?
研究结果表明,包含工具调用部分的完整重复同样有效。
生产级实现
自动应用转换器
"""prompt_repetition_transformer.py"""
from dataclasses import dataclass, field
from typing import Optional, Callable, List
import re
# 各模型的上下文窗口(以 token 计)
MODEL_CONTEXT_WINDOWS = {
"claude-3-haiku": 200_000,
"claude-haiku": 200_000,
"gemini-flash": 1_000_000,
"gemini-flash-lite": 1_000_000,
"gemini-2.0-flash": 1_000_000,
"gpt-4o-mini": 128_000,
"gpt-low": 128_000,
}
# 自动应用的目标模型列表
AUTO_APPLY_MODELS = list(MODEL_CONTEXT_WINDOWS.keys())
# 思维链模式(应用此技能时需排除)
COT_PATTERNS = [
r"step by step",
r"think through",
r"let's think",
r"reasoning:",
r"chain of thought",
]
# 位置/索引任务模式(需要 3 次重复)
POSITION_PATTERNS = [
r"slot \d+",
r"position \d+",
r"index \d+",
r"\d+(st|nd|rd|th)",
r"item \d+",
r"row \d+",
r"column \d+",
]
@dataclass
class PromptRepetitionConfig:
"""提示词重复配置"""
default_repetitions: int = 2
position_repetitions: int = 3
separator: str = "\n\n"
max_context_ratio: float = 0.8
applied_marker: str = "<!-- prompt-repetition-applied -->"
class PromptRepetitionTransformer:
"""为轻量级模型自动应用提示词重复的转换器"""
def __init__(self, config: Optional[PromptRepetitionConfig] = None):
self.config = config or PromptRepetitionConfig()
def should_apply(self, model: str, prompt: str) -> bool:
"""判断是否自动应用"""
# 如果已应用,则跳过
if self.config.applied_marker in prompt:
return False
# 检查目标模型
model_lower = model.lower()
if not any(m in model_lower for m in AUTO_APPLY_MODELS):
return False
# 检测到思维链模式时跳过
prompt_lower = prompt.lower()
for pattern in COT_PATTERNS:
if re.search(pattern, prompt_lower):
return False
return True
def determine_repetitions(self, prompt: str, model: str) -> int:
"""根据任务类型确定重复次数"""
prompt_lower = prompt.lower()
# 检测到位置/索引模式 → 3 次重复
for pattern in POSITION_PATTERNS:
if re.search(pattern, prompt_lower):
return self.config.position_repetitions
return self.config.default_repetitions
def estimate_tokens(self, text: str) -> int:
"""简单的 token 估算(速度优先于精度)"""
# 大约估算 4 个字符 = 1 个 token
return len(text) // 4
def transform(self, prompt: str, model: str) -> str:
"""对提示词应用重复"""
if not self.should_apply(model, prompt):
return prompt
repetitions = self.determine_repetitions(prompt, model)
# 检查上下文限制
model_lower = model.lower()
max_tokens = 128_000 # 默认值
for m, tokens in MODEL_CONTEXT_WINDOWS.items():
if m in model_lower:
max_tokens = tokens
break
max_allowed = int(max_tokens * self.config.max_context_ratio)
prompt_tokens = self.estimate_tokens(prompt)
# 如果超过 token 限制,则减少重复次数
while prompt_tokens * repetitions > max_allowed and repetitions > 1:
repetitions -= 1
if repetitions <= 1:
return prompt
# 应用重复并添加标记
repeated = self.config.separator.join([prompt] * repetitions)
return f"{self.config.applied_marker}\n{repeated}"
def wrap_llm_call(self, llm_fn: Callable, model: str) -> Callable:
"""包装 LLM 调用函数"""
def wrapped(prompt: str, **kwargs):
transformed = self.transform(prompt, model)
return llm_fn(transformed, **kwargs)
return wrapped
如何衡量效果(验证方法)
A/B 测试方法
def run_ab_test(prompts: List[str], llm_fn, model: str, ground_truth: List[str]):
"""提示词重复效果的 A/B 测试"""
transformer = PromptRepetitionTransformer()
results = {"baseline": [], "repeated": []}
for prompt, expected in zip(prompts, ground_truth):
# 基线测试
response_a = llm_fn(prompt)
results["baseline"].append(response_a == expected)
# 应用重复后的测试
repeated_prompt = transformer.transform(prompt, model)
response_b = llm_fn(repeated_prompt)
results["repeated"].append(response_b == expected)
baseline_acc = sum(results["baseline"]) / len(prompts)
repeated_acc = sum(results["repeated"]) / len(prompts)
print(f"基线准确率:{baseline_acc:.2%}")
print(f"重复后准确率:{repeated_acc:.2%}")
print(f"提升:{repeated_acc - baseline_acc:+.2%}个百分点")
关键指标
| 指标 | 测量方法 |
|---|---|
| 准确率 | 比较正确答案的比例 |
| 一致性 | 同一提示运行 10 次的方差 |
| Token 成本 | 输入 token 的增加率 |
| 延迟 | 比较 p50, p99 延迟 |
何时不使用
| 场景 | 原因 |
|---|---|
| 使用思维链时 | 推理过程本身已提供了上下文 |
| 推理模型 (opus, sonnet) | 已优化,效果甚微 |
| 极长的提示词 | 可能超出上下文限制 |
| 已经重复过 | 重复应用浪费 token |
成本-准确率分析
| 指标 | 基线 | 应用重复 | 变化 |
|---|---|---|---|
| 输入 tokens | 500/请求 | 1000/请求 | +100% |
| 输出 tokens | 100/请求 | 100/请求 | 0% |
| 延迟 (p50) | 450ms | 460ms | +2% |
| 延迟 (p99) | 1200ms | 1250ms | +4% |
| 准确率 | 78% | 89% | +14 个百分点 |
| 每正确回答成本 | $0.019 | $0.020 | +5% |
关键洞察: 预填充阶段在 GPU 上是高度并行化的,因此输入 token 翻倍对延迟影响极小。
多代理集成
各代理的自动应用策略
| 代理 | 模型 | 是否应用重复 | 应用位置 |
|---|---|---|---|
| Claude 协调器 | opus/sonnet | 可选 | – |
| Claude 执行器 | haiku | 自动 | skill_loader.py |
| Gemini 分析器 | flash | 自动 | 调用 MCP 时 |
| OpenAI | gpt-4o-mini | 自动 | skill_loader.py |
防止重复应用
为防止在多代理流水线中重复应用:
- 使用标记:通过
<!-- prompt-repetition-applied -->标记检测是否已应用 - 传递元数据:在代理之间传递
x-prompt-repetition-applied: true头信息 - 协调器管理:Claude 协调器在调用子代理时跟踪是否已应用重复
应用模式
[Claude Sonnet] 规划(无需重复)
↓
[Gemini Flash] 分析(自动应用 2 次重复,添加标记)
↓
[Claude Haiku] 执行(检测到标记 → 跳过重复应用)
skill_loader.py 集成指南
推荐实现
# 添加到 skill_loader.py 的代码
from prompt_repetition_transformer import PromptRepetitionTransformer
class SkillLoader:
def __init__(self, ...):
# ... 现有代码 ...
self.prompt_transformer = PromptRepetitionTransformer()
def apply_auto_skills(self, prompt: str, model: str) -> str:
"""处理自动应用的技能"""
# 自动应用提示词重复
for skill in self.skills.values():
auto_apply = skill.get('data', {}).get('auto-apply', {})
if auto_apply.get('trigger') == 'auto':
target_models = auto_apply.get('models', [])
if any(m in model.lower() for m in target_models):
prompt = self.prompt_transformer.transform(prompt, model)
return prompt
约束条件
强制性规则
- 优先轻量级模型:对 haiku, flash, mini 系列效果最显著
- 限制重复次数:一般任务 2 次,位置任务最多 3 次
- 监控上下文:注意重复可能导致上下文溢出
- 检查标记:必须检查标记以防止重复应用
禁止事项
- 禁止用填充替代:添加
.等字符增加长度无效(根据研究) - 不要与思维链结合:效果会相互抵消
- 不要强制应用于推理模型:它们已优化
- 禁止重复应用:无标记的连续应用会浪费 token
快速参考
=== 自动应用目标模型 ===
claude-3-haiku, claude-haiku
gemini-flash, gemini-flash-lite, gemini-2.0-flash
gpt-4o-mini, gpt-low
=== 重复次数 ===
一般任务:2 次
位置/索引任务(包含 slot/position/index 等关键词):3 次
包含思维链:0 次(不应用)
=== 效果(Google Research 2025) ===
提升率:67% (47/70 个基准测试)
性能下降:0 个案例
最大提升:+76 个百分点 (NameIndex)
=== 成本 ===
输入 tokens:+100%
延迟:+2% (预填充并行化)
每正确回答成本:+5%
=== 防止重复应用 ===
标记:<!-- prompt-repetition-applied -->
参考文献
📄 原始文档
完整文档(英文):
https://skills.sh/supercent-io/skills-template/prompt-repetition
💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)