prompt-repetition
原文:🇺🇸 英文
已翻译
包含 1 个脚本检查通过 / 未检测到疑似敏感代码
用于提升LLM准确率的提示词重复技法。在70项基准测试中,67%(47/70)的场景实现了显著性能提升,可在轻量模型(haiku、flash、mini系列)中自动应用。
10.7k次下载
NPX安装
npx skill4agent add supercent-io/skills-template prompt-repetition标签
翻译版元数据已加入标签,便于Agent理解和查找SKILL.md 内容(中文)
查看翻译对照 →Prompt Repetition(提示词重复)
解决的问题
LLM是Causal Language Model,训练时每个token仅参考之前的token,由此导致以下问题:
- 上下文-问题矛盾:处理上下文时还未获取到问题信息
- 选项优先型MCQ问题:查看选项时无法完全理解问题语境
- 位置/索引问题:长列表中针对特定位置信息的注意力权重被弱化
提示词重复可让第二次处理流程参考第一次的全部内容,从而获得类似双向注意力机制的部分效果。
何时使用该技巧
- 使用轻量模型时:claude-haiku、gemini-flash、gpt-4o-mini等
- 选项优先型客观题:选项早于问题出现的选择题
- 上下文+问题场景:长上下文中的特定信息检索
- 索引/位置类任务:库存、列表中的位置查询
- NPC对话:维持游戏AI角色的一致性
- 非推理任务:不使用Chain-of-Thought(CoT)的任务
工作原理
传统因果注意力的局限
[Context] → [Question]
↓
处理Context token时无法参考Question内容
Question token出现时,对Context的注意力权重已确定提示词重复的解决方案
[第一次处理] [第二次处理]
Context → Question → Context' → Question'
↑ ↑
可参考第一次处理的全部内容在第二次重复处理中,模型会重新处理第一次提示词的全部信息,并强化核心概念的注意力权重,以此提升性能。
注意:这并非将模型架构改为双向机制,而是通过提示词工程缓解因果模型的局限性。
研究结果(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:根据任务类型确定重复次数
| 任务类型 | 关键词模式 | 重复次数 | 预期提升幅度 |
|---|---|---|---|
| 选项优先型MCQ | | 2次 | +15-40个百分点 |
| 索引/位置类 | | 3次 | +50-76个百分点 |
| 上下文+问题 | 普通问题 | 2次 | +5-15个百分点 |
| 搭配CoT使用 | | 0次(不适用) | ~0% |
步骤3:检查token限制
python
# 自动应用前的上下文检查
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:转换提示词
python
def apply_prompt_repetition(prompt: str, times: int = 2) -> str:
"""将提示词重复指定次数
Args:
prompt: 原始提示词
times: 重复次数(默认2次)
Returns:
重复后的提示词
"""
if times <= 1:
return prompt
return "\n\n".join([prompt] * times)实作示例
示例1:选项优先型MCQ(效果最显著)
应用前:
A. Paris
B. London
C. Berlin
D. Madrid
Which city is the capital of France?
Reply with one letter.应用后(重复2次):
A. Paris
B. London
C. Berlin
D. Madrid
Which city is the capital of France?
Reply with one letter.
A. Paris
B. London
C. Berlin
D. Madrid
Which city is the capital of France?
Reply with one letter.预期输出:
A准确率:原78% → 应用后93%(+15个百分点)
示例2:索引/位置类任务(提升幅度最大)
应用前:
Inventory:
1. Iron Sword
2. Leather Armor
3. Health Potion (x5)
4. Magic Staff
...
25. Dragon Scale
...
50. Ancient Map
What item is in slot 25?应用后(重复3次):
提示词重复3次
预期输出:
Dragon Scale准确率:原21% → 应用后97%(+76个百分点)
示例3:工具调用提示词处理
注意:包含工具调用指令的提示词也需完整重复。为实现简洁性与一致性,采用全量重复方式。
应用前:
Use the calculator tool to compute 234 * 567.
What is the result?应用后(重复2次):
Use the calculator tool to compute 234 * 567.
What is the result?
Use the calculator tool to compute 234 * 567.
What is the result?研究结果显示,包含工具调用部分的全量重复同样有效。
生产级实现
自动应用转换器
python
"""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模式(不适用提示词重复)
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+번째",
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
# 检测到CoT模式则跳过
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测试方法
python
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%}p")核心测量指标
| 指标 | 测量方法 |
|---|---|
| 准确率 | 正确率对比 |
| 一致性 | 同一提示词执行10次的结果差异 |
| Token成本 | 输入token增长率 |
| 延迟 | p50、p99延迟对比 |
不适用场景
| 场景 | 原因 |
|---|---|
| 使用CoT时 | 推理过程已提供足够上下文 |
| 高性能模型(opus、sonnet) | 已优化完善,效果微乎其微 |
| 超长提示词 | 存在超出上下文限制的风险 |
| 已应用过重复处理 | 重复应用会浪费token |
成本-准确率分析
| 指标 | 基准值 | 重复应用后 | 变化幅度 |
|---|---|---|---|
| 输入Token | 500/请求 | 1000/请求 | +100% |
| 输出Token | 100/请求 | 100/请求 | 0% |
| 延迟(p50) | 450ms | 460ms | +2% |
| 延迟(p99) | 1200ms | 1250ms | +4% |
| 准确率 | 78% | 89% | +14个百分点 |
| 单正确答案成本 | $0.019 | $0.020 | +5% |
核心结论:Prefill阶段在GPU中高度并行化,因此输入token翻倍对延迟的影响极小
Multi-Agent整合
各Agent的自动应用策略
| Agent | 模型 | 重复应用设置 | 应用位置 |
|---|---|---|---|
| Claude Orchestrator | opus/sonnet | 可选 | - |
| Claude Executor | haiku | 自动应用 | skill_loader.py |
| Gemini Analyst | flash | 自动应用 | MCP调用时 |
| OpenAI | gpt-4o-mini | 自动应用 | skill_loader.py |
避免重复应用
在多Agent流水线中,为避免重复应用可采取以下措施:
- 使用标记:通过标记检测已处理的提示词
<!-- prompt-repetition-applied --> - 传递元数据:Agent间通过头信息传递状态
x-prompt-repetition-applied: true - 由编排器管理:Claude Orchestrator跟踪子Agent的应用状态
应用模式
[Claude Sonnet] 制定计划(无需重复)
↓
[Gemini Flash] 分析(自动重复2次,添加标记)
↓
[Claude Haiku] 执行(检测到标记 → 跳过重复应用)skill_loader.py集成指南
推荐实现
python
# 需添加到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:
"""处理自动应用的技巧"""
# 自动应用prompt-repetition
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次
- 监控上下文:注意避免因重复导致超出上下文限制
- 检查标记:必须通过标记避免重复应用
禁止操作
- 禁止用填充替代:用等字符仅增加长度无效果(研究结果验证)
. - 禁止与CoT同时使用:效果会相互抵消
- 禁止强制应用于高性能模型:此类模型已优化完善
- 禁止重复应用:无标记的连续应用会浪费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次
搭配CoT:0次(不适用)
=== 效果(Google Research 2025) ===
提升占比:67%(47/70基准任务)
性能下降:0例
最大提升幅度:+76个百分点(NameIndex任务)
=== 成本 ===
输入Token:+100%
延迟:+2%(Prefill并行化)
单正确答案成本:+5%
=== 避免重复应用 ===
标记:<!-- prompt-repetition-applied -->