算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
du-dum【设计与创意】Separate expensive observation from cheap decision-making in autonomous agent loops using a two-clock architecture. A fast clock accumulates data into a digest file; a slow clock reads the digest and acts only when something is pending. Idle cycles cost nothing because the action clock returns immediately after reading an empty digest. Use when build…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Split watching from acting. Two clocks run at different speeds. Fast clock (look) grab data cheap and write tight digest. Slow clock (do) read digest and pick act or skip. Digest empty? Action clock quit fast -- zero cost for idle tick.
Name come from heartbeat: du-dum, du-dum. First beat (du) watch; second beat (dum) act. Most time, only first beat fire.
Split all work into watch (cheap, often) and act (costly, rare).
| Clock | Cost profile | Speed | Example |
|---|---|---|---|
| Fast (look) | Cheap: API read, file parse, no LLM | 4-6x/day | Scan GitHub notifications, parse RSS, read logs |
| Slow (act) | Costly: LLM inference, write ops | 1x/day | Compose reply, update dashboard, send alerts |
Got: Clean two-column split. Every op put in exactly one clock. Fast clock has no LLM calls; slow clock has no data grab.
If fail: Op need both read and LLM (e.g., "summarize new issues")? Split: fast clock grab raw issues into digest; slow clock summarize. Digest is boundary.
Digest is low-bandwidth message bridging two clocks. Must be tight, human-readable, machine-parse.
pending: none or empty section)Example digest shape:
# 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 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: Digest template with clear pending/empty states. Action clock can pick go/no-go by one field or section.
If fail: Digest too big (>50 lines)? Fast clock packing too much raw data. Move detail to separate data file; keep digest as summary with pointers.
Build watch scripts running on fast schedule.
# 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 watch scripts, each make or update digest file. Scripts run split -- one fails, others still update their sections.
If fail: Source down short time? Script log err and leave old digest entry alone. Do not clear digest on source fail -- stale data better than missing data for action clock.
Build act script that read digest and pick act or skip.
# 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: Act script quits under 1 sec on idle cycle (only file read and empty check). On busy cycle, handle pending items and clear digest.
If fail: LLM call fail? Do not clear digest. Pending items stay for next act cycle. Think about retry count in digest to stop infinite retry on permanently broken items.
Cost savings come from idle detect -- action clock must reliably pick "nothing to do" vs "something to do" with low cost.
# Minimal idle check
if grep -q "^(none)quot; "$DIGEST_PATH" || grep -q "pending: 0" "$DIGEST_PATH"; then
echo "$(date -u +%FT%TZ) heartbeat: idle" >> "$LOG_PATH"
exit 0
fi
Got: Idle path is one file read then string match. No net calls, no process spawning past script itself.
If fail: Idle check flaky (false hits miss work, or false miss cause bad LLM calls)? Simpler digest. One bool field (has_pending: true/false) at top is most reliable.
Tally expected cost to confirm two-clock arch delivers savings.
fast_runs = 24 / fast_interval_hoursfast_runs * cost_per_analysis_run (should be ~$0 if no LLM)active_days_fraction * cost_per_action_run(1 - active_days_fraction) * cost_per_idle_check (should be ~$0)Example cost compare:
| 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: Cost model show du-dum cheaper than old by at least 10x on idle day.
If fail: Cost model not show big savings? One likely true: (a) fast clock too fast, (b) fast clock has hidden LLM calls, or (c) system rarely idle. Du-dum helps high-idle systems. Always busy? Simpler poll may fit better.
manage-token-budget -- cost control frame that du-dum make real; du-dum is arch pattern, token budget is count layercircuit-breaker-pattern -- handle fail case (tools break); du-dum handle normal case (nothing to do). Use together: du-dum for idle detect, circuit-breaker for fail recoveryobserve -- watch method for fast clock; du-dum shape when and how watch become act via digestforage-resources -- strategy roam layer; du-dum is run rhythm forage-resources sits incoordinate-reasoning -- stigmergic signal patterns; digest file is form of stigmergy (indirect coord through env artifacts)