du-dum
정보
du-dum 스킬은 자율 에이전트에서 지속적이고 저렴한 관찰과 가끔 발생하는 고비용 의사 결정을 분리하기 위해 이중 클록 아키텍처를 구현합니다. 이는 빠른 클록으로 데이터를 요약 정보로 누적하고, 대기 중인 작업이 발견될 때만 LLM 호출과 같은 고비용 작업을 트리거하는 느린 클록을 사용합니다. 이 패턴은 API 비용이 주요 지출이며 대부분의 관찰 주기에서 조치가 필요하지 않은 비용에 민감한 에이전트에 이상적입니다.
빠른 설치
Claude Code
추천npx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/du-dumClaude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요
문서
Du-Dum: Batch-Then-Act Pattern
Separate observation from action using two clocks running at different frequencies. The fast clock (analysis) collects data cheaply and writes a compact digest. The slow clock (action) reads the digest and decides whether to act. If the digest says nothing pending, the action clock exits immediately -- zero cost for idle cycles.
The name comes from the heartbeat rhythm: du-dum, du-dum. The first beat (du) observes; the second beat (dum) acts. Most of the time, only the first beat fires.
When to Use
- Building autonomous agents that run on a budget and must observe more often than they act
- An existing heartbeat loop calls the LLM every tick, even when nothing has changed
- Observation is cheap (API reads, file parsing, log scanning) but action is expensive (LLM calls, write operations, notifications)
- You need decoupled failure: if observation fails, the last good digest should still be valid for the action clock
- Designing cron-based agent architectures where analysis and action run as separate jobs
Inputs
- Required: List of data sources the fast clock should observe (APIs, files, logs, feeds)
- Required: Action the slow clock should take when the digest indicates pending work
- Optional: Fast clock interval (default: every 4 hours)
- Optional: Slow clock interval (default: once per day)
- Optional: Cost ceiling per day (to validate the clock configuration)
- Optional: Digest format preference (markdown, JSON, YAML)
Procedure
Step 1: Identify the Two Clocks
Separate all work into observation (cheap, frequent) and action (expensive, rare).
- List every operation in the current loop or planned workflow
- Classify each as observation (reads data, produces summary) or action (calls LLM, writes output, sends messages)
- Verify the split: observations should have zero or near-zero marginal cost; actions should be the expensive operations
- Assign frequencies: the fast clock runs often enough to catch events; the slow clock runs often enough to meet response-time requirements
| Clock | Cost profile | Frequency | Example |
|---|---|---|---|
| Fast (analysis) | Cheap: API reads, file parsing, no LLM | 4-6x/day | Scan GitHub notifications, parse RSS, read logs |
| Slow (action) | Expensive: LLM inference, write operations | 1x/day | Compose response, update dashboard, send alerts |
Got: A clear two-column split where every operation is assigned to exactly one clock. The fast clock has no LLM calls; the slow clock has no data gathering.
If fail: If an operation needs both reading and LLM inference (e.g., "summarize new issues"), split it: the fast clock collects the raw issues into the digest; the slow clock summarizes them. The digest is the boundary.
Step 2: Design the Digest Format
The digest is the low-bandwidth message that bridges the two clocks. It must be compact, human-readable, and machine-parseable.
- Define the digest file path and format (markdown recommended for human debugging)
- Include a header with timestamp and source metadata
- Define a "pending" section listing items that require action
- Define a "status" section with current state (for dashboards or logging)
- Include a clear empty-state indicator (e.g.,
pending: noneor empty section)
Example digest structure:
# Digest — 2026-03-22T06:30:00Z
## Pending
- PR #42 needs review response (opened 2h ago, author requested feedback)
- Issue #99 has new comment from maintainer (action: reply)
## Status
- Last analyzed: 2026-03-22T06:30:00Z
- Sources checked: github-notifications, rss-feed, error-log
- Items scanned: 14
- Items pending: 2
When nothing is pending:
# Digest — 2026-03-22T06:30:00Z
## Pending
(none)
## Status
- Last analyzed: 2026-03-22T06:30:00Z
- Sources checked: github-notifications, rss-feed, error-log
- Items scanned: 8
- Items pending: 0
Got: A digest template with clear pending/empty states. The action clock can determine whether to proceed by checking a single field or section.
If fail: If the digest grows too large (>50 lines), the fast clock is including too much raw data. Move details to a separate data file and keep the digest as a summary with pointers.
Step 3: Implement the Fast Clock (Analysis)
Build the observation scripts that run on the fast schedule.
- Create one script per data source (keeps failures independent)
- Each script reads its source, extracts relevant events, and appends to or rewrites the digest
- Use file locking or atomic writes to prevent partial digests
- Log the analysis run (timestamp, items found, errors) to a separate log file
- Never call the LLM or perform write operations beyond updating the digest
# Pseudocode: analyze-notifications.sh
fetch_notifications()
filter_actionable(notifications)
format_as_digest_entries(filtered)
atomic_write(digest_path, entries)
log("analyzed {count} notifications, {pending} actionable")
Schedule example (cron):
# Fast clock: analyze every 4 hours
30 */4 * * * /path/to/analyze-notifications.sh >> /var/log/analysis.log 2>&1
0 6 * * * /path/to/analyze-pr-status.sh >> /var/log/analysis.log 2>&1
Got: One or more analysis scripts, each producing or updating the digest file. Scripts run independently -- if one fails, the others still update their sections.
If fail: If a data source is temporarily unavailable, the script should log the error and leave the previous digest entries intact. Do not clear the digest on source failure -- stale data is better than missing data for the action clock.
Step 4: Implement the Slow Clock (Action)
Build the action script that reads the digest and decides whether to act.
- Read the digest file (Step 0 of every action cycle)
- Check the pending section: if empty or "none", exit immediately with a log entry
- If items are pending, invoke the expensive operation (LLM call, message composition, etc.)
- After acting, clear or archive the processed digest entries
- Log the action run (items processed, cost, duration)
# Pseudocode: heartbeat.sh (the slow clock)
digest = read_file(digest_path)
if digest.pending is empty:
log("heartbeat: nothing pending, exiting")
exit(0)
# Only reaches here if work exists
response = call_llm(digest.pending, system_prompt)
execute_actions(response)
archive_digest(digest_path)
log("heartbeat: processed {count} items, cost: {tokens} tokens")
Schedule example (cron):
# Slow clock: act once per day at 7am
0 7 * * * /path/to/heartbeat.sh >> /var/log/heartbeat.log 2>&1
Got: The action script exits in under 1 second on idle cycles (just a file read and empty check). On active cycles, it processes pending items and clears the digest.
If fail: If the LLM call fails, do not clear the digest. The pending items remain for the next action cycle. Consider implementing a retry counter in the digest to avoid infinite retries on permanently failing items.
Step 5: Configure Idle Detection
The cost savings come from idle detection -- the action clock must reliably distinguish "nothing to do" from "something to do" with minimal overhead.
- Define the idle check as a single, fast operation (file read + string check)
- Verify the idle path has zero external calls (no API, no LLM, no network)
- Measure the idle path duration -- it should be under 1 second
- Log idle cycles differently from active cycles for monitoring
# Minimal idle check
if grep -q "^(none)$" "$DIGEST_PATH" || grep -q "pending: 0" "$DIGEST_PATH"; then
echo "$(date -u +%FT%TZ) heartbeat: idle" >> "$LOG_PATH"
exit 0
fi
Got: The idle path is a single file read followed by a string match. No network calls, no process spawning beyond the script itself.
If fail: If the idle check is unreliable (false positives causing missed work, or false negatives causing unnecessary LLM calls), simplify the digest format. A single boolean field (has_pending: true/false) at the top of the file is the most reliable approach.
Step 6: Validate the Cost Model
Calculate the expected cost to confirm the two-clock architecture delivers savings.
- Count fast clock runs per day:
fast_runs = 24 / fast_interval_hours - Count slow clock runs per day: typically 1
- Calculate observation cost:
fast_runs * cost_per_analysis_run(should be ~$0 if no LLM) - Calculate action cost:
active_days_fraction * cost_per_action_run - Calculate idle cost:
(1 - active_days_fraction) * cost_per_idle_check(should be ~$0) - Compare with the original single-loop cost
Example cost comparison:
| Architecture | Daily cost (active) | Daily cost (idle) | Monthly cost (80% idle) |
|---|---|---|---|
| Single loop (LLM every 30min) | $13.74/37h | $13.74/37h | ~$400 |
| Du-dum (6 analyses + 1 action) | $0.30 | $0.00 | ~$6 |
Got: A cost model showing the du-dum architecture is cheaper than the original by at least 10x on idle days.
If fail: If the cost model does not show significant savings, one of these is likely true: (a) the fast clock is too frequent, (b) the fast clock includes hidden LLM calls, or (c) the system is rarely idle. Du-dum benefits systems with high idle ratios. If the system is always active, a simpler polling approach may be more appropriate.
Validation
- Fast and slow clocks are cleanly separated with no LLM calls in the fast path
- Digest format has a clear empty-state indicator
- Idle detection exits in under 1 second with zero external calls
- Fast clock failure does not corrupt the digest (stale data preserved)
- Slow clock failure does not clear pending items (retry on next cycle)
- Cost model shows at least 10x savings on idle days vs. single-loop architecture
- Both clocks log their runs for monitoring and debugging
- Digest does not grow unbounded (old entries archived or cleared after processing)
Pitfalls
- Digest growing unbounded: If the fast clock appends but the slow clock never clears, the digest becomes a growing log. Always clear or archive processed entries after the action cycle completes.
- Fast clock too fast: Running analysis every 5 minutes when events arrive daily wastes API quota and disk I/O. Match the fast clock frequency to the actual event rate of your data sources.
- Slow clock too slow: If the action window is once per day but events need same-hour response, the slow clock is too slow. Increase its frequency or add an urgent-event shortcut that triggers immediate action.
- LLM calls in the fast clock: The entire cost model breaks if the fast clock includes LLM inference. Audit every fast-clock script to confirm zero LLM calls. If summarization is needed, defer it to the slow clock.
- Coupling fast clock scripts: If one analysis script depends on another's output, a failure in the first cascades. Keep fast-clock scripts independent -- each reads its own source and writes its own digest section.
- Silent idle logging: If idle cycles produce no log output, you cannot distinguish "running and idle" from "crashed and not running." Always log idle cycles, even if just a timestamp.
- Clearing digest on analysis failure: If a data source is down, do not write an empty digest. The slow clock would see "nothing pending" and skip work that is actually pending. Preserve the last good digest on failure.
Related Skills
manage-token-budget-- cost control framework that du-dum makes practical; du-dum is the architectural pattern, token budget is the accounting layercircuit-breaker-pattern-- handles the failure case (tools breaking); du-dum handles the normal case (nothing to do). Use together: du-dum for idle detection, circuit-breaker for failure recoveryobserve-- observation methodology for the fast clock; du-dum structures when and how observations become actionable via the digestforage-resources-- strategic exploration layer; du-dum is the execution rhythm that forage-resources operates withincoordinate-reasoning-- stigmergic signaling patterns; the digest file is a form of stigmergy (indirect coordination through environmental artifacts)
GitHub 저장소
연관 스킬
content-collections
메타이 스킬은 콘텐츠 콜렉션(Content Collections)을 위한 프로덕션 검증된 설정을 제공합니다. 콘텐츠 콜렉션은 Markdown/MDX 파일을 Zod 검증이 포함된 타입 안전한 데이터 콜렉션으로 변환해주는 TypeScript 최우선 도구입니다. 블로그, 문서 사이트 또는 콘텐츠 중심의 Vite + React 애플리케이션을 구축할 때 타입 안전성과 자동 콘텐츠 검증을 보장하기 위해 사용하세요. Vite 플러그인 구성과 MDX 컴파일부터 배포 최적화 및 스키마 검증에 이르기까지 모든 것을 다룹니다.
polymarket
메타이 스킬은 개발자들이 Polymarket 예측 시장 플랫폼을 활용한 애플리케이션을 구축할 수 있도록 지원하며, 거래 및 시장 데이터를 위한 API 통합 기능을 포함합니다. 또한 WebSocket을 통한 실시간 데이터 스트리밍을 제공하여 실시간 거래와 시장 활동을 모니터링할 수 있습니다. 이를 통해 거래 전략을 구현하거나 실시간 시장 업데이트를 처리하는 도구를 생성하는 데 활용할 수 있습니다.
creating-opencode-plugins
메타이 스킬은 개발자들이 명령어, 파일, LSP 작업 등 25개 이상의 이벤트 유형에 연결되는 OpenCode 플러그인을 만들 수 있도록 돕습니다. JavaScript/TypeScript 모듈을 위한 플러그인 구조, 이벤트 API 명세, 구현 패턴을 제공합니다. OpenCode AI 어시스턴트의 라이프사이클을 사용자 정의 이벤트 기반 로직으로 가로채거나, 모니터링하거나, 확장해야 할 때 사용하세요.
sglang
메타SGLang은 RadixAttention 프리픽스 캐싱을 활용하여 JSON, 정규식, 에이전트 워크플로우를 위한 고속 구조화 생성에 특화된 고성능 LLM 서빙 프레임워크입니다. 특히 반복되는 프리픽스가 있는 작업에서 상당히 빠른 추론 속도를 제공하여 복잡한 구조화 출력 및 다중 턴 대화에 이상적입니다. 제약 디코딩이 필요하거나 광범위한 프리픽스 공유가 있는 애플리케이션을 구축할 때는 vLLM과 같은 대안보다 SGLang을 선택하십시오.
