EP08. "Claude 进阶功能:Extended Thinking、图片、引用与 Prompt Caching"
🔒 登录后可标记已读- Extended Thinking 让 Claude 在回答前先把思考过程"写出来"给你看,但不是遇到复杂问题就该无脑打开——正确流程是先不开测一次、跑评测看准确度够不够,不够才考虑开
- 图片支持能让 Claude 描述图片内容、比较多张图、数物件数量、做复杂的视觉分析,但跟文字 prompt 一样,prompt 写得好不好直接决定分析准不准,简单一句「这张图里有什么」往往效果不好
- Citations 能让 Claude 的回答标出「这句话是从哪份文档的哪里来的」,解决用户分不清「这是 Claude 训练数据里的知识」还是「这是我提供的文档里写的」这个信任问题
- Prompt Caching 把处理过的内容(tokenize、embedding 这些前置工作)存起来,5 分钟内如果后续请求内容完全一致就直接读缓存,不用重新处理——响应更快、成本更低,但内容只要有一个字符不同,缓存就直接失效
- 前置知识:EP01 的基本 API 调用、EP04 的 tools 参数
重点内容
Extended Thinking:先测试,不够准才开
Extended thinking 是 Claude 的进阶推理能力,让它在回答复杂问题前先系统性地想一遍——Claude 会产出一段用户能看到的思考过程,让人了解模型是怎么一步步得出这个答案的。
📌 建议的决策流程:
- 先不开 extended thinking,测试你的 prompt
- 跑评测(参考 EP02 的评测 pipeline)量出准确度
- 优化过 prompt 之后准确度还是不够,才考虑打开 extended thinking
不要看到"复杂问题"就直接开——先确认真的需要。
打开前后,回应结构不一样:
- 没开 extended thinking:普通的 user 消息 → assistant 回应流程
- 开了 extended thinking:assistant 消息里会包含两个 block——一个
thinkingblock(Claude 的推理过程)+ 一个textblock(最终回答)
安全机制:加密签名:每个 thinking block 都带一个签名,防止被篡改——这能确保当你把这段 thinking 文字原样带进后续对话轮次时,内容没有被动过手脚;如果 thinking 文字被改了,签名验证就会失败。
Redacted Thinking(被遮蔽的思考):当内部安全系统标记 Claude 的思考内容有问题时,会改成返回一个 redacted block,而不是原始文字——这种 block 一样可以带进后续对话轮次,避免丢失上下文。
参数设置:
def chat(
messages,
system=None,
temperature=1.0,
stop_sequences=[],
tools=None,
thinking=False,
thinking_budget=1024
):
if thinking:
params["thinking"] = {
"type": "enabled",
"budget_tokens": thinking_budget
}
⚠️ 几个硬性要求:
thinking_budget最少要 1024 tokenmax_tokens一定要大于thinking_budget(比如thinking_budget=1024时,max_tokens至少要 1025)
📌 Extended thinking 能提高准确度,但也有代价:所有 thinking token 都要计费,回应延迟也会变长。
图片支持
Claude 能描述图片内容、比较多张图片、数物件数量、做更复杂的视觉分析任务。
技术限制:
| 限制项 | 数值 |
|---|---|
| 单次请求最多图片数 | 100 张 |
| 单张图片文件大小上限 | 5MB |
| 单张图片时最大尺寸 | 8000px |
| 多张图片时每张最大尺寸 | 2000px |
| Token 计算方式 | (宽 × 高) / 750 |
图片以 base64 编码的 block 形式,跟文字一起放进消息:
with open("image.png", "rb") as f:
image_bytes = base64.standard_b64encode(
f.read()
).decode("utf-8")
add_user_message(messages, [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image_bytes,
}
},
{
"type": "text",
"text": "What do you see in this image?"
}
])
📌 图片再清楚,prompt 写不好一样分析不准——好的 prompt 技巧在这里跟文字任务一样重要,简单一句「这张图里有什么」经常得到很表面的结果。建议用系统化的方法引导 Claude:一步步分析、给一个 one-shot 范例、或用详细的分析框架,而不是只丢一句笼统的问题。
Citations:标出回答是从哪来的
Citations 功能让 Claude 的回答标出「具体引用了提供文档里的哪部分」,解决的核心信任问题是:没有 citations 时,用户没办法分辨这段回答是 Claude 训练数据里的知识,还是真的来自你提供的文档。
启用方式:在 document 消息里加两个字段——title 和 citations:
{
"type": "document",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": file_bytes,
},
"title": "earth.pdf",
"citations": { "enabled": True }
}
title 给这份文档命名,方便引用时标注来源;citations.enabled: True 让 Claude 主动追踪信息来源。
返回的引用结构包含:
| 字段 | 内容 |
|---|---|
cited_text | 被引用的原文文字 |
document_index | 引用的是第几份文档(多文档场景) |
document_title | 文档的命名 |
start_page_number / end_page_number | 引用内容所在的页码范围 |
📌 纯文本文档也支持 citations,用的是 CitationCharLocation 对象,给出的是「字符位置」而不是页码。
适用场景:处理敏感文档、需要让用户自行核实信息、想靠来源透明来建立应用的可信度。
Prompt Caching:省重复处理的钱和时间
没有缓存时:Claude 每次处理输入都要重新走一遍分词、生成 token embedding、加上下文这些前置工作,这些计算结果用完就丢——多轮对话里,Claude 得反复重新处理「已经分析过一次」的历史消息,即使内容完全一样。
有了缓存:Claude 不再把这些前置工作丢掉,而是存进缓存;后续请求如果内容完全相同,直接读缓存结果,不用重新处理。
📌 好处是响应更快、成本更低;限制是缓存只保留 5 分钟,而且要求内容完全一致才有用——最适合用在多轮对话应用、或用户在短时间内反复引用同一份文档的场景。
Prompt Caching 的规则
缓存断点(Cache Breakpoint)要手动加,而且必须用「完整长格式」(不能用简写):
user_message = {
"role": "user",
"content": [
{
"type": "text",
"text": "",
"cache_control": {
"type": "ephemeral"
}
}
]
}
断点前面完成的处理工作会被缓存,后续内容完全一致的请求就能重用这份缓存。
断点可以加在:消息里的文字 block、system prompt、tool 定义。📌 System prompt 和 tool 定义是最常用来加断点的地方,因为它们通常每次请求都不太会变。
处理顺序和数量限制:请求会照 tools → system prompt → messages 这个固定顺序处理,最多能加 4 个缓存断点。断点位置会影响缓存范围——比如断点加在最后一个 tool 上,只会缓存到这个 tool 为止,不包含后面的 system prompt 和 messages。
⚠️ 内容长度门槛:要缓存的内容(所有被缓存 block 加总)至少要有 1024 token,太短的文字达不到这个门槛,缓存不起作用。
实操示例:给 Tool Schema 和 System Prompt 加缓存
请求处理顺序固定是 tool schemas → system prompt → message history,缓存断点也按这个顺序设置。
⚠️ 只要缓存内容有一个字符不一样,缓存就直接失效——这条规则很严格,改动 system prompt 里的任何一个字都会让缓存作废。
给 Tool Schema 加缓存:不直接改原始定义,而是复制一份 tools 列表和最后一个 tool,只在复制出来的最后一个 tool 上加 cache_control:
# 复制 tools 列表和最后一个 tool,只在复制品上加 cache_control: {"type": "ephemeral"}
# 再把改好的复制品赋值回去
给 System Prompt 加缓存:把 system 参数结构改成一个包含文字 block 的列表,在这个 block 上加 cache_control:
"system": [{"type": "text", "text": system, "cache_control": {"type": "ephemeral"}}]
监控缓存表现:第一次请求的回应里会看到 cache_creation_input_tokens(正在建立缓存);后续内容一致的请求会改成看到 cache_read_input_tokens(正在读取缓存),可以用这两个字段确认缓存有没有真的命中。
💡 越稳定不变的内容(tool schema、system prompt)越适合缓存;频繁变动的内容缓存意义不大,命中率低,反而多一道管理成本。
常见错误
- ❌ 一遇到复杂任务就直接打开 extended thinking——正确顺序是先测不开的效果、跑评测,准确度真的不够才开,否则平白多花 token 和延迟
- ❌
thinking_budget设置低于 1024,或max_tokens没有大于thinking_budget——这两条都是硬性要求,不满足会出错 - ❌ 传大图片时用「多图片」的 2000px 上限标准去检查单图——单张图片和多张图片的最大尺寸限制不一样
- ❌ 图片分析只丢一句笼统的提问(比如「这张图里有什么」)——图片任务一样需要好的 prompt 技巧,简单问法效果通常不好
- ❌ 加缓存断点时用简写格式,而不是完整长格式(
{"type": "text", "text": ..., "cache_control": {...}})——简写格式加不了cache_control - ❌ 要缓存的内容太短(低于 1024 token)——门槛不到,缓存不会生效
Sources
官方文档:
- Claude with Google Cloud's Vertex AI(Claude Academy 课程)— https://academy.claude.com/courses/claude-with-google-cloud-s-vertex-ai