背景
在使用OpenRouter調用Anthropic Claude大模型時,部分模型支持上下文緩存功能。當緩存命中時,調用成本會顯著降低。雖然像DeepSeek這類模型自帶上下文緩存機制,但本文主要針對構建Agent場景下,需要多次調用Anthropic Claude時的緩存設置策略。
緩存機制的價值
根據官方定價策略:
- 緩存設置:需要支付額外費用
- 緩存命中:可大幅降低調用成本
- 成本效益:在大量調用場景下,緩存命中能帶來顯著的成本節約
提示:可以通過OpenRouter賬單中的調用歷史費用來驗證是否成功命中緩存。
官方緩存設置方法
根據官方文檔的說明:
標準的緩存設置通過在消息中添加以下結構實現:
{"cache_control": {"type": "ephemeral"}
}
緩存機制原理:這是一個前綴緩存機制,即設置緩存的消息之前的所有消息都會被緩存。
現有問題與限制
經過實際測試發現:
? 有效場景:在role
為user
的消息中設置緩存控制有效
? 無效場景:在role
為tool
的消息中設置緩存控制無效(盡管Claude官方API支持)
注意:這個問題在OpenRouter社區中已有反饋,但目前尚未得到修復。
解決方案
針對工具調用后無法在tool消息中設置緩存的問題,我們采用添加用戶消息的方式來繞過限制。
原始消息結構
[{"role": "system","content": [ {"type": "text", "text": "..."} ]},{"role": "user","content": [{ "type": "text", "text": "...", "cache_control": {"type": "ephemeral"} }]},{"role": "assistant","content": [ {"type": "text", "text": "..."} ],"tool_calls": []},{"role": "tool", "tool_call_id": "...", "name": "...", "content": "..."}, // 這里無法添加cache_control{"role": "assistant","content": [ {"type": "text", "text": "..."} ],"tool_calls": []}
]
優化后的消息結構
[{"role": "system","content": [ {"type": "text", "text": "..."} ]},{"role": "user","content": [{ "type": "text", "text": "..."}]},{"role": "assistant","content": [ {"type": "text", "text": "..."} ],"tool_calls": []},{"role": "tool", "tool_call_id": "...", "name": "...", "content": "..."},{"role": "user","content": [{ "type": "text", "text": "function called", "cache_control": {"type": "ephemeral"} }]}, // 新增用戶消息來設置緩存{"role": "assistant","content": [ {"type": "text", "text": "..."} ],"tool_calls": []}
]
關鍵改進:
- 在工具調用后添加一個用戶消息
- 消息內容使用"function called"等簡單提示,避免改變對話語義
- 在此消息中設置緩存控制
重要注意事項
- 緩存設置上限:Claude的
cache_control
結構設置是有數量限制的 - 最佳實踐:只需在最后一個用戶消息中設置緩存即可,前面的消息會自動被緩存
- 成本優化:在高頻調用場景下,合理使用緩存能顯著降低API調用成本
總結
通過在工具調用后添加用戶消息的方式,我們成功繞過了OpenRouter在tool消息中無法設置緩存的限制。這種方法在保持對話語義完整性的同時,實現了有效的緩存管理,為Agent應用的成本控制提供了實用的解決方案。