DeepSeek R1 Tutorial — 10 Practical Use Cases for the Best Chinese Reasoning AI
发布于 2026-07-19 · 2400 字 · 12 分钟阅读
过去半年我把 DeepSeek R1 当主力推理模型用,跑过奥数题、debug 过 Python 异步代码、分析过 20 页的 arXiv 论文。这篇文章把真实使用中踩过的坑和好用的 prompt 模式整理出来,不是营销稿,每个场景都附上可以直接复制的 prompt。
一句话结论:R1 不是"中文版 GPT",而是一个会先思考再回答的推理特化模型。它在需要慢思考的任务上(数学、逻辑、复杂代码)能和 GPT-5、Claude Opus 4 打平甚至反超,但在快应答、长上下文窗口、多模态上仍有短板。下面 10 个场景会讲清楚什么时候该用 R1,什么时候该换别的模型。
DeepSeek R1 的核心特性
R1 和普通聊天模型最大的区别是它的思维链(Chain-of-Thought)显式输出。API 返回里有一个独立的 reasoning_content 字段,你能在最终答案之前看到模型完整的推理过程——通常 500-3000 字,像看一个学生写解题步骤。
实测数据(DrAI 平台 2026 Q2 内部 benchmark,题目集来自 MATH-500 + HumanEval + C-Eval):
| 任务类型 | DeepSeek R1 | GPT-5 | Claude Opus 4 |
|---|---|---|---|
| 数学(MATH-500) | 97.2% | 96.8% | 94.1% |
| 代码(HumanEval) | 93.4% | 95.1% | 92.7% |
| 中文推理(C-Eval 硬子集) | 89.6% | 84.3% | 82.1% |
| 响应延迟(中位数) | 8.3s | 2.1s | 3.4s |
| 1M tokens 输入价格 | $0.55 | $5.00 | $15.00 |
看这张表就知道:R1 在中文推理上是碾压级优势,价格只有 GPT-5 的 1/9、Claude 的 1/27。代价是延迟更高——因为它真的在"思考"。
场景 1:数学推理 — 高中奥数级题目
Prompt 示例:
求方程 x! + y! = x^y 的所有正整数解,并证明解的完备性。
要求:写出完整的证明过程,不要跳步。
R1 的输出特点:它会在 reasoning_content 里先枚举小数值(x,y 从 1 到 5 逐一代入),发现 (2,2) 满足,然后证明当 x≥3 时 x! 增长速度快于 x^y 的可行域,最后给出 (1,2)、(2,2) 两组解。整个推理链 1200 字左右,没有"显然""易证"这种偷懒。
对比要点:GPT-5 会直接给出答案但证明略简;Claude 会写得更优雅但偶尔跳步;R1 最像"诚实的学生",每一步都写出来。代价是输出 token 多,成本上去。
实用建议:数学题一定要在 prompt 里加"写出完整证明"——R1 默认就喜欢详写,但你不说它有时会偷懒。复杂题目建议加 temperature: 0.6(R1 官方推荐值),别用默认 1.0。
场景 2:代码 Debug — 定位隐蔽 Bug
问题代码(Python 异步死锁):
import asyncio
async def fetch_data():
lock = asyncio.Lock()
async with lock:
return await process(lock) # bug: 嵌套获取同一个 lock
async def process(lock):
async with lock: # 死锁!
return "done"
Prompt:
这段代码 hang 住不动,运行环境 Python 3.11。
请:1) 定位 bug 2) 解释原因 3) 给出修复方案(至少 2 种)
R1 的输出特点:它会在思维链里先列出 asyncio.Lock 的语义("非可重入,同 task 二次获取会死锁"),再代入代码模拟事件循环,最后给出三种修复:传参不传 lock、改用RLock 模式(asyncio 原生不支持,需自己实现)、重构函数职责。比直接说"别嵌套"深刻得多。
对比要点:GPT-5 修代码又快又准,但有时直接给答案不解释;Claude 会写详细注释但偶尔给出不能跑的代码;R1 的思维链让你能看到它怎么推理的,便于你判断它对不对——这对生产环境 debug 价值很大。
实用建议:Debug 类任务把报错堆栈完整贴进去,R1 对 stack trace 的解读能力很强。超过 200 行的代码建议拆成函数级别分批问,否则思维链会被上下文淹没。
场景 3:论文分析 — 长文本总结与批判
Prompt 模板:
论文标题:《xxx》
摘要:[粘贴摘要]
请回答:
1. 这篇论文的核心贡献是什么?(不超过 3 句)
2. 方法论的关键创新点在哪?
3. 实验设计有什么漏洞?
4. 如果我要复现,最难的部分是什么?
R1 的输出特点:它对论文的批判性阅读强于 GPT-5 和 Claude——尤其在找实验漏洞上。让它读一篇 LLM 训练论文,它能指出"baseline 没有调参""评测集可能泄露到训练集"这类问题。中文论文(如智谱、阿里发的)它对术语的理解比英文模型准确。
对比要点:Claude Opus 4 在英文论文的优雅总结上更强;GPT-5 速度快;R1 在中文学术写作风格和找方法论问题上最强。
实用建议:不要把整篇 PDF 扔进去(R1 的 64K 上下文比 Claude 的 200K 短)。先让 Claude 或 Gemini 做第一遍摘要,把摘要 + 你关心的章节喂给 R1 做深度分析,这是性价比最高的组合。
场景 4:逻辑推理 — 经典谜题
Prompt(骑士与无赖问题):
岛上有骑士(永远说真话)和无赖(永远说假话)。
你遇到 A、B、C 三人:
A 说:"我们三个里恰好有一个无赖。"
B 说:"我们三个里恰好有两个无赖。"
C 说:"B 是骑士。"
请确定 A、B、C 各自的身份,并说明推理过程。
R1 的输出特点:它会穷举 8 种身份组合,逐一验证陈述一致性,最后得到唯一解。这种系统化搜索是 R1 的招牌——它不容易被直觉带跑。答案:A 无赖、B 骑士、C 骑士(你心算可以验证)。
对比要点:GPT-5 偶尔会在多约束逻辑题里"跳步"给错答案;Claude 严谨但慢;R1 在 AIME、Putnam 这类竞赛题的 pass@1 比 GPT-5 高 5-8 个百分点。
实用建议:逻辑题让 R1"先列出所有可能情况再验证",不要让它直接给答案——这个 prompt 习惯能把准确率再提一截。
场景 5:中文写作 — 公文、文案、报告
Prompt 模板(周报):
角色:你是我的助理,帮我写本周工作周报
输入:本周我做了——
- 完成用户登录模块重构(PHP → Go),QPS 从 800 提到 3000
- 修了 3 个 P1 bug
- 推进和支付团队的联调(卡在他们那边)
要求:
1. 用 STAR 结构
2. 量化结果
3. 控制在 300 字以内
4. 语气:务实,不要"赋能""闭环"这种词
R1 的输出特点:中文母语级流畅度,没有翻译腔。最关键的是它真听你的约束——你说不要"赋能"它就真不用,GPT-5 经常说了还是偷偷塞一个进来。
对比要点:Claude 的中文有轻微翻译腔("我们将要讨论..."这种句式);GPT-5 中文不错但偶尔用词生硬;R1 是唯一一个写出来像中国人写的。
实用建议:中文写作一定要给出负面示例("不要用 XX 词"),R1 对负面约束的遵守程度是三者里最高的。
场景 6:数据分析 — CSV 处理与洞察
Prompt:
这是某电商 7 月的销售数据(CSV 前 5 行):
date,product,channel,revenue,units
2026-07-01,SKU-A1,抖音,12800,32
2026-07-01,SKU-A1,淘宝,8600,21
...
请:
1. 写 Python 代码用 pandas 算出每个渠道的客单价
2. 找出 revenue 异常的日期(定义:偏离均值 >2σ)
3. 用一句话总结渠道分布特征
R1 的输出特点:它会写出能直接跑的 pandas 代码,并在思维链里先推理"客单价 = revenue / units,所以聚合时要用 sum 后再除",避免常见的"先求平均再平均"错误。这种数据语义推理是它的强项。
对比要点:纯代码生成 GPT-5 略强(写得简洁);但 R1 在理解数据含义和给出业务洞察上更好——它会主动说"抖音客单价高但淘宝走量,建议差异化选品",GPT-5 通常只给代码不给建议。
实用建议:数据分析类任务一定要给 R1字段含义而不只是列名。"revenue 是含税收入"比"revenue 字段"有用十倍。
场景 7:翻译 — 中英互译与术语处理
Prompt:
把下面这段技术文档翻译成英文,术语要求:
- "推理" → inference(不是 reasoning)
- "微调" → fine-tuning
- "蒸馏" → distillation
原文:R1 通过强化学习获得推理能力,不需要蒸馏 GPT-4 的输出。
R1 的输出特点:它对术语约束的遵守极强,不会自作主张。译文风格偏学术、精确。中文→英文的译文比 GPT-5 更"地道"——R1 训练数据里有大量英文论文,所以英文输出质量出乎意料地好。
对比要点:Claude 的文学性翻译(小说、诗歌)最强;GPT-5 通用翻译最快;R1 在技术文档和学术论文翻译上最准确,错译率最低。
实用建议:翻译技术内容时,先给术语表,效果立竿见影。长文档分段翻译(每段 <2000 字),不要一次扔整篇。
场景 8:创意写作 — 小说、剧本、诗
Prompt:
写一个 500 字的科幻短篇,设定:
- 2077 年,记忆可以上传到云端
- 主角是一个"记忆审计员"
- 必须出现一个反转
风格:刘慈欣式的硬科幻,不要赛博朋克
R1 的输出特点:坦白说,创意写作不是 R1 的强项。它的故事逻辑严密但语言偏平,反转设计不错但情绪张力弱于 Claude。
对比要点:创意写作的排序是 Claude Opus 4 > GPT-5 > R1。Claude 的文学性碾压级;GPT-5 平衡;R1 适合设定严密、逻辑要求高的硬科幻或悬疑,不适合言情、散文。
实用建议:需要 R1 写创意内容时,给它一个明确的结构约束("开头-发展-反转-收尾"四段式),它的结构感比想象力好。
场景 9:知识问答 — 中文领域的深度问答
Prompt:
对比 Rust 和 Zig 在系统编程上的差异,
重点说明:
1. 内存安全机制的本质区别
2. 各自适合什么场景
3. 为什么 Linux 内核选 Rust 不选 Zig?
R1 的输出特点:中文技术问答质量极高,尤其对中文技术社区流行的问题(比如"为什么 Vue 比 React 简单"" Cursor 和 Copilot 哪个好")它给出的答案更贴近中文开发者的视角。
对比要点:英文技术问答 GPT-5 和 Claude 更新更快(R1 的训练数据截止稍早);但中文技术问答和中国本土产品/公司相关的问题,R1 是最好的。
实用建议:问 R1 知识类问题时加上"请说明你的依据",它会主动指出哪些是确定的、哪些是推测的——减少幻觉。
场景 10:多轮对话 — 复杂任务的拆解协作
对话示例(设计一个推荐系统):
用户:我要给电商 APP 做推荐,预算 50 万 MAU
R1:[思维链] 先问清场景...
→ 反问:冷启动比例多少?是否有用户画像?
用户:70% 是新用户,有设备型号和地域
R1:[思维链] 冷启动占比高,不能用纯 CF...
→ 建议:双塔模型 + 内容召回,给出架构图
用户:召回流怎么做 A/B?
R1:[给出完整 A/B 设计方案]
R1 的输出特点:多轮对话中 R1 会主动反问而不是硬猜,这是它和 GPT-5 最大的差异——GPT-5 倾向于"问什么答什么",R1 倾向于"先搞清楚再答"。复杂任务协作体验极佳。
对比要点:GPT-5 多轮对话响应快、流畅;Claude 上下文窗口大(200K vs R1 的 64K);R1 的优势是推理深度和主动澄清。
实用建议:和 R1 协作复杂任务时,让它先输出"任务拆解计划"再开始执行,能显著减少返工。
如何通过 DrAI 调用 DeepSeek R1
DrAI 是一个 AI 模型聚合平台,支持 40+ 主流模型(GPT-5、Claude Opus 4、DeepSeek R1、Gemini 2.5 Pro、Qwen 3、GLM-4、Grok 等),全部走 OpenAI 兼容 API。你只需要一个 API key 就能在不同模型间切换,按量付费,无需为每个模型单独充值。
curl 调用示例:
curl https://api.dr-ai.top/v1/chat/completions \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-r1",
"messages": [
{"role": "user", "content": "证明根号 2 是无理数"}
],
"temperature": 0.6,
"max_tokens": 4096
}'
Python SDK 示例(推荐用于生产):
from openai import OpenAI
client = OpenAI(
api_key="sk-your-key",
base_url="https://api.dr-ai.top/v1"
)
resp = client.chat.completions.create(
model="deepseek-r1",
messages=[{"role": "user", "content": "用 Python 写一个 LRU 缓存"}],
temperature=0.6
)
# R1 特有:reasoning_content 字段
msg = resp.choices[0].message
print("推理过程:", msg.reasoning_content) # 思维链
print("最终答案:", msg.content)
关键参数说明:
temperature:R1 官方推荐 0.5-0.7,推理类任务用 0.6max_tokens:建议至少 4096,思维链会占大量 tokenreasoning_content:DrAI 默认返回这个字段,GPT-5/Claude 没有
DrAI 相比 UniAPI、GlobalGPT 这类平台的优势:支持信用卡支付、每日免费额度可以测模型、延迟优化做得好(亚太节点 R1 平均 6.2s,比直连官方快 30%)。
何时用 R1,何时换别的模型
用了一年多,我的结论是 R1 是性价比最高的中文推理模型,但不是万能。决策清单:
| 任务 | 首选模型 | 理由 |
|---|---|---|
| 数学/逻辑/算法题 | DeepSeek R1 | 准确率最高,价格最低 |
| 中文写作/公文 | DeepSeek R1 | 母语级流畅度 |
| Debug 复杂代码 | R1 或 GPT-5 | R1 推理链透明 |
| 快应答(<1s) | GPT-5 | R1 延迟太高 |
| 长文档(>64K) | Claude Opus 4 | 200K 上下文 |
| 创意写作 | Claude Opus 4 | 文学性最强 |
| 多模态(图片) | GPT-5 或 Gemini | R1 是纯文本 |
| 生产 API(成本敏感) | DeepSeek R1 | 价格只有 GPT-5 的 1/9 |
常见问题
Q:R1 为什么这么慢?
A:因为它真的在"思考"。一个数学题的思维链可能 2000+ token,生成需要时间。如果你不需要推理过程,用 DeepSeek V3 或 GPT-5 更快。
Q:reasoning_content 字段要不要展示给用户?
A:看场景。to-C 产品建议隐藏(用户体验差),to-B 工具类产品建议展示(增加可信度,便于 debug)。
Q:R1 支持 function calling 吗?
A:支持但不是强项。需要复杂 tool use 的场景建议用 GPT-5 或 Claude,R1 的 tool 调用准确率略低。
Q:DrAI 上的 R1 是官方版本吗?
A:是的,DrAI 走 DeepSeek 官方 API,不蒸馏不中转。可以对比官方文档的输出验证。
总结
DeepSeek R1 不是要替代 GPT-5 或 Claude,而是补上了"中文 + 推理 + 便宜"这个三角的空白。如果你做的是中文用户的产品、对成本敏感、需要可解释的推理过程,R1 基本是唯一选择。如果你要的是最快响应、最长上下文、最强创意,那 GPT-5 和 Claude 各有所长。
最务实的做法:通过 DrAI 平台一个 key 调用所有模型,根据任务类型动态路由——推理用 R1、创意用 Claude、快应答用 GPT-5。这种"模型组合"才是 2026 年做 AI 应用的正确姿势。
| 特性 | DrAI | UniAPI/GlobalGPT |
|---|---|---|
| 模型数量 | 40+ | 10-20 |
| 价格 | 按量付费 | 月费 + 超量 |
| 免费额度 | 每日免费 | 无 |
| API 兼容 | OpenAI 格式 | 部分 |
| 支付方式 | 信用卡 + 加密货币 | 仅信用卡 |
DeepSeek R1 Installation Guide
DeepSeek R1 is a powerful reasoning model that can be deployed locally for privacy-sensitive applications or accessed through cloud APIs. This guide covers both approaches with step-by-step instructions.
Local Deployment with vLLM
For production self-hosted deployment, vLLM is the recommended inference engine. It provides optimized attention mechanisms, continuous batching, and tensor parallelism for maximum throughput.
# System requirements:
# - DeepSeek R1 (671B full): 8x H100/A100 80GB GPUs
# - DeepSeek R1 Distill (70B): 2x A100 80GB or 4x RTX 4090
# - DeepSeek R1 Distill (32B): 1x A100 80GB or 2x RTX 4090
# - DeepSeek R1 Distill (7B): 1x RTX 4090 24GB
# Step 1: Install vLLM
pip install vllm>=0.6.0
# Step 2: Download model weights
huggingface-cli download deepseek-ai/DeepSeek-R1-Distill-Qwen-32B \\
--local-dir /models/deepseek-r1-32b
# Step 3: Start vLLM server (OpenAI-compatible API)
python -m vllm.entrypoints.openai.api_server \\
--model /models/deepseek-r1-32b \\
--tensor-parallel-size 1 \\
--max-model-len 32768 \\
--port 8000 \\
--trust-remote-code
# Step 4: Test the deployment
curl http://localhost:8000/v1/chat/completions \\
-H "Content-Type: application/json" \\
-d '{
"model": "/models/deepseek-r1-32b",
"messages": [{"role": "user", "content": "What is 27*45?"}]
}'
Quantization for Reduced Hardware Requirements
For deployments with limited GPU memory, quantization reduces the model footprint significantly. AWQ (Activation-aware Weight Quantization) to INT4 reduces memory requirements by 75% with minimal quality loss (typically 1-3% on benchmarks). GGUF format, compatible with llama.cpp, enables deployment on CPU-only systems for development and testing. For the 32B distilled model, INT4 quantization requires approximately 18GB VRAM, enabling deployment on consumer GPUs. Quality comparison: FP16 (baseline) → INT8 (0.5% quality loss) → INT4 (2% quality loss). The trade-off between quality and hardware requirements should be evaluated on your specific use case.
Docker Deployment
Containerized deployment simplifies scaling and management. The following Docker setup includes automatic GPU detection and health checking.
# Dockerfile
FROM vllm/vllm-openai:latest
ENV MODEL_NAME=deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
ENV TENSOR_PARALLEL_SIZE=1
ENV MAX_MODEL_LEN=32768
EXPOSE 8000
CMD ["--model", "${MODEL_NAME}", \\
"--tensor-parallel-size", "${TENSOR_PARALLEL_SIZE}", \\
"--max-model-len", "${MAX_MODEL_LEN}", \\
"--trust-remote-code"]
# docker-compose.yml
version: "3.8"
services:
deepseek-r1:
build: .
runtime: nvidia
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
ports:
- "8000:8000"
environment:
- MODEL_NAME=deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
API Usage Examples
Basic Reasoning Query
DeepSeek R1's key differentiator is its explicit reasoning capability. The model produces a chain-of-thought process before delivering the final answer. Understanding how to work with this reasoning output is essential.
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed-for-local"
)
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
messages=[
{"role": "system", "content": "You are a math expert. Show your reasoning."},
{"role": "user", "content": "A train travels 240 km in 3 hours. "
"If it increases speed by 20 km/h, "
"how long will a 400 km journey take?"}
],
temperature=0.6, # R1 recommends 0.5-0.7 for reasoning
max_tokens=4096
)
# R1 output contains reasoning and final answer
content = response.choices[0].message.content
print(content)
# The model will show step-by-step reasoning:
# 1. Current speed: 240/3 = 80 km/h
# 2. New speed: 80 + 20 = 100 km/h
# 3. New time: 400/100 = 4 hours
Using the Reasoning Content
When deployed via certain API providers, DeepSeek R1 separates its reasoning from the final answer in the response structure, allowing applications to display or hide reasoning as needed.
response = client.chat.completions.create(
model="deepseek-r1",
messages=[{"role": "user", "content": "Prove that the square root "
"of 2 is irrational."}],
)
# Some providers expose reasoning separately
message = response.choices[0].message
if hasattr(message, 'reasoning_content') and message.reasoning_content:
print("=== Reasoning Process ===")
print(message.reasoning_content)
print("\n=== Final Answer ===")
print(message.content)
Batch Processing for Cost Efficiency
import asyncio
import aiohttp
async def batch_reasoning(questions: list[str]) -> list[dict]:
"""Process multiple reasoning questions concurrently."""
async with aiohttp.ClientSession() as session:
tasks = [
single_request(session, q, idx)
for idx, q in enumerate(questions)
]
return await asyncio.gather(*tasks)
async def single_request(session, question, idx):
payload = {
"model": "deepseek-r1",
"messages": [{"role": "user", "content": question}],
"temperature": 0.6,
"max_tokens": 2048
}
async with session.post(
"http://localhost:8000/v1/chat/completions",
json=payload
) as resp:
result = await resp.json()
return {
"index": idx,
"answer": result["choices"][0]["message"]["content"],
"tokens": result["usage"]["total_tokens"]
}
Use Cases for DeepSeek R1
Mathematical Problem Solving
DeepSeek R1 excels at mathematical reasoning, achieving 96.3% on the MATH benchmark — competitive with premium models costing 100x more. It handles calculus, linear algebra, probability, and number theory problems with detailed step-by-step solutions. For educational applications, R1's visible reasoning process makes it an excellent tutor — students can follow the problem-solving methodology, not just see the final answer. For research applications, R1 can verify mathematical proofs, explore conjectures, and suggest approaches to open problems. The model's training included extensive mathematical reasoning data, giving it deep competency in this domain.
Code Generation and Debugging
R1's reasoning capability enhances code generation by planning solutions before writing code. For complex algorithms, R1 analyzes the problem, considers multiple approaches, selects the optimal strategy, and then implements it. This planning phase produces cleaner, more efficient code than direct generation. R1 scores 92.1% on HumanEval and 65.4% on the more challenging SWE-bench. For debugging, R1's chain-of-thought reasoning traces through code execution paths to identify root causes. The model is particularly effective at identifying subtle bugs in concurrent code and distributed systems, where surface-level analysis often misses race conditions and state management issues.
Scientific Research Assistance
Researchers use DeepSeek R1 for literature analysis, hypothesis generation, and experimental design. The model's ability to reason through complex scientific problems makes it valuable for synthesizing findings across multiple papers, identifying research gaps, and proposing novel research directions. R1's open-weight nature is particularly appealing for academic use — researchers can examine, fine-tune, and build upon the model without proprietary restrictions. The reasoning transparency also makes R1 suitable for peer review assistance, where understanding the analysis process is as important as the conclusions.
Performance Optimization Tips
Optimal Temperature Settings
DeepSeek R1's reasoning quality is highly sensitive to temperature settings. For mathematical and logical reasoning tasks, the optimal temperature range is 0.5-0.7. Lower temperatures (0.1-0.3) can cause repetitive reasoning loops where the model cycles through the same arguments without converging. Higher temperatures (0.8-1.0) introduce too much randomness in the reasoning chain, leading to logical errors. For creative tasks that still require reasoning (strategic planning, analytical writing), temperature 0.7 provides the best balance. Always specify temperature explicitly — the default value in some frameworks may not be optimal for reasoning models.
Context Window Optimization
R1 supports context windows up to 128K tokens, but reasoning quality degrades when context exceeds 32K tokens due to the "lost in the middle" phenomenon. For complex problems requiring extensive context, structure your prompt with the most important information at the beginning and end. Break very long problems into sub-problems and solve them sequentially, passing only the essential results between steps. This approach maintains reasoning quality while handling problems that exceed the optimal context length.
Batch Inference Optimization
When processing multiple independent queries, batch inference dramatically improves throughput. vLLM's continuous batching handles this automatically — simply send concurrent requests to the API server. For optimal throughput, maintain 10-50 concurrent requests (depending on GPU memory). Monitor GPU utilization: if utilization is below 80%, increase concurrency. If latency exceeds 10 seconds per request, reduce concurrency. KV-cache reuse provides additional speedup for requests sharing common prefixes (e.g., the same system prompt) — structure prompts to maximize prefix sharing across batched requests.