Agent Skillsstagewise-io/stagewise › history-compression

history-compression

GitHub

介绍 Stagewise Agent 历史压缩流水线,涵盖边界选择、近期偏好及 SQLite 测试工具。用于调试压缩逻辑、优化上下文窗口溢出问题或评估压缩质量。

.agents/skills/history-compression/SKILL.md stagewise-io/stagewise

Trigger Scenarios

调试历史压缩功能 优化上下文窗口溢出 评估压缩质量

Install

npx skills add stagewise-io/stagewise --skill history-compression -g -y
More Options

Non-standard path

npx skills add https://github.com/stagewise-io/stagewise/tree/main/.agents/skills/history-compression -g -y

Use without installing

npx skills use stagewise-io/stagewise@history-compression

指定 Agent (Claude Code)

npx skills add stagewise-io/stagewise --skill history-compression -a claude-code -g -y

安装 repo 全部 skill

npx skills add stagewise-io/stagewise --all -g -y

预览 repo 内 skill

npx skills add stagewise-io/stagewise --list

SKILL.md

Frontmatter
{
    "name": "history-compression",
    "description": "How stagewise's agent history compression pipeline works — boundary selection, recency bias, chained compressions, and the SQLite-backed test harness for replaying real compressions in LLM playgrounds. Use when debugging, tuning, or extending history compression, when investigating context-window overflow, or when the user wants to probe compression quality against real chat histories."
}

History Compression

Stagewise summarizes long agent histories into a single briefing stored on a "boundary" message. Everything before the boundary is replaced by the briefing; everything after stays verbatim. Recency bias baked into both boundary math + LLM prompt.

Key files

All paths are repo-root-relative.

  • apps/browser/src/backend/agents/shared/base-agent/base-agent.ts — trigger + boundary logic (compressHistoryInternal, ~L1898; trigger check in handlePostStep ~L2208).
  • apps/browser/src/backend/agents/shared/base-agent/history-compression/index.ts — model cascade + generateSimpleCompressedHistory.
  • apps/browser/src/backend/agents/shared/base-agent/history-compression/prompt.tsCOMPRESSION_SYSTEM_PROMPT, COMPRESSION_TARGET_CHARS = 30_000, buildCompressionUserMessage (dynamic budget hint).
  • apps/browser/src/backend/agents/shared/base-agent/history-compression/serialization.tsconvertAgentMessagesToCompactMessageHistoryString, estimateMessageTokens.
  • scripts/experiments/extract-compression-test-data.ts — SQLite → playground-ready per-compression bundles.

Trigger

After every step → handlePostStep checks:

usedTokens > min(compactionThreshold × contextWindow, 200k)

  • compactionThreshold default 0.65; chat agent overrides to 0.5.
  • 200k hard cap (HISTORY_COMPRESSION_HARD_CAP_TOKENS) = 1M-ctx models trigger at the same absolute count as a 200k-context model running near its full window.
  • Runs via void (async, non-blocking). Guarded by _isCompressingHistory flag → no concurrent runs.
  • Silent failure — agent keeps going, context overflow later surfaces normal model error.

Boundary selection (compressHistoryInternal)

Kept-budget = min(0.2 × contextWindow, 40k tokens) (KEPT_BUDGET_FRACTION, KEPT_BUDGET_HARD_CAP_TOKENS). Preferred floor = max(5, config.minUncompressedMessages ?? 10).

Walk backward from history end:

  1. Accumulate estimateMessageTokens(msg) until next msg would bust budget → boundary there.
  2. Else stop once kept-count ≥ floor.
  3. Edge: single last msg > budget → keep just that one, warn.
  4. boundary < 1 → nothing to compress, skip.

Then: messagesToCompact = history.slice(0, boundary) → compress → write result to history[boundary].metadata.compressedHistory.

Token estimation quirks

estimateMessageTokens = ceil(chars / 4). Includes:

  • Text parts.
  • Tool-call toolName + JSON-stringified input + output.
  • Metadata overhead: env-snapshot, compressedHistory, mentions, attachments.
  • PER_MESSAGE_OVERHEAD_CHARS = 400 flat — accounts for XML wrappers/role tags the pipeline injects but aren't in parts. Without it, budget walk under-counts → compression triggers too late.

Chained compressions

When messagesToCompact already contains a prior compressedHistory:

  • Serializer (convertAgentMessagesToCompactMessageHistoryString) walks backward and stops at first compressedHistory it finds, emitting it as <previous-chat-history>...</previous-chat-history>. Older raw messages never re-serialized.
  • buildCompressionUserMessage reads prior briefing length → injects ratio-bucketed budget hint:
    • <60% target → "incorporate verbatim, do NOT shorten".
    • 60–85% → "light condensation to oldest sections".
    • ≥85% → "condense oldest fully-resolved sections".
  • Prompt mandates: keep every ## heading, shorten oldest sections only, preserve all [](path:...) links + user decisions + outcomes verbatim. Recent sections untouched.

→ Chain is bounded: each round re-absorbs prior briefing under the same 30k target.

Serialization format

Input to LLM is XML-ish:

  • <user> — text + [attached: ...], [mentioned: ...] metadata annotations.
  • <assistant> — text + one-liner tool markers: [read: path], [edited: path (N edits)], [shell: label → ✓ / exit N / timed out], [lint: paths → clean / N errors, M warnings], [asked user: title → field: answer; ...], [searched: "query"], [created: path], [wrote: path].
  • <previous-chat-history> — inlined prior briefing (see above).
  • Error state on any tool → ✗ <msg> suffix.
  • Unknown tool types → [tool-xxx] generic marker (never silently dropped).

