Latch 模式 — reference/15 问题: Anthropic API 支持 prompt caching, 如果系统提示词的前缀不变,可以省大量 token 费用。 但系统提示词中有动态内容(日期、git status 等), 每次请求都可能变化,导致缓存失效。 解决方案: Latch 模式 1. 把系统提示词分成"静态"和"动态"两部分 2. 静态部分放在前面,用 DYNAMIC_BOUNDARY 分隔 3. API 客户端在 DYNAMIC_BOUNDARY 处插入 cache_control 4.
()
| 826 | # 这是一个非常精妙的工程技巧。 |
| 827 | |
| 828 | def demonstrate_latch_pattern(): |
| 829 | """Latch 模式 — reference/15 |
| 830 | |
| 831 | 问题: Anthropic API 支持 prompt caching, |
| 832 | 如果系统提示词的前缀不变,可以省大量 token 费用。 |
| 833 | 但系统提示词中有动态内容(日期、git status 等), |
| 834 | 每次请求都可能变化,导致缓存失效。 |
| 835 | |
| 836 | 解决方案: Latch 模式 |
| 837 | 1. 把系统提示词分成"静态"和"动态"两部分 |
| 838 | 2. 静态部分放在前面,用 DYNAMIC_BOUNDARY 分隔 |
| 839 | 3. API 客户端在 DYNAMIC_BOUNDARY 处插入 cache_control |
| 840 | 4. 这样静态部分可以被缓存,动态部分每次重新计算 |
| 841 | |
| 842 | 更巧妙的是: 一旦某个 section 的值被"锁定"(latch), |
| 843 | 即使底层数据变了,这次会话内也不再更新。 |
| 844 | 这防止了会话中途 git status 变化导致缓存失效。 |
| 845 | """ |
| 846 | print("\n=== Latch 模式(缓存稳定性)===") |
| 847 | |
| 848 | # 模拟两次构建 |
| 849 | builder = SystemPromptBuilder() |
| 850 | ctx1 = ProjectContext( |
| 851 | cwd=Path("/project"), |
| 852 | current_date="2026-04-02", |
| 853 | git_status="## main\nM src/main.rs", |
| 854 | ) |
| 855 | sections1 = builder.with_os("darwin", "25.2").with_project_context(ctx1).build() |
| 856 | |
| 857 | # 找到 boundary 的位置 |
| 858 | boundary_idx = None |
| 859 | for i, s in enumerate(sections1): |
| 860 | if s == SYSTEM_PROMPT_DYNAMIC_BOUNDARY: |
| 861 | boundary_idx = i |
| 862 | break |
| 863 | |
| 864 | print(f"总共 {len(sections1)} 个 sections") |
| 865 | print(f"DYNAMIC_BOUNDARY 在索引 {boundary_idx}") |
| 866 | print(f" 静态部分: sections[0:{boundary_idx}] — 可缓存") |
| 867 | print(f" 动态部分: sections[{boundary_idx+1}:] — 每次可能变") |
| 868 | |
| 869 | # 展示缓存效果 |
| 870 | static_size = sum(len(s) for s in sections1[:boundary_idx]) |
| 871 | dynamic_size = sum(len(s) for s in sections1[boundary_idx+1:]) |
| 872 | print(f"\n 静态部分大小: ~{static_size} 字符 ≈ {static_size//4} tokens(缓存命中)") |
| 873 | print(f" 动态部分大小: ~{dynamic_size} 字符 ≈ {dynamic_size//4} tokens(每次计算)") |
| 874 | print(f" 缓存节省: {static_size / (static_size + dynamic_size) * 100:.0f}% 的系统提示词被缓存") |
| 875 | |
| 876 | |
| 877 | # ============================================================ |
no test coverage detected