PeanutSplash/promptloom

GitHub: PeanutSplash/promptloom

逆向工程自 Claude Code 的提示词编译器,通过缓存边界、条件区块、工具注入和 Token 预算来编排生产级 LLM 系统提示词。

Stars: 1 | Forks: 0

# promptloom **通过缓存边界、工具注入和 Token 预算,编织生产级 LLM 提示词。** 逆向工程自 [Claude Code](https://claude.ai/code) 的 7 层提示词架构——这正是 Anthropic 内部用于为其 50 万行以上 CLI 工具组装系统提示词的相同模式。 [![npm version](https://img.shields.io/npm/v/promptloom?color=f97316)](https://www.npmjs.com/package/promptloom) [![license](https://img.shields.io/npm/l/promptloom?color=22c55e)](./LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-first-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![zero deps](https://img.shields.io/badge/dependencies-0-10b981)](./package.json) [快速开始](#quick-start) | [文档](#core-concepts) | [API 参考](#api-reference) | [LLM 文档](https://raw.githubusercontent.com/PeanutSplash/promptloom/main/llms.txt)
## 为什么 每个 LLM 应用都是将提示词拼接而成的。大多数应用使用字符串拼接来完成。而 Claude Code 使用**编译器**来实现——多区域缓存作用域、条件区块、逐工具提示词注入、延迟工具加载和 Token 预算追踪。 **promptloom** 将这些经过实战检验的模式提取为一个零依赖的库。 ### 亮点 - **多区域缓存作用域** — 每个区域都有自己的缓存作用域(`global`、`org` 或 `null`),因此更改某个部分不会破坏其他部分的缓存 - **工具注册表** — 会话级别的提示词缓存,具有稳定的排序和延迟加载功能,适用于 40 种以上的工具配置 - **条件区块** — `when` 谓词根据模型、环境或用户类型控制是否包含 - **Token 估算与预算规划** — 内置于每次 `compile()` 调用中,带有针对 Agent 循环的边际效益递减检测 - **5 个提供商格式化工具** — `toAnthropic()` / `toOpenAI()` / `toOpenAIResponses()` / `toBedrock()` / `toGemini()` 加上任何 OpenAI 兼容的提供商(Groq、Together、DeepSeek、Mistral、Fireworks...) ## 安装 ``` # npm npm install promptloom # bun bun add promptloom # pnpm pnpm add promptloom # yarn yarn add promptloom ``` ## 快速开始 ### 对于 Agent 将此内容提供给您的 AI 助手,即可开始构建: ``` curl -s https://raw.githubusercontent.com/PeanutSplash/promptloom/main/llms.txt ``` 或者直接在您的 AI 聊天中粘贴 URL: ``` https://raw.githubusercontent.com/PeanutSplash/promptloom/main/llms.txt ``` ### 对于人类 ``` import { PromptCompiler, toAnthropic } from 'promptloom' const pc = new PromptCompiler() // Zone 1: Attribution header (no cache) pc.zone(null) pc.static('attribution', 'x-billing-org: org-123') // Zone 2: Static rules (globally cacheable) pc.zone('global') pc.static('identity', 'You are a code review bot.') pc.static('rules', 'Only comment on bugs, not style.') // Zone 3: Dynamic context (session-specific) pc.zone(null) pc.dynamic('diff', async () => { const diff = await getCurrentDiff() return `Review this diff:\n${diff}` }) // Conditional section — only included for Opus models pc.static('thinking', 'Use extended thinking for complex reviews.', { when: (ctx) => ctx.model?.includes('opus') ?? false, }) // Tools (inline + deferred) pc.tool({ name: 'post_comment', prompt: 'Post a review comment on a specific line of code.', inputSchema: { type: 'object', properties: { file: { type: 'string' }, line: { type: 'number' }, body: { type: 'string' }, }, required: ['file', 'line', 'body'], }, order: 1, }) pc.tool({ name: 'web_search', prompt: 'Search the web for context.', inputSchema: { type: 'object', properties: { query: { type: 'string' } } }, deferred: true, // excluded from prompt, loaded on demand }) // Compile const result = await pc.compile({ model: 'claude-opus-4-6' }) result.blocks // CacheBlock[] — one per zone, with scope annotations result.tools // CompiledTool[] — inline tools only result.deferredTools // CompiledTool[] — deferred tools result.tokens // { systemPrompt, tools, deferredTools, total } result.text // Full prompt as a single string ``` ## 配合 API 使用
Anthropic ``` import Anthropic from '@anthropic-ai/sdk' import { PromptCompiler, toAnthropic } from 'promptloom' const pc = new PromptCompiler() // ... add zones, sections, and tools ... const result = await pc.compile({ model: 'claude-sonnet-4-6' }) const { system, tools } = toAnthropic(result) const response = await new Anthropic().messages.create({ model: 'claude-sonnet-4-6', max_tokens: 4096, system, // TextBlockParam[] with cache_control tools, // includes deferred tools with defer_loading: true messages: [{ role: 'user', content: 'Review this PR' }], }) ```
OpenAI ``` import OpenAI from 'openai' import { PromptCompiler, toOpenAI } from 'promptloom' const pc = new PromptCompiler() // ... add zones, sections, and tools ... const result = await pc.compile() const { system, tools } = toOpenAI(result) const response = await new OpenAI().chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'system', content: system }, { role: 'user', content: 'Review this PR' }, ], tools, }) ```
OpenAI Responses API ``` import OpenAI from 'openai' import { PromptCompiler, toOpenAIResponses } from 'promptloom' const pc = new PromptCompiler() // ... add zones, sections, and tools ... const result = await pc.compile() const { instructions, tools } = toOpenAIResponses(result) const response = await new OpenAI().responses.create({ model: 'gpt-4o', instructions, input: 'Review this PR', tools, }) ```
AWS Bedrock ``` import { PromptCompiler, toBedrock } from 'promptloom' const result = await pc.compile() const { system, toolConfig } = toBedrock(result) // Use with @aws-sdk/client-bedrock-runtime ConverseCommand ```
Google Gemini / Vertex AI ``` import { GoogleGenAI } from '@google/genai' import { PromptCompiler, toGemini } from 'promptloom' const pc = new PromptCompiler() // ... add zones, sections, and tools ... const result = await pc.compile() const { systemInstruction, tools } = toGemini(result) const response = await new GoogleGenAI({ apiKey: '...' }).models.generateContent({ model: 'gemini-2.5-pro', contents: [{ role: 'user', parts: [{ text: 'Review this PR' }] }], config: { systemInstruction, tools }, }) ```
OpenAI 兼容提供商 (Groq, Together, DeepSeek, Mistral, Fireworks) `toOpenAI()` 适用于任何 OpenAI 兼容 API——只需替换 `baseURL`: ``` import OpenAI from 'openai' import { PromptCompiler, toOpenAI } from 'promptloom' const result = await pc.compile() const { system, tools } = toOpenAI(result) // Groq const groq = new OpenAI({ baseURL: 'https://api.groq.com/openai/v1', apiKey: '...' }) // Together AI const together = new OpenAI({ baseURL: 'https://api.together.xyz/v1', apiKey: '...' }) // DeepSeek const deepseek = new OpenAI({ baseURL: 'https://api.deepseek.com', apiKey: '...' }) // Mistral const mistral = new OpenAI({ baseURL: 'https://api.mistral.ai/v1', apiKey: '...' }) // Fireworks AI const fireworks = new OpenAI({ baseURL: 'https://api.fireworks.ai/inference/v1', apiKey: '...' }) ```
## 核心概念 ### 区域:多区块缓存作用域 Claude Code 使用单个 `SYSTEM_PROMPT_DYNAMIC_BOUNDARY` 将提示词拆分为 2 个区块。promptloom 将其泛化为 **N 个区域**——每个区域编译成一个独立的 `CacheBlock`,并拥有自己的缓存作用域。 ``` pc.zone(null) // Zone 1: no-cache (attribution headers) pc.static('header', 'x-billing: org-123') pc.zone('global') // Zone 2: globally cacheable (identity, rules) pc.static('identity', 'You are Claude Code.') pc.static('rules', 'Follow safety protocols.') pc.zone('org') // Zone 3: org-level cacheable pc.static('org_rules', 'Company-specific guidelines.') pc.zone(null) // Zone 4: session-specific (dynamic context) pc.dynamic('git', async () => `Branch: ${await getBranch()}`) ``` 编译为 4 个 `CacheBlock`: ``` ┌─────────────────────────────┐ │ x-billing: org-123 │ Block 1 scope=null (no cache) ├─────────────────────────────┤ │ You are Claude Code. │ Block 2 scope=global (cross-org cache) │ Follow safety protocols. │ ├─────────────────────────────┤ │ Company-specific guidelines│ Block 3 scope=org (org-level cache) ├─────────────────────────────┤ │ Branch: main │ Block 4 scope=null (session-specific) └─────────────────────────────┘ ``` ### 条件区块 根据模型、环境或用户类型对部分内容进行门控: ``` // Only for Opus models pc.static('thinking_guide', 'Use extended thinking for complex tasks.', { when: (ctx) => ctx.model?.includes('opus') ?? false, }) // Only when MCP servers are connected pc.dynamic('mcp', async () => fetchMCPInstructions(), { when: (ctx) => (ctx.mcpServers as string[])?.length > 0, }) // Only for internal users pc.static('internal_tools', 'You have access to internal APIs.', { when: (ctx) => ctx.userType === 'internal', }) const result = await pc.compile({ model: 'claude-opus-4-6', mcpServers: ['figma', 'slack'], userType: 'internal', }) ``` ### 工具管理 #### 工具提示词注入 每个工具都带有自己的面向 LLM 的描述,在每个会话中解析一次并被缓存: ``` pc.tool({ name: 'Bash', prompt: async () => { const sandbox = await detectSandbox() return `Execute shell commands.\n${sandbox ? 'Running in sandbox.' : ''}` }, inputSchema: { /* ... */ }, order: 1, // explicit ordering for cache stability }) ``` #### 延迟工具 当您有许多工具时(Claude Code 有 42 个以上),大多数工具在每轮交互中并不都需要: ``` pc.tool({ name: 'web_search', prompt: 'Search the web for information.', inputSchema: { /* ... */ }, deferred: true, // not in system prompt, loaded via tool search }) const result = await pc.compile() result.tools // inline tools only result.deferredTools // deferred tools (with defer_loading: true) ``` ### Token 预算 #### 估算 每次 `compile()` 调用都包含 Token 估算: ``` const result = await pc.compile() result.tokens.systemPrompt // ~350 tokens result.tokens.tools // ~200 tokens (inline only) result.tokens.deferredTools // ~100 tokens (not counted in total) result.tokens.total // ~550 tokens (systemPrompt + tools) ``` #### Agent 循环的预算追踪 ``` import { createBudgetTracker, checkBudget } from 'promptloom' const tracker = createBudgetTracker() const decision = checkBudget(tracker, currentTokens, { budget: 100_000 }) if (decision.action === 'continue') { // Inject decision.nudgeMessage to keep the model working } else { // decision.reason: 'budget_reached' | 'diminishing_returns' } ``` #### 自然语言预算解析 ``` import { parseTokenBudget } from 'promptloom' parseTokenBudget('+500k') // 500_000 parseTokenBudget('spend 2M tokens') // 2_000_000 parseTokenBudget('+1.5b') // 1_500_000_000 parseTokenBudget('hello world') // null ``` ## API 参考 ### `PromptCompiler` | 方法 | 描述 | |--------|-------------| | `zone(scope)` | 启动一个新的缓存区域 (`'global'`、`'org'` 或 `null`) | | `boundary()` | 当 `enableGlobalCache` 为 true 时,`zone(null)` 的简写 | | `static(name, content, options?)` | 添加静态部分。`options.when` 用于条件包含 | | `dynamic(name, compute, options?)` | 添加动态部分(每次 `compile()` 时重新计算) | | `tool(def)` | 注册工具。设置 `deferred: true` 以进行按需加载,`order` 用于排序稳定性 | | `compile(context?)` | 编译所有内容 -> `CompileResult`。上下文会传递给 `when` 谓词 | | `clearCache()` | 清除所有部分 + 工具缓存 | | `clearSectionCache()` | 仅清除部分缓存 | | `clearToolCache()` | 仅清除工具缓存 | | `sectionCount` | 已注册部分的数量(不包括区域标记) | | `toolCount` | 已注册工具的数量(内联 + 延迟) | | `listSections()` | 列出各部分及其类型(`static`、`dynamic`、`zone`) | | `listTools()` | 列出已注册的工具名称 | ### `CompileResult` | 字段 | 类型 | 描述 | |-------|------|-------------| | `blocks` | `CacheBlock[]` | 每个区域对应一个区块,带有 `cacheScope` 注解 | | `tools` | `CompiledTool[]` | 带有已解析描述的内联工具 schema | | `deferredTools` | `CompiledTool[]` | 延迟工具 schema(带有 `defer_loading: true`) | | `tokens` | `TokenEstimate` | `{ systemPrompt, tools, deferredTools, total }` | | `text` | `string` | 完整提示词,作为单个拼接字符串 | ### 提供商格式化工具 | 格式化工具 | 输出 | 提供商 | |-----------|--------|-----------| | `toAnthropic(result)` | `{ system, tools }` | Anthropic (1P) | | `toOpenAI(result)` | `{ system, tools }` | OpenAI、Azure、Groq、Together、DeepSeek、Mistral、Fireworks、Cohere v2 | | `toOpenAIResponses(result)` | `{ instructions, tools }` | OpenAI Responses API | | `toBedrock(result)` | `{ system, toolConfig }` | AWS Bedrock (Claude、Llama、Mistral、Cohere — Converse API) | | `toGemini(result)` | `{ systemInstruction, tools }` | Google Gemini、Google Vertex AI | ### 独立工具 ``` import { // Token estimation estimateTokens, // Rough estimate (bytes / 4) estimateTokensForFileType, // File-type-aware (JSON = bytes / 2) // Budget createBudgetTracker, // Create a new tracker checkBudget, // Check budget -> continue or stop parseTokenBudget, // Parse "+500k" -> 500_000 // Low-level (for custom compilers) splitAtBoundary, // Split text at sentinel -> CacheBlock[] section, // Create a static Section object dynamicSection, // Create a dynamic Section object defineTool, // Create a ToolDef with fail-closed defaults SectionCache, // Section cache class ToolCache, // Tool cache class resolveSections, // Resolve sections against cache compileTool, // Compile a single tool compileTools, // Compile all tools } from 'promptloom' ``` ## 背景:Claude Code 的提示词架构 本库提取了 Claude Code 源代码(于 2026 年 3 月通过未剥离的 source maps 泄露)中的模式。核心洞察是:**Anthropic 将提示词视为编译器的输出,而不是手写的文本。** 他们的系统提示词由 7 层以上的结构组装而成: 1. **身份** — AI 是谁 2. **系统** — 工具执行上下文、钩子、压缩 3. **执行任务** — 代码风格、安全性、协作规则 4. **行动** — 风险感知执行、可逆性 5. **使用工具** — 工具偏好指导、并行执行 6. **语气与风格** — 简洁性、格式化规则 7. **动态上下文** — git 状态、CLAUDE.md 文件、用户记忆、MCP 服务器指令 第 1-6 层是**静态的**(全局可缓存)。第 7 层及以上的内容是**动态的**(特定于会话)。它们之间的边界是一个字面上的哨兵字符串,API 层使用它来标注缓存作用域。 ## 贡献 欢迎贡献!请随时开启 issue 或提交 pull request。 ``` git clone https://github.com/PeanutSplash/promptloom.git cd promptloom bun install bun test # Run tests bun run dev # Run CLI demo bunx tsc --noEmit # Type check ``` ## 许可证 [MIT](./LICENSE)
**[GitHub](https://github.com/PeanutSplash/promptloom)** | **[npm](https://www.npmjs.com/package/promptloom)** | **[LLM 文档](https://raw.githubusercontent.com/PeanutSplash/promptloom/main/llms.txt)**
标签:Anthropic, API密钥扫描, Bedrock, CIS基准, Claude, Claude Code, CVE检测, DeepSeek, DLL 劫持, DNS解析, Gemini, LLM, Mistral, MITM代理, NPM包, OpenAI, OSV-Scalibr, Together, Token估算, Token限制, Token预算, TypeScript, Unmanaged PE, 云资产清单, 内存规避, 后端开发, 多模型适配, 大语言模型, 安全插件, 工具注入, 开源项目, 提示词工程, 提示词组装, 提示词缓存, 提示词编织, 提示词编译器, 暗色界面, 条件渲染, 熵值分析, 策略决策点, 缓存边界, 逆向工程, 零依赖