Agent / Local Harness

一套自己拥有的本地 Agent 运行时:自研循环、可替换执行器、文件优先记忆、无人值守调度与代码化验收。

本地 Agent Harness

把记忆、权限、触发和验收握在自己手里,让 Agent 真的把事做完。

为什么做

Why this exists

我原本已经有一个每天 23:00 自动发布技术趋势的流程:抓取、撰写、渲染、推送,步骤都是我自己定的。但它跑在哪、什么时候醒、记住了什么,全都挂在别人的运行时里。行为归我,运行时归厂商——这是"看起来很像自己的 Agent"和"真的是自己的 Agent"之间最常见的一条界线。

I already had a workflow that publishes a daily tech digest at 23:00: fetch, write, render, push, all steps defined by me. But where it ran, when it woke up and what it remembered all belonged to someone else's runtime. My behaviour, their runtime - that is the most common boundary between something that looks like my own agent and something that actually is.

RAG 不是"自己的"的来源。检索只是上下文装填手段:通用 Agent 读本地文件本身就是按需检索,在个人规模下往往比向量召回更准。真正属于自己的是四件事——记忆归你、权限归你、触发归你、验收标准归你。

RAG is not what makes an agent yours. Retrieval is just context filling: a general coding agent already reads local files on demand, which at personal scale is usually more accurate than vector recall. What is genuinely yours are four things - memory, permissions, triggers and acceptance criteria.

解决什么问题

What it solves

  1. 01

    能力在,但所有权不在

    Capability without ownership

    会话、记忆、调度和凭据都在别人的产品里,换一个工具就从零开始,历史也拿不回来。

    Sessions, memory, scheduling and credentials live inside someone else's product; switching tools means starting over.

  2. 02

    通用 Agent 不会自己开始

    A general agent never starts itself

    它只在你打开窗口、开口提问时干活。夜里该跑的东西,需要有人先想起它。

    It only works when you open a window and type. Anything that should run overnight needs a human to remember it.

  3. 03

    权限是"大概能用",不是"明确允许"

    Permissions are vague, not explicit

    哪个任务能写哪些目录、能跑哪些命令、能不能联网,通常没有一处可审计的声明。

    Which task may write where, run what, or reach the network is rarely declared in one auditable place.

  4. 04

    验收靠人眼,失败靠运气

    Acceptance by eyeball, failure by luck

    输出合不合格由人翻一遍才知道;失败后是重跑、降级还是放弃,没有统一策略。

    Whether an output is acceptable is decided by scrolling through it; whether a failure retries, degrades or aborts is ad hoc.

能做什么

What it can do

无人值守跑完整流程

Run a full pipeline unattended

定时或事件唤醒,从抓取一路做到发布与通知,中途不需要人盯着。

Woken by a schedule or an event, it goes from data collection all the way to publishing and notification without supervision.

把重复流程变成一条声明

Turn a repeated process into a declaration

步骤、可用工具、可写路径、预算和降级策略写进一个任务文件,而不是散落在聊天记录里。

Steps, allowed tools, writable paths, budget and degradation policy live in one task file instead of scattered chat history.

会记住事的助手

An assistant that remembers

每次运行的事实自动落盘并建索引,长期结论由人确认后才沉淀,可检索、可审计、可删除。

Facts from every run are stored and indexed automatically; long-term conclusions are human-confirmed, searchable, auditable and deletable.

用实验台比较策略

Compare strategies with an eval lab

同一份输入跑多条路线,比较成功率、可核验率、token 与耗时,而不是凭感觉选方案。

Run several routes over the same input and compare success rate, traceability, tokens and wall-clock instead of guessing.

把重活外包给成熟执行器

Delegate heavy lifting to mature executors

Codex CLI、Claude Code、云端模型都只是可替换的执行器;调度、记忆和验收留在自己手里。

Codex CLI, Claude Code and cloud models are swappable executors; scheduling, memory and acceptance stay on your side.

失败看得见、说得清

Failures that are visible and explainable

每次运行都有台账:步骤、工具调用、token、耗时、失败分类与降级原因,回看就能定位。

Every run leaves a ledger: steps, tool calls, tokens, duration, failure class and degradation reasons.

系统结构

Architecture

内核是自己写的确定性循环,模型只是其中一层。任务声明式描述,工具按权限调用,产物经过代码化的验收标准才会落地。

The kernel is a deterministic loop I wrote; the model is only one layer inside it. Tasks are declared, tools are called under explicit permissions, and artifacts must pass acceptance criteria written in code.

本地 Agent Harness 的五层结构:触发与验收、任务与编排、工具与权限、记忆、模型适配 Five layers of the local agent harness: triggers and acceptance, tasks and orchestration, tools and permissions, memory, model adapters
图 1 · 五层结构:上面两层是你的规矩,中间两层是你的资产与边界,最下面才是可替换的模型。
Figure 1 - Five layers: the top two are your rules, the middle two are your assets and boundaries, and the bottom layer is the swappable model.

一次无人值守运行

One unattended run