Prompt design (apps/browser/src/backend/agents/shared/base-agent/history-compression/prompt.ts)

  • Target 30k chars soft ("goal, not ceiling — longer > losing detail").
  • 2nd-person for agent, 3rd-person for user.
  • ## headings per topic, flowing prose inside. No bullets/tables/code blocks.
  • Recency bias: old resolved = 2–4 sentences; recent/active = full detail ending with current status.
  • MUST preserve verbatim: [](path:...) links, markdown links, user decisions/preferences/constraints, color values, directory structures, config.
  • Output plain markdown. Never emit <previous-chat-history> or any XML wrapper in output.

Model cascade (apps/browser/src/backend/agents/shared/base-agent/history-compression/index.ts)

  1. gemini-3.1-flash-lite → 2. gpt-5.4-nano → 3. claude-haiku-4.5.
  • Each 30s abort timeout, temperature: 0.1, maxOutputTokens: 20000.
  • Min valid output: 30 chars (shorter → fallback).
  • Final fallback: active chat model (only if not already tried).
  • All fail → throws; caller (compressHistoryInternal) logs + reports, agent continues uncompressed.

Tuning knobs

Knob Where Default Effect
compactionThreshold config.historyCompressionThreshold 0.65 (chat: 0.5) Trigger fraction of ctx window
HISTORY_COMPRESSION_HARD_CAP_TOKENS base-agent.ts const 200_000 Absolute trigger cap
KEPT_BUDGET_FRACTION base-agent.ts const 0.2 Fraction kept uncompressed
KEPT_BUDGET_HARD_CAP_TOKENS base-agent.ts const 40_000 Absolute kept cap
minUncompressedMessages config 10 Floor on kept msg count
COMPRESSION_TARGET_CHARS prompt.ts const 30_000 Soft briefing size target
HISTORY_COMPRESSION_TIMEOUT_MS index.ts const 30_000 Per-model attempt timeout
HISTORY_COMPRESSION_MODELS index.ts const 3-model cascade Compression model order
PER_MESSAGE_OVERHEAD_CHARS serialization.ts 400 Metadata overhead fudge

Invariant: kept budget < compression trigger (else nothing ever compresses).

Test harness (scripts/experiments/extract-compression-test-data.ts)

Replays every real compression from local stagewise SQLite into playground-ready bundles.

npx tsx scripts/experiments/extract-compression-test-data.ts --channel prerelease
npx tsx scripts/experiments/extract-compression-test-data.ts --channel dev --min-messages 10

Channels map to <appData>/{stagewise | stagewise-prerelease | stagewise-dev}/stagewise/agents/instances.sqlite.

Per chat, for each boundary message (every real compression event):

  • Slices messages[0..boundary).
  • Runs real convertAgentMessagesToCompactMessageHistoryString + buildCompressionUserMessage (imported from app source → fidelity guaranteed).
  • Writes to experiments-data/history-compression/<channel>/NNN-title/compression-NNN/:
    • system-prompt.md — static prompt.
    • user-message.md — dynamic user msg with budget hint.
    • compact-history.xml — raw serialized input.
    • actual-output.md — what the real in-app LLM produced.
    • metadata.json — indices, char counts, prev-tag leak check.

→ Paste system + user into AI Studio/Claude → diff against actual-output.md. Covers full chain (1st → Nth compression) so chained-compression drift is testable.

Common tasks

  • "Why didn't compression trigger?" → check usedTokens vs trigger formula; verify compactionThreshold ≥ 0; check _isCompressingHistory not stuck.
  • "Compression is too aggressive/lossy" → bump COMPRESSION_TARGET_CHARS; lower compactionThreshold so it triggers earlier with smaller inputs.
  • "Too few kept messages after compression" → raise minUncompressedMessages or KEPT_BUDGET_FRACTION (but keep < trigger).
  • "Output leaks <previous-chat-history> tags" → check metadata.json actualOutputIncludesPreviousTag; prompt already forbids it, likely model regression → bump cascade order.
  • "Boundary drift after compression"compressHistoryInternal re-finds boundary by id after LLM round-trip (user may have undone messages mid-compression); missing id → silent skip + warn.

Version History

  • 45a1544 Current 2026-07-24 21:12

Same Skill Collection

.agents/skills/add-llm-model/SKILL.md
.agents/skills/caveman/SKILL.md
.agents/skills/create-skill/SKILL.md
.agents/skills/karton-best-practices/SKILL.md
.agents/skills/stage-ui-design-system/SKILL.md
.agents/skills/vercel-react-best-practices/SKILL.md
apps/browser/bundled/plugins/figma/SKILL.md
apps/browser/bundled/plugins/github/SKILL.md
apps/browser/bundled/plugins/javascript-sandbox/SKILL.md
apps/browser/bundled/plugins/mini-apps/SKILL.md
apps/browser/bundled/plugins/posthog/SKILL.md
apps/browser/bundled/plugins/remotion/SKILL.md
apps/browser/bundled/plugins/supabase/SKILL.md
apps/browser/bundled/plugins/vercel/SKILL.md
apps/browser/bundled/skills/debug/SKILL.md
apps/browser/bundled/skills/learn-skill/SKILL.md
apps/browser/bundled/skills/plan/SKILL.md
apps/browser/bundled/skills/preview/SKILL.md
apps/browser/bundled/skills/watch/SKILL.md
.agents/skills/copywriting/SKILL.md
.agents/skills/prompt-optimization/SKILL.md
apps/browser/bundled/skills/implement/SKILL.md

Metadata

Files
0
Version
18ac8a2
Hash
c5725ca6
Indexed
2026-07-24 21:12

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-20 12:30
浙ICP备14020137号-1 $Гость$