diff --git a/content/posts-en/agensh.md b/content/posts-en/agensh.md new file mode 100644 index 0000000..5f38c26 --- /dev/null +++ b/content/posts-en/agensh.md @@ -0,0 +1,53 @@ +--- +title: "Agensh: Scaling Organizational Intelligence to 1,024 Agents" +pubDate: 2026-11-01 +category: tech +tags: [Paper Notes, AI Collaboration] +locked: true +--- + +Multi-agent systems compress the latency of complex tasks through concurrency, but mainstream frameworks share one ceiling: the central orchestrator. Task allocation, progress aggregation, and result adjudication all squeeze through a single context — the bigger the scale, the sooner the orchestrator dies. In October 2026, Microsoft Research open-sourced [Agensh](https://github.com/microsoft/Agensh) — a self-organized multi-agent harness **with no central orchestrator**, and the paper [*Scaling Organizational Intelligence to 1,024 Agents*](https://arxiv.org/abs/2609.26781) pushed it to a thousand and twenty-four agents. + +Its answer is disarmingly simple: instead of building a smarter scheduling brain, hand the agents the coordination infrastructure of a human organization, as is. + +## 1. Three pillars: an organization's coordination infrastructure + +![From central orchestration to self-organization](../posts/assets/agensh/pillars.svg) + +Agensh provides exactly three pieces of infrastructure; everything else self-organizes: + +- **Shared workspace**: a git platform carries the organization's in-progress and integrated work — branches, PRs, and merge conflicts, twenty years of human machinery reused as-is; +- **Message interface**: a team channel plus direct messages with priority delivery — organization-wide broadcasts and urgent collision resolution each take their own lane; +- **Shared context**: a typed-entry board holding the organization's findings and work intentions. + +The open-source reference implementation runs Gitea for the workspace and Mattermost for channel and DMs — a fully self-hosted "office" with no proprietary services. No orchestrator assigns tasks: workers find work themselves in the workspace and the context board, claim it, verify it, and merge it. The natural bottleneck of scaling — that ever-busier hub — simply does not exist. + +## 2. The cooperation loop: every worker runs their own lap + +![The multi-agent cooperation loop](../posts/assets/agensh/loop.svg) + +Every worker concurrently and asynchronously runs the same loop: **gather context → claim a sub-task → take action → verify → merge progress**. Gathering context means reading the shared workspace and the board's accumulated knowledge; claiming is a CLAIM declaration, with collisions resolved over direct messages; verification is running the tests yourself — evidence talks; merging goes through PRs. + +The most interesting design is the **economy** of the shared context: entries are deliberately tiny (about 100 characters, 300 for PATCH_SUMMARY), with the long version in a `detail` field fetched on demand; `board_read` serves only the latest 2,000 entries, and anything older is reachable only through boolean search (`,` = OR, `&` = AND) — recent memory stays small, the long tail is searched. The paper calls **FAIL the highest-value entry**: one documented falsified path stops the whole team from re-burning budget on the same dead end. New entries are pushed to peers as higher-priority updates at their next tool-call boundary. + +This shared context is not Agensh's invention — §2.3 of the paper states plainly that "the shared context follows the core idea of DeLM". [DeLM](https://github.com/yuzhenmao/DeLM) ([arXiv:2606.10662](https://arxiv.org/abs/2606.10662)) ran decentralized multi-agent coordination through a shared context and task queue: its board is an append-only event log (items, claims, completions, FACT/FAIL notes, status) with bodies stored in a separate database beside the log, hard limits (≤40 files, ≤400 KB total), and a blocking `read --wait` that wakes when a peer posts. On a 10-task Terminal-Bench 4.0 subset, two agents coordinating through the shared context averaged +12.5 percentage points accuracy and a 1.78× speedup. Agensh scaled that thread to a thousand agents. + +## 3. The numbers: does scaling actually help? + +![Scaling gains](../posts/assets/agensh/scale.svg) + +Two datasets answer "do more agents actually move the needle": on the five hardest ProgramBench tasks, 1 → 128 agents raised the pass rate from 19.31% to 28.78% (~49% relative); on building pandoc from scratch (6-hour budget, no Internet), 1 → 1,024 agents raised it from 33.89% to 55.06%. For problems where raw compute has hit diminishing returns, **the marginal return of organization is still there**. + +Engineering readiness arrived too: v1.0 shipped on 2026-10-23, and v1.0.1 six days later supports Copilot, Codex, Claude Code, and Pi as the underlying single-agent harness — use whatever mainline model you like underneath. The open-source release is a single-node harness, and the v1.0 package ships with a reproduction guide, the paper, and a demo — from paper to runnable repository with no "coming soon" in between. + +## 4. From paper to desktop: the story of one issue + +For us this paper was never just on paper. After digesting it, on 2026-10-23 I filed [issue #13](https://github.com/cgarrot/pi-mesh/issues/13) on the pi-mesh repository: pi-mesh already had the message interface (`mesh_send`, rooms, priorities) and the shared workspace (git + `mesh_reserve`), but lacked the third pillar, shared context — proposing `board_write / board_read / board_grep` in exactly the Agensh/DeLM shape. + +The maintainer cgarrot's reply is the most instructive part of the story: the direction was right, but **the hash-only ledger makes pi-mesh structurally incapable of being that board** — embedding persistence in the broker would turn a router into a database. The right shape was a separate package: join the room as a normal peer, own your storage, and let the mesh keep routing. Thus [pi-board](https://github.com/wait4xx/pi-board): v0.1 landed within a day — 55 tests, zero failures, a nine-step smoke run on a real broker — and when the issue finally closed, the official pointer landed on it. The memory layer of the [four-piece toolkit](/en/archives/pi-mesh-stack/) introduced in the previous post grew straight out of this paper. + +## 5. Closing + +Agensh's insight is not the number "1024" but its decomposition of organizational intelligence: workspace, messages, shared context — three pillars holding up self-organization, none of which needs a smarter brain. The decomposition holds at thousand-agent scale, holds for a local four-piece toolkit, and holds for a one-person shop with a few agent terminals. Scale changes; the pillars stay. + +Related reading: [Spec Harness in Depth](/en/archives/spec-harness/) · [The pi-mesh Tool Family](/en/archives/pi-mesh-stack/) diff --git a/content/posts-en/pi-mesh-stack.md b/content/posts-en/pi-mesh-stack.md new file mode 100644 index 0000000..fbc3626 --- /dev/null +++ b/content/posts-en/pi-mesh-stack.md @@ -0,0 +1,63 @@ +--- +title: "The pi-mesh Tool Family: A Four-Piece Toolkit for Local Multi-Agent Coordination" +pubDate: 2026-11-01 +category: tech +tags: [Engineering, AI Collaboration] +locked: true +--- + +[pi](https://github.com/earendil-works/pi) is the coding-agent harness we use daily. With a single terminal it is a quiet assistant; with three or four terminals open at once, each running an agent over the same repository, questions pile up: who is online? Who is editing which file? Was that message actually seen? Who has the right to stop the build running at midnight? + +A family of small tools grew around [pi-mesh](https://github.com/cgarrot/pi-mesh) to turn that coordination layer into infrastructure. Each owns one concern, and they interlock: + +![The pi-mesh tool family](../posts/assets/pi-mesh-stack/stack.svg) + +## 1. pi-mesh: the communication backbone + +pi-mesh is a local bus: a broker detached from any session (NDJSON frames over a unix socket), each pi terminal a peer with an alias, organized into rooms. Messages arrive in under 50 ms; zero runtime dependencies, Node ≥ 20. + +Its most admirable trait is the **honest status model**: `delivered` (written to the recipient's socket) ≠ `read` (injected into the recipient's session) ≠ `answered` (an explicit reply came back) — three states never conflated, none of them meaning "done". The companion **durable ledger is hash-only**: message bodies are never persisted; after a restart you can audit who sent what to whom and when, but never read the content. This self-restraint later became the family's design axiom: **the mesh stays a router, never a database.** + +Three coordination needs live in the backbone: + +- **`mesh_reserve` path reservations**: reserve before editing; other peers' `edit`/`write` tools get blocked on those paths — concurrent editing is prevented by mechanism, not by shouting. +- **`mesh_claim` task leases**: a single-writer lock with an `epoch:fence` (a broker restart invalidates old fences); commits carry `Mesh-Lease: task#leaseId#epoch:fence`, and the bundled commit-msg hook rejects stale-fence commits outright. +- **Capability routing `cap:`**: `mesh_send({ "to": "cap:deploy", ... })` routes the task to any idle peer advertising that capability instead of waiting for a busy teammate. Three message priorities: normal queues, urgent interrupts, force aborts the recipient's current turn and delivers once it settles (force is a control class and requires a reason). + +Add `mesh_wait_all` for group verdicts (one call returns who answered and who is missing), `mesh_status` for peer activity (● working / ○ idle / ✕ stuck), and a `pimesh` CLI for session-less access (`pimesh attach` can adopt a dead session's identity). Multi-machine deployment is supported: one machine runs the broker, the rest connect as clients. + +The honesty reaches down to exit codes: in the CLI, 3 means `expired` — a late reply is still delivered, you just stopped waiting; 5 means a stale lease, and the `commit-msg` hook rejects the commit on that basis. Even the host-specific edge of ESC purging the message queue is covered: a batch injected just as a turn aborts is re-delivered through an abort-safe channel once the turn settles (bounded retries), with a re-delivery counter visible in status. + +## 2. pi-board: the shared context board + +Messages are ephemeral; the ledger is hash-only. Where does "what we learned" live? [pi-board](https://github.com/wait4xx/pi-board) fills that layer. Five typed entries: + +- **OBSERVED** — something seen, no commitment +- **FACT** — a verified truth +- **FAIL** — a falsified path (the highest-value kind: the whole team stops re-burning budget on it) +- **CLAIM** — an ownership note, paired with a `mesh_claim` lease (the board records; it never enforces) +- **PATCH_SUMMARY** — what a landed change did + +The design is bounded and honest throughout: append-only local storage, refuse-not-evict (over-limit writes are refused, never silently evicted), short entries by default with a `detail` field unfolded only by id, boolean search (`,` = OR, `&` = AND) across the full history while `board_read` serves only the recent window; a search miss returns an honest empty, never a guess. Writes go to the room as ordinary broadcast frames; a new-FAIL digest line rides every turn boundary; the room's member / observer roles follow mesh semantics, so a read-only peer is never re-admitted as a writer after a reconnect. It joins the room as a normal peer — **all storage stays at the board's home; zero persistence in the broker**. A bundled `piboard` CLI does it in five verbs — join (member / observer) / watch / write / read / grep, one verb per action — so even a session-less terminal can join a room read-only and observe. The typology and the "small entries + on-demand detail + recent memory / full-history search" split come straight from the research literature (the lineage story is in [the next post](/en/archives/agensh/)). + +## 3. pi-jobd: the background job daemon + +`bash` blocks the current turn; `/reload` kills the process. [pi-jobd](https://github.com/cgarrot/pi-jobd) runs long commands in their own process group supervised by a per-user daemon: it returns in ~150 ms, and the job outlives the session. When to use it? Three criteria: the command will run longer than 60–90 seconds; you must keep working while it runs; or it must survive `/reload` and session end — plus "another agent should be able to stop it": `mesh_job_control` lets any authorized peer remotely stop/pause/resume someone else's background job. + +The state machine is equally honest: `running / paused / stopped / exited / failed`, plus `lost` — when the daemon restarts and cannot prove pid ownership, it refuses to stop rather than signal an unproven process. One more clever touch: installing the package is not enough — the model must *know when* to use it. Three layers feed the model the decision rule: a prompt snippet, guidelines on all seven tools, and an on-demand skill. + +## 4. pi-subagents: worker control + +[pi-subagents](https://github.com/nicobailon/pi-subagents) manages in-process child agents: foreground children stream inside the conversation; background children live in a detached runner process you can check later. It works right after install with no slash commands to learn — just say "use reviewer to review this diff". It ships common roles like scout and reviewer, and supports saved workflows and parallel reviews. Its mesh interface is `mesh_run_control`: remotely stop or steer a peer's RPC worker. + +## 5. One rehearsal of the four-piece suite + +![The collaboration loop](../posts/assets/pi-mesh-stack/loop.svg) + +## 6. Five minutes to onboard + +One line each: mesh and subagents install as pi packages — `pi install npm:pi-mesh-extension`, `pi install npm:pi-subagents`; pi-board is not on npm yet — clone, `npm ci`, `npm run build` — and it works CLI-only (reading and writing the local board needs no mesh at all); pi-jobd builds from source the same way, with `pijob run / list / log / stop` working out of the box. Open two pi sessions in one directory and you have two peers visible to each other in `mesh_status` — "zero config" is not a slogan here. + +Conversation over mesh, memory on the board, long work to jobd, exclusivity by lease — four packages, each doing its job, none overstepping. This blog's redesign was their proving ground: two mesh terminals (op-gitea, op-artalk) ran in parallel with the mainline, nineteen commits in one day; during the publish-chain outage, one lane reserved build.sh for emergency repair while an incoming hotfix edit was correctly blocked by the reservation — collisions are prevented by rule, not by reflex. + +Together the four pieces contain no database and no central brain, yet pin down all four questions: who is online, who is doing what, what was learned, and who watches the long jobs. Small tools, hard boundaries, honest states — that philosophy is worth copying more than any individual package. diff --git a/content/posts-en/spec-harness.md b/content/posts-en/spec-harness.md new file mode 100644 index 0000000..0a57053 --- /dev/null +++ b/content/posts-en/spec-harness.md @@ -0,0 +1,60 @@ +--- +title: "Spec Harness in Depth: Packaging Long-Horizon Development into Verifiable Task Packages" +pubDate: 2026-11-01 +category: tech +tags: [Engineering, AI Collaboration] +locked: true +--- + +What AI coding agents lack is not bandwidth for writing code — it is memory. A task that spans several sessions accumulates half-finished plans, already-falsified approaches, and acceptance criteria that get lost in chat history; restart the terminal and the context resets to zero. [Spec Harness](https://github.com/MicTx/spec-harness) targets exactly this: a task-package workflow tool for AI coding agents that persists long-horizon changes as a **recoverable, verifiable Development Record**, governed by scope, evidence, and Git gates. It provides no model and makes no product decisions for you. + +Its worldview in one sentence: **when a coding task outlives one conversation, the missing tool is not a smarter model — it is a contract that everyone (including your future self) can read.** + +## 1. The core abstraction: the task package + +All work lives in a `.spec/specs/YYYY-MM-DD_slug/` directory with two core files: `spec.md` records scope, assumptions, and trade-offs (including a remarkable "falsified paths" section, more on that below), while `tasks.md` holds the task list. After closeout the whole package is archived under `.spec/specs/archive/` — the archive directory is the project's engineering log. + +Every task must carry a two-line contract: **boundary** (which files this task may touch) and **verify** (how completion is proven). The verify is a read-only assertion that must exit 0 before the checkbox goes on. A real example from this blog's archived `2026-10-26_blog-5f` package, task T3: + +![Task package anatomy](../posts/assets/spec-harness/package-anatomy.svg) + +Boundary delimits "what may change"; verify delimits "how completion is proven" — both lines present, or the task stays unchecked. This is not formalism: with multiple agents running in parallel, boundary is the guardrail between lanes (in our practice, global style files are mainline-only; lanes request new variables instead of reaching in). Verify separates "looks done" from "proven done" — a verbal "passed" never counts. + +The most interesting section of `spec.md` is **falsified paths**: rejected proposals go into the archive together with the reason for rejection. Our blog-5f package records three — hero banner treatment (rejected by visual adjudication), a green heatmap (broke the grayscale skeleton), and shrinking the title from 27px to 22px (a hierarchy anchor; reduce weight, not size). Whoever wants to try again reads the file first and saves a round of budget. + +## 2. The stage pipeline: five core commands and the gates they keep + +![Stage pipeline](../posts/assets/spec-harness/pipeline.svg) + +Five core commands form one verifiable chain: **goal → scope → tasks → verification → archive → commit → push**. Gates stand between stages: `run` refuses while `spec.md` still has template placeholders; `done` requires every task to have boundary/verify, a fully green acceptance surface, and at least one non-placeholder piece of evidence (script output, test results); `push` merges only `spec/`-prefixed integration branches, never combines file changes with a commit, and forbids `--no-verify`. + +A blocked task gets a `!` marker and surfaces to the user — never a silent skip. Actionable issues found during `check` must be written back into the package and fixed in the same round; "to-dos" are not deliverables. + +**Interruption recovery is a designed norm** — the most direct answer to "tasks outlive conversations": re-run `/spec:run` at any moment and it resumes from the checked state in `tasks.md`, depending on no chat memory. Going further, `/spec:autoplan` runs interactive planning (clarify the goal, then framework, detail, and review passes; it stops when planning is ready — no auto-start), and `/spec:autorun` executes package by package, capped at 5 auto rounds by default (`--max-rounds` adjustable), resuming from the same step after a pause; the one-shot entry `/spec:goal` runs planning, execution, review, archiving, and the commit in a single pass. + +The command surface totals 12 stage commands: the core profile installs the five core commands, and full adds the seven extensions — goal / autoplan / autorun / update / status / doctor / organize — where `doctor` self-checks and repairs the environment and `organize` audits structure. One easily-missed detail: installing only lays down files; it never auto-evaluates every task. If you want it to proactively ask "should this get a package?" before you start, wire the activation hooks once with `install_activation_hooks.py --mode on`. The criterion is delivery shape — an independent acceptance surface, actual implementers, a recoverable in-flight task; small fixes, read-only investigations, and one-off experiments just get done. It guards against "forgot to evaluate", not against deliberate under-reporting — the documentation is refreshingly candid about this. + +## 3. Multi-agent orchestration: one orchestrator, bounded helpers + +Spec Harness is deliberately conservative about multi-agent work: **the main session is the single orchestrator** — routing, integration, acceptance, and the `done`/`push` gates never leave the mainline. Sidecar work (exploration, building, reviewing — context-independent slices) may be delegated, but only after a machine route decision (`scripts/route_decision.py`) and a written assignment contract: goal, scope, excluded areas, output, and verification method, all five present. An optional `handoff.md` covers cross-session boundaries — a generative snapshot header plus an append-only entry log, with required sections that adapt to solo / multi-person / agent / cluster collaboration modes. + +Extension slots plug other team processes in: `team-loop` for team cycles and `workflow-runner` for workflow fan-out, each with its README protocol and tests. The source repo also ships four orchestration agent definitions: orchestrator, planner, reviewer, confirmer. + +## 4. Installation: one installer, a dozen-plus hosts + +Spec Harness is a Python 3.9+ standard-library implementation (PolyForm Noncommercial license), installed in three steps: + +```bash +git clone https://github.com/MicTx/spec-harness.git /tmp/spec-harness +cd /tmp/spec-harness +git checkout v0.22.2 +bash install.sh +``` + +The installer supports a dozen-plus hosts: Claude Code, Codex, Gemini CLI, Grok, OpenCode, OpenClaw, Hermes, Pi, ZCode, DeepSeek Harness, Devin, Cursor… auto-detecting installed hosts when unspecified. Install profiles come in core / full: core ships the five core stage commands plus Git hooks; full adds all 12 stage commands and the slots/agents extensions. We use `INSTALL_HOSTS=pi bash install.sh` on Pi — the `/spec` commands work right after installation. + +## 5. Running on a real blog + +This blog is a user. The archive directory holds a chain of packages — from the bare-clone build rework and mobile layout fixes to the SEO unblocking: blog-5f packed eight tasks on three lanes (two mesh terminals plus the mainline) running in parallel, every task's verify a command-line assertion, page tasks wired to E2E — `E2E_BASE=http://127.0.0.1:18924 node tests/e2e.mjs`, all 34 passing. Packages relayed one after another; nineteen green commits landed in a single day. + +Tools iterate, but the idea does not expire: **write "what to do" as a contract, write "done" as evidence, archive the process as a log.** Whether the collaborators are humans or agents, those three things are the foundation of long-horizon engineering. diff --git a/content/posts/agensh.md b/content/posts/agensh.md new file mode 100644 index 0000000..a728136 --- /dev/null +++ b/content/posts/agensh.md @@ -0,0 +1,52 @@ +--- +title: "Agensh:把组织智能扩展到 1,024 个智能体" +pubDate: 2026-11-01 +category: tech +tags: [论文笔记, AI 协作] +--- + +多智能体系统能靠并发压缩复杂任务的时延,但主流框架有一个共同的天花板:中心编排器。任务分配、进度汇总、结果裁决全部挤过同一个上下文,规模越大,编排器先死。2026 年 10 月,微软研究院开源了 [Agensh](https://github.com/microsoft/Agensh)——一个**没有中心编排器**的自组织多智能体 harness,论文[《Scaling Organizational Intelligence to 1,024 Agents》](https://arxiv.org/abs/2609.26781)把它推到了一千零二十四个 agent 的规模。 + +它的答案出人意料地朴素:与其造一个更聪明的调度大脑,不如把一个人类组织的协同基建原样搬给 agent 们。 + +## 一、三支柱:组织的协同基建 + +![从中心编排到自组织](./assets/agensh/pillars.svg) + +Agensh 只给三样基础设施,其余全部自组织: + +- **共享工作区**:git 平台承载组织的进行中工作与集成结果,分支、PR、合并冲突这些人类用了二十年的机制原样复用; +- **消息接口**:团队频道加私信,带优先级送达——组织级广播与紧急碰撞调解各走各的道; +- **共享上下文**:一块类型化条目板,存组织的发现与工作意图。 + +开源参考实现用的是 Gitea 承载工作区、Mattermost 承载频道与私信——一套完全开源自接的“办公室”,没有任何私有服务。没有编排器分配任务:worker 自己从工作区和上下文里找活、认领、验证、合并。规模化时天生的瓶颈(那个越来越忙的中枢)根本不存在。 + +## 二、协作环:每个 worker 各跑一圈 + +![多智能体协作环](./assets/agensh/loop.svg) + +每个 worker 并发、异步地执行同一个协作环:**收集上下文 → 认领子任务 → 执行 → 验证 → 合并进度**。收集上下文时读共享工作区和条目板的存量知识;认领靠 CLAIM 声明,撞车了私聊解决;验证自己跑测试,证据说话;合并走 PR。 + +最有意思的设计在共享上下文的**经济学**:条目刻意短小(约 100 字符,PATCH_SUMMARY 放宽到 300),长版本放 `detail` 字段按需展开;`board_read` 只服务最近 2000 条,更早的历史只能靠布尔检索(`,` = OR,`&` = AND)翻出来——近期记忆保持小,长尾靠搜索。论文称 **FAIL 是价值最高的条目**:一条被证伪的路径写下来,就能止住全队在同一个死胡同里重复烧预算。新条目会作为较高优先级的更新,在同伴的下一个工具调用边界推送过去。 + +这套共享上下文不是 Agensh 的发明——论文 §2.3 明说“共享上下文遵循 DeLM 的核心思想”。[DeLM](https://github.com/yuzhenmao/DeLM)([arXiv:2606.10662](https://arxiv.org/abs/2606.10662))用共享上下文加任务队列跑去中心化多智能体:它的板是一张 append-only 事件日志(条目、认领、完成、FACT/FAIL 笔记、状态),正文存在日志旁的独立数据库,带硬上限(≤40 个文件、≤400KB 总量),还有一个阻塞式的 `read --wait`——同伴发帖即唤醒等待者。在 Terminal-Bench 4.0 的 10 项子集上,两个 agent 通过共享上下文协同,平均提升 12.5 个百分点准确率、1.78 倍加速。Agensh 把这条线索放大到了千级规模。 + +## 三、数字:扩容真的有用吗 + +![规模收益](./assets/agensh/scale.svg) + +两组数据回答"加 agent 到底加不加得动":ProgramBench 最难 5 题,1 → 128 个 agent,通过率 19.31% → 28.78%(相对提升约 49%);从零构建 pandoc(6 小时预算、无外网),1 → 1,024 个 agent,通过率 33.89% → 55.06%。对纯堆算力已经边际递减的难题,**组织化的边际收益还在**。 + +工程可用性也到位了:v1.0 于 2026-10-23 发布,六天后的 v1.0.1 已支持 Copilot、Codex、Claude Code、Pi 作为底层单智能体 harness——单 agent 侧你可以用任何顺手的主力模型。开源版是单节点 harness,v1.0 发布包里就带着复现指南、论文与演示——从论文到可跑的仓库,中间没有隔着一句“敬请期待”。 + +## 四、从论文到桌面:一个 issue 的故事 + +这篇论文对我们不只在纸上。把它读透之后,2026-10-23 我在 pi-mesh 仓库提了[第 13 号 issue](https://github.com/cgarrot/pi-mesh/issues/13):pi-mesh 已有消息接口(`mesh_send`/房间/优先级)和共享工作区(git + `mesh_reserve` 预约),独缺第三支柱共享上下文——提议按 Agensh/DeLM 的形状加 `board_write / board_read / board_grep`。 + +维护者 cgarrot 的回复是整个故事里最值得学的一课:方向对,但**hash-only 台账让 pi-mesh 结构上当不了这块板**——把持久化塞进 broker 等于把路由器改造成数据库。正确的形状是独立包:以普通 peer 入房、自有存储、mesh 继续只做路由。于是有了 [pi-board](https://github.com/wait4xx/pi-board):一天内出 v0.1,55 个测试零失败、真实 broker 上九步冒烟,issue 最终关闭时官方指针就落在它身上。上一篇文章介绍的[四件套](/archives/pi-mesh-stack/),其记忆层就是从这篇论文长出来的。 + +## 五、结语 + +Agensh 的启示不是"1024"这个数字,而是它对"组织智能"的拆解:工作区、消息、共享上下文——三根支柱撑起自组织,任何一根都不需要一个更聪明的大脑。这个拆解在千级规模成立,在单机四件套成立,在单人加几个 agent 终端的小作坊同样成立。规模会变,支柱不变。 + +相关阅读:[Spec Harness 详解](/archives/spec-harness/) · [pi-mesh 全家桶详解](/archives/pi-mesh-stack/) diff --git a/content/posts/assets/agensh/loop.svg b/content/posts/assets/agensh/loop.svg new file mode 100644 index 0000000..a20da1a --- /dev/null +++ b/content/posts/assets/agensh/loop.svg @@ -0,0 +1,45 @@ + + + 多智能体协作环:每个 worker 并发、异步地各跑一圈 + + + + + ① 收集上下文 + 读工作区 + 检索条目板 + + + ② 认领子任务 + 声明 CLAIM,冲突私聊解 + + + ③ 执行 + 本地改动推送分支 + + + ④ 验证 + 跑测试,证据说话 + + + ⑤ 合并进度 + PR 合入共享工作区 + + + + + + + + + + + 下一圈 + + + + 共享上下文(类型化条目:OBSERVED / FACT / FAIL / CLAIM / PATCH_SUMMARY) + 全程发布发现;条目刻意短小(约 100 字符),长文 detail 按需展开;近 2000 条常驻,全史靠布尔检索 + + + 论文称 FAIL 是"价值最高的条目":一条被证伪的路,能止住全队的重复预算 + diff --git a/content/posts/assets/agensh/pillars.svg b/content/posts/assets/agensh/pillars.svg new file mode 100644 index 0000000..41ed6bd --- /dev/null +++ b/content/posts/assets/agensh/pillars.svg @@ -0,0 +1,64 @@ + + + 从中心编排到自组织:Agensh 的三支柱 + + + + 传统多智能体:中心编排器瓶颈 + + orchestrator + + + + + + + + w1 + w2 + w3 + … + + 任务分配、进度汇总、结果裁决 + 全部挤过同一个上下文—— + 规模越大,编排器先成为天花板 + + + + + + + + Agensh:无中心编排,三支柱基础设施 + + + 共享工作区 + git 平台 + 分支 / PR / 合并 + + 消息接口 + 团队频道 + 私信 + 优先级送达 + + 共享上下文 + 类型化条目板 + 近期记忆 + 全史检索 + + + + + + + + + + + w1 + w2 + w3 + w4 + … + + worker 自己跑协作环:收集上下文 → 认领 → 执行 → 验证 → 合并 + 发现发布到共享上下文,同伴在下一个工具调用边界收到广播 + diff --git a/content/posts/assets/agensh/scale.svg b/content/posts/assets/agensh/scale.svg new file mode 100644 index 0000000..159ff85 --- /dev/null +++ b/content/posts/assets/agensh/scale.svg @@ -0,0 +1,34 @@ + + + 规模收益:扩容 agent 带来的通过率提升 + 数据:arXiv:2609.26781 + + + ProgramBench 最难 5 题 + 1 → 128 agents + + + + + 19.31% + 1 agent + 28.78% + 128 agents + + 相对提升约 49% + + + 从零构建 pandoc(6h 预算 · 无外网) + 1 → 1,024 agents + + + + 33.89% + 1 agent + 55.06% + 1,024 agents + + +21.2 个百分点 + + + diff --git a/content/posts/assets/pi-mesh-stack/loop.svg b/content/posts/assets/pi-mesh-stack/loop.svg new file mode 100644 index 0000000..3bec23c --- /dev/null +++ b/content/posts/assets/pi-mesh-stack/loop.svg @@ -0,0 +1,47 @@ + + + 一次典型合奏:四件套怎么咬合 + + + + mesh_send + 契约式派单 / 对话 + 五字段任务包 + 期限 + + + board_grep + 先查团队记忆 + FAIL 可检索不重烧 + + + job_run + 长活交后台 + turn 不阻塞 + + + mesh_claim + 单写者租约 + epoch:fence 围栏 + + + board_write + 留痕 + CLAIM 带租约号 + + + + + + + + + + + + + + + 发现与结论回写团队记忆,下一轮派单从存量知识起步 + + 对话走 mesh · 记忆上 board · 长活交 jobd · 排他靠租约 + diff --git a/content/posts/assets/pi-mesh-stack/stack.svg b/content/posts/assets/pi-mesh-stack/stack.svg new file mode 100644 index 0000000..747133c --- /dev/null +++ b/content/posts/assets/pi-mesh-stack/stack.svg @@ -0,0 +1,47 @@ + + + pi-mesh 工具族:一个路由器,三个卫星 + + + + pi 终端 @op-gitea + edit/write 受预约拦截 + + pi 终端 @op-artalk + 读回执 · 忙闲状态 + + pimesh attach / CLI + 无会话独立 peer + + + + + + + + pi-mesh —— 通信骨干(github.com/cgarrot/pi-mesh) + broker(内存态:peers / rooms / 邮箱 / 限速)· 房间与角色 member/observer + mesh_reserve 路径预约 · mesh_claim 单写者租约(epoch:fence,commit-msg 钩子拒过期围栏) + 优先级 normal / urgent / force · 状态诚实三档 delivered ≠ read ≠ answered · 台账 hash-only + + + + + + + + + pi-board —— 团队记忆板 + OBSERVED/FACT/FAIL/CLAIM/PATCH_SUMMARY + 有界 append-only 存储 · 布尔检索 board_grep + 以普通 peer 入房;自有存储,broker 零持久化 + + + pi-jobd —— 后台作业守护 + 脱离 turn 的进程组 · 存活于 /reload 与会话之外 + 诚实状态机(lost = 无法证明归属则拒操作) + mesh_job_control 跨 peer 远程 stop/pause/resume + + + pi-subagents(worker 控制:spawn/steer/abort,mesh_run_control)与上面三者同族协作 + diff --git a/content/posts/assets/spec-harness/package-anatomy.svg b/content/posts/assets/spec-harness/package-anatomy.svg new file mode 100644 index 0000000..f6f346b --- /dev/null +++ b/content/posts/assets/spec-harness/package-anatomy.svg @@ -0,0 +1,37 @@ + + + 任务包解剖:.spec/specs/YYYY-MM-DD_slug/ + + + + 2026-10-26_blog-5f/ + ├── spec.md + 范围 · 假设 · 已证伪 + ├── tasks.md + boundary + verify + └── handoff.md + 跨会话交接(可选) + + 收尾后整包归档至 .spec/specs/archive/, + 归档目录就是项目的工程日志。 + + + + + 每个任务 + + + + + - [x] T3 构建期内容 lint + build.sh 守卫 + claim: op-gitea(mesh 车道) + boundary: 新建 content-lint.mjs + 守卫挂载 + verify: + node scripts/build-perf/content-lint.mjs dist + && bash -n infra/deploy/build.sh + verify 是只读断言:跑出退出码 0 才许勾选, + 口头"过了"永远不算数。 + + boundary 划定"能动什么",verify 划定"怎么证明做完"——两行合同,缺一不勾 + + diff --git a/content/posts/assets/spec-harness/pipeline.svg b/content/posts/assets/spec-harness/pipeline.svg new file mode 100644 index 0000000..371e19b --- /dev/null +++ b/content/posts/assets/spec-harness/pipeline.svg @@ -0,0 +1,51 @@ + + + 阶段流水线:五个核心命令与它们把守的门 + + + + + /spec:new + 建任务包 + spec.md + tasks.md + 模板占位未填 → 拒 run + + + /spec:run + 逐任务执行 + verify 跑通才勾选 + 阻塞任务打 ! 上浮 + + + /spec:check + 复核轮 + 问题当轮回写修复 + 闭环项五选一登记 + + + /spec:done + 归档 + 包提交 + 证据随包入档 + 验收面证据必须真实 + + + /spec:push + 合并 + 推送 + 删已并分支 + 只认 spec/ 前缀分支 + + + + + + + + + + + + + + 中断恢复是常态设计 + 任意时刻重跑 /spec:run,从 tasks.md 勾选状态续跑;/spec:autorun 可续自动链(默认 5 轮上限,--max-rounds 可调) + diff --git a/content/posts/pi-mesh-stack.md b/content/posts/pi-mesh-stack.md new file mode 100644 index 0000000..2cfdcd0 --- /dev/null +++ b/content/posts/pi-mesh-stack.md @@ -0,0 +1,62 @@ +--- +title: "pi-mesh 全家桶详解:单机多智能体协同的四件套" +pubDate: 2026-11-01 +category: tech +tags: [工程实践, AI 协作] +--- + +[pi](https://github.com/earendil-works/pi) 是我们日常用的编码智能体宿主。单开一个终端时它是个安静的助手;但同时开三四个终端、每个里面一个 agent 抢同一个仓库时,问题就来了:谁在线?谁在改哪个文件?消息发出去了对方到底看没看见?半夜跑着的构建谁有权停? + +围绕 [pi-mesh](https://github.com/cgarrot/pi-mesh) 长出来的一族小工具把这层协同做成了基建。它们各管一摊,咬合成套: + +![pi-mesh 工具族](./assets/pi-mesh-stack/stack.svg) + +## 一、pi-mesh:通信骨干 + +pi-mesh 是一条本机总线:一个脱离会话存活的 broker(NDJSON 帧走 unix socket),每个 pi 终端以别名成为 peer,加入房间(room)。消息 < 50ms 到达,零运行时依赖,Node ≥ 20。 + +它最值得称道的是**诚实状态模型**:`delivered`(写进了对方套接字)≠ `read`(注入了对方会话)≠ `answered`(拿到了显式回复)——三者永不混淆,没有一个是"完成"的意思。配套的**持久台账是 hash-only 的**:消息正文永不落盘,重启后能审计"谁在何时给谁发过什么",但看不到内容。这个自我约束后来成了整个工具族的设计公理:**mesh 只做路由器,永不做数据库。** + +协同刚需有三个都在骨干里: + +- **`mesh_reserve` 路径预约**:改文件前先预约,其他 peer 的 `edit`/`write` 工具在该路径上直接被拦——并发编辑靠机制防,不靠喊话。 +- **`mesh_claim` 任务租约**:单写者锁,带 `epoch:fence`(broker 重启即作废旧围栏);提交信息里写 `Mesh-Lease: task#leaseId#epoch:fence`,配套 commit-msg 钩子直接拒绝过期围栏的提交。 +- **能力路由 `cap:`**:`mesh_send({ "to": "cap:deploy", ... })` 把任务发给任意一个空闲且自报该能力的 peer,而不是等忙着的队友。消息优先级三档:normal 排队、urgent 插队、force 先中止对方当前回合再送达(force 属管控类,必须带 reason)。 + +另有 `mesh_wait_all` 做群裁(一次收回“谁答了、谁没答”的名单)、`mesh_status` 看 peer 忙闲(● 干活 / ○ 空闲 / ✕ 卡死)、`pimesh` CLI 支持无会话接入(`pimesh attach` 能收养死掉会话的身份)。跨机部署也支持:一台起 broker,其余机器做客户端。 + +诚实的颗粒度细到退出码:CLI 里 3 表示 `expired`——晚到的答复仍会送达,只是你等起见超时了;5 表示租约已过期,`commit-msg` 钩子据此把提交拒之门外。甚至 ESC 清空消息队列这种宿主边界也考虑到了:批量注入若撞上回合中止,broker 会在该回合结束后经中止安全通道重投(有界重试),状态页能看到“中止清除恢复重投”计数。 + +## 二、pi-board:团队记忆板 + +消息是易逝的,台账是 hash-only 的,那"我们学到了什么"存哪?[pi-board](https://github.com/wait4xx/pi-board) 补上这层。五种类型化条目: + +- **OBSERVED**——看到了什么(不承诺) +- **FACT**——验证过的事实 +- **FAIL**——一条被证伪的路(价值最高:全队不必再烧第二次预算) +- **CLAIM**——认领声明,与 `mesh_claim` 租约配对(板只记录,从不执行) +- **PATCH_SUMMARY**——落了什么改动 + +设计上处处是“有界与诚实”:append-only 本地存储、refuse-not-evict(超限拒绝写入而非静默淘汰)、条目默认短小、长文 `detail` 只能按 id 展开、布尔检索(`,` = OR,`&` = AND)覆盖全史而 `board_read` 只看近期窗口;检索无果时返回诚实的空,绝不猜一条充数。写入以普通广播帧发进房间,turn 边界有新 FAIL 摘要行;房间角色 member / observer 沿用 mesh 语义,只读 peer 永远不会在重连后被误升为写者。它以普通 peer 身份入房——**存储全在板自己家里,broker 里零持久化**。附带的 `piboard` CLI 五个动词一把梭:join(member / observer)/ watch / write / read / grep,一动词一动作,无会话的终端也能进房只读围观。这套类型学与"小条目+按需展开+近期记忆/全史检索"的分工直接来自学术论文(血统故事见[下一篇](/archives/agensh/))。 + +## 三、pi-jobd:后台作业守护 + +`bash` 会阻塞当前回合,`/reload` 会杀进程。[pi-jobd](https://github.com/cgarrot/pi-jobd) 把长命令放进独立进程组,由 per-user 守护监管:~150ms 返回,作业存活于会话之外。什么时候用它?三条判据:命令预计超过 60-90 秒;你必须边跑边干别的;或者它得扛过 `/reload` 和会话结束——以及"别的 agent 应该能停它"这一条:`mesh_job_control` 让任一授权 peer 远程 stop/pause/resume 别人的后台作业。 + +状态机同样诚实:`running / paused / stopped / exited / failed`,外加一个 `lost`——守护重启后无法证明 pid 归属时,宁可拒绝 stop 也绝不信号一个来路不明的进程。这个包还有个巧思:装包不够,模型还得**知道什么时候用**——它靠 prompt 快照、七个工具上的决策守则和一份按需加载的 skill 三层把使用时机喂给模型。 + +## 四、pi-subagents:worker 控制 + +[pi-subagents](https://github.com/nicobailon/pi-subagents) 管的是进程内子代理:前台子代理流式跑在对话里,后台子代理活在独立的 runner 进程中随时可查。装完即用,不需要学斜杠命令——直接说"用 reviewer 审这个 diff"就行。它预置了 scout(侦察)、reviewer(审查)这类常用角色,也支持保存的工作流和并行审查。与 mesh 的接口是 `mesh_run_control`:远程 stop 或 steer 一个 peer 的 RPC worker。 + +## 五、四件套的一次合奏 + +![协作循环](./assets/pi-mesh-stack/loop.svg) + +## 六、上手五分钟 + +安装各一行:mesh 与 subagents 走 pi 包管理——`pi install npm:pi-mesh-extension`、`pi install npm:pi-subagents`;pi-board 还没发 npm,源码三步(clone、`npm ci`、`npm run build`),且可 CLI 独立用(不需要 mesh 也能读写本地板);pi-jobd 同样源码构建,`pijob run / list / log / stop` 开箱即用。装完在同一目录开两个 pi 会话,就是两个 peer,`mesh_status` 互相可见——协同基建的“零配置”不是口号。 + +对话走 mesh,记忆上 board,长活交 jobd,排他靠租约——四个包各司其职,没有任何一个越界。这个博客的重设计期就是这套东西的实战场:两个 mesh 终端(op-gitea、op-artalk)与主线并行,一天 19 连发;发布链中断的修复窗口里,主线预约了 build.sh 紧急处置,另一边赶去补刀的编辑被预约机制正确拦下——撞车靠规则防住,不靠谁手快。 + +四件套加起来没有一个数据库、没有一个中心大脑,却把"谁在线、谁在干啥、学到过啥、长活谁看着"四件事全部钉死。小工具、硬边界、诚实状态——这套哲学比任何一个具体包都值得抄。 diff --git a/content/posts/spec-harness.md b/content/posts/spec-harness.md new file mode 100644 index 0000000..7c05af3 --- /dev/null +++ b/content/posts/spec-harness.md @@ -0,0 +1,61 @@ +--- +title: "Spec Harness 详解:把长程开发装进可验收的任务包" +pubDate: 2026-11-01 +category: tech +tags: [工程实践, AI 协作] +--- + +AI 编程智能体最不缺的是写代码的带宽,最缺的是记忆。一个跨了好几轮会话的任务,改到一半的方案、已经否决的路线、验收口径,散落在聊天记录里就等于丢了——换一个会话、重启一次终端,上下文归零。[Spec Harness](https://github.com/MicTx/spec-harness) 解决的就是这个问题:它是一个面向 AI 编程智能体的任务包工作流工具,把长程改动保存为**可恢复、可验证的 Development Record**,用范围、证据和 Git 门禁管住全程。它不提供模型,也不替你做产品决策。 + +一句话概括它的世界观:**当一个编码任务的寿命超过一段对话,缺的不是更聪明的模型,而是一份大家(包括未来的你)都能读的合同。** + +## 一、核心抽象:任务包 + +所有工作装进 `.spec/specs/YYYY-MM-DD_slug/` 目录,核心是两个文件:`spec.md` 写范围、假设与取舍(还有一节很特别的"已证伪路径",后面细说),`tasks.md` 写任务清单。收尾后整包归档到 `.spec/specs/archive/`,归档目录本身就是项目的工程日志。 + +每个任务必须带两行合同——**boundary**(这个任务能动哪些文件)和 **verify**(怎么证明做完了)。verify 是只读断言,跑出退出码 0 才许勾选。拿这个博客真实归档的 `2026-10-26_blog-5f` 包里 T3 任务举例: + +![任务包解剖](./assets/spec-harness/package-anatomy.svg) + +boundary 划定"能动什么",verify 划定"怎么证明做完"——两行齐备,缺一不勾。这不是形式主义:多 agent 并行时,boundary 就是车道之间的护栏(我们的实践里,全局样式文件只许主线动,车道要新变量走申请);verify 则把"看起来好了"和"证明做完了"区分开,口头"过了"永远不算数。 + +`spec.md` 里最有味道的一节是**已证伪路径**:被否决的方案连否定理由一起入库。我们的 blog-5f 包里记着三条——首屏 banner 化(视觉裁定否决)、热力图换绿(破坏灰阶骨架)、标题 27px 收到 22px(层级锚点,要轻减字重不减号)。下次谁想再试一遍,先读档案,少烧一轮预算。 + +## 二、阶段流水线:五个核心命令与它们把守的门 + +![阶段流水线](./assets/spec-harness/pipeline.svg) + +五个核心命令串起一条可验证链:**目标 → 范围 → 任务 → 验证 → 归档 → 提交 → 推送**。每个阶段之间都有门把守:`spec.md` 有模板占位符就拒绝进入 run;`done` 要求每个任务 boundary/verify 齐备、验收面全绿且至少有一条非占位证据(脚本输出、测试结果);`push` 只合并 `spec/` 前缀的集成分支,文件改动与提交永远分开做,禁用 `--no-verify`。 + +被阻塞的任务会打 `!` 标记上浮给用户,绝不静默跳过;复核轮(check)发现的可执行问题必须当轮写回任务包并修复,不允许把"待办"当交付物甩给用户。 + +**中断恢复是常态设计**——这是它对“任务寿命超过对话”最直接的回答:任意时刻重跑 `/spec:run`,从 `tasks.md` 的勾选状态续跑,不依赖任何对话记忆。更进一步,`/spec:autoplan` 做交互式规划(澄清目标后过框架、细节、复核三轮,规划就绪即停,不自动开工),`/spec:autorun` 按规划逐包执行,默认最多 5 轮自动链(`--max-rounds` 可调),暂停后从同一步恢复;一键式入口 `/spec:goal` 则把规划、执行、复核、归档、提交一次跑完。 + +命令面共 12 个阶段命令:core 档装五个核心命令,full 档补齐 goal / autoplan / autorun / update / status / doctor / organize 七个扩展件——`doctor` 做环境自检与修复,`organize` 做结构审计。还有一个容易被忽略的细节:安装只是放文件,不会主动逐任务评估;想让它在你动手前主动问一句“这事要不要开包”,需要显式接线一次 `install_activation_hooks.py --mode on`。判据看交付形状——独立验收面、实际实施者、可恢复的在途任务;小修、只读调查、一次性实验都直接做。它防的是“忘了评估”,不防刻意瞒报——文档里对此毫不讳言。 + +## 三、多 agent 编排:一个编排者,有边界的帮工 + +Spec Harness 对多 agent 的态度很克制:**主会话是唯一的编排者**,路由、集成、验收和 `done`/`push` 门禁永远不出主线。旁支工作(探索、构建、审查这类上下文无关的活)可以委托,但要先过机器路由决策(`scripts/route_decision.py`)并写下任务合同:目标、范围、排除区、产出、验证方式五项齐备才许派。它甚至为"跨会话交接"准备了可选的 `handoff.md`——生成式快照头加 append-only 条目日志,单人、多人、agent、集群四种协作模式各有一套必填小节。 + +扩展位(slots)机制则把"别的团队流程"插进来:`team-loop` 管团队循环、`workflow-runner` 管工作流扇出,各自带 README 协议和测试。源码库里还附了 orchestrator/planner/reviewer/confirmer 四个编排代理定义。 + +## 四、安装:一个安装器,十余个宿主 + +Spec Harness 是 Python 3.9+ 的标准库实现(PolyForm Noncommercial 许可),安装就三步: + +```bash +git clone https://github.com/MicTx/spec-harness.git /tmp/spec-harness +cd /tmp/spec-harness +git checkout v0.22.2 +bash install.sh +``` + +安装器支持十余个宿主:Claude Code、Codex、Gemini CLI、Grok、OpenCode、OpenClaw、Hermes、Pi、ZCode、DeepSeek Harness、Devin、Cursor……不指定时自动探测已装的宿主。安装档位分 core / full:core 只装五个核心阶段命令加 Git 钩子;full 补齐全部 12 个阶段命令和 slots、agents 扩展组件。我们在 Pi 上用 `INSTALL_HOSTS=pi bash install.sh`,装完 `/spec` 系列命令直接可用。 + +## 五、跑在一个真实博客上 + +这个博客就是它的用户。归档目录里躺着从裸 clone 构建改造、移动端布局修复到 SEO 解封的一串任务包:blog-5f 一个包八个任务、三条车道(两条 mesh 终端加主线)并行,每个任务的 verify 都是能在命令行跑出退出码的断言,页面类任务统一挂 E2E——`E2E_BASE=http://127.0.0.1:18924 node tests/e2e.mjs`,34 项全过才算数。包与包接力,一天 19 个提交全绿落地。 + +门禁也真的拦过烂账:一次一个全 manual、从未执行的任务包混进了 `.spec/specs/`,check 门禁直接判 blocked,连带拦下所有携带归档路径的提交——直到把它移出。门禁防的不只是烂尾,还有“看起来有规划”的空包。 + +工具会迭代,但这套思路不会过期:**把"要干什么"写成合同,把"做完了"写成证据,把过程归档成日志。** 无论协作方是人还是 agent,这三件事都是长程工程的地基。