以"每日技术趋势"为例,这是它每晚实际走过的路径。任何一步降级都会被记录,而不是悄悄糊过去。

Using the daily tech digest as the example, this is the path it actually walks every night. Every degradation is recorded rather than quietly smoothed over.

一次无人值守运行的七个步骤,以及降级路径 Seven steps of one unattended run, plus the degradation path
图 2 · 定时唤醒到发布:任务锁保证同一个任务只跑一份,四项校验通过之后才允许推送。
Figure 2 - From scheduled wake-up to release: a task lock keeps a single run in flight, and publishing only happens after all four gates pass.
  • 重复触发:同一天同一任务只成功一次(数据库唯一索引 + 文件锁),被中断的运行下次自动标记为 crashed 并重跑。
  • Idempotency: one successful run per task and day (unique index plus a file lock); an interrupted run is marked crashed and safely retried.
  • 降级:代理不可用或数据源额度耗尽时,沿用已有数据继续,并如实标记 degraded。
  • Degradation: when a proxy or a data source quota fails, it continues on existing data and marks the run degraded.
  • 中止:必需校验不通过或推送失败就判失败并发通知,绝不用半成品凑数。
  • Abort: a failed required gate or a failed push stops the release and raises a notification - no half-finished output is shipped.

实测数据

Measured evidence

下面这组数字来自真实运行,不是设计文档里的估计。它同时解释了一个工程结论:一篇 20 条的双语稿件塞不进一次模型响应。

These numbers come from real runs, not estimates in a design document. They also explain one engineering conclusion: a 20-item bilingual article does not fit in a single model response.

三条撰写路线的输入输出 token 与结果对比 Input and output tokens for three composition routes, with outcomes
图 3 · 同一份 2026-09-22 抓取数据下的三条路线:一次性撰写两次都被输出上限截断,分片撰写在更省 token 的前提下通过全部校验。
Figure 3 - Three routes over the same 2026-09-22 capture: single-shot composition was truncated twice by the output ceiling, while chunking passed every gate on fewer tokens.
  • 发布闸门:结构、引用完整性、来源可核验性、生成物漂移四项校验,全部代码化。
  • Release gates: structure, reference integrity, source traceability and generated-file drift - all enforced in code.
  • 防编造:正文引用的每条来源都必须能在当日原始抓取结果里找到,实测 47/47 可回溯。
  • Anti-fabrication: every cited source must exist in that day's raw capture; measured 47 out of 47 traceable.
  • 真实的失败案例:模型多写了 4 条热点,被上限校验挡下,运行判失败并通知,而不是把超限内容发出去。
  • A real failure: the model wrote four items over the limit; the gate failed the run and notified instead of publishing over-limit content.
  • 崩溃恢复:在步骤执行中途强制 kill 进程,下一次运行自动识别并重跑,没有产生重复发布。
  • Crash recovery: killing the process mid-step led the next run to detect and retry it, with no duplicate release.

怎么用

How to use it

标准库优先,不需要 Docker,也不需要额外服务。仓库里带一条真实任务(每日技术趋势)作为参考实现。

Standard library first: no Docker and no extra services. The repository ships one real task (the daily digest) as a reference implementation.

./agent doctor ./agent doctor ./agent run daily-trends --compose replay --dry-run ./agent run daily-trends --compose replay --dry-run ./agent experiment run daily-trends-compare --date 2026-09-22 --allow-llm ./agent experiment run daily-trends-compare --date 2026-09-22 --allow-llm ./agent status / runs / report <run_id> ./agent status / runs / report <run_id>

质量闸门

Quality gates

  • 同一天同一任务只允许一次成功产物,重跑必须显式声明。
  • One successful artifact per task and day; a forced re-run must be explicit.
  • 工具调用受可写路径与命令白名单约束,越权直接拒绝并记入台账。
  • Tool calls are bounded by writable paths and a command allow-list; violations are refused and recorded.
  • 内容必须通过结构、引用与可核验性校验,缺一不发。
  • Content must pass structure, reference and traceability checks; missing one blocks release.
  • 生成物漂移同样会被拦下(例如站点 sitemap 反复累积空行这类问题)。
  • Generated-file drift is blocked too - for example a sitemap that accumulates blank lines on every run.

边界与说明

Limits and notes

  • 面向个人规模:一台笔记本、少量任务,不追求多 Agent 花哨编排或通用聊天界面。
  • Designed for personal scale: one laptop, a handful of tasks. No elaborate multi-agent choreography and no general chat UI.
  • 语义检索只保留可选接口,当前版本以关键词索引与结构化检索为主。
  • Semantic retrieval is an optional interface only; the current version relies on keyword indexing and structured lookup.
  • 模型是可换的:云端模型为主,本地模型留同一接口,能力上限由所选模型决定。
  • Models are swappable: cloud by default with the same interface for a local endpoint, and the ceiling is set by whichever model you pick.
  • 密钥不落仓库:所有凭据走环境变量或本地 .env,仓库里不含任何明文密钥。
  • No secrets in the repository: credentials come from environment variables or a local .env file.