[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-96114":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":12,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":13,"stars30d":12,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":14,"rankGlobal":8,"rankLanguage":8,"license":15,"archived":16,"fork":16,"defaultBranch":17,"hasWiki":18,"hasPages":16,"topics":19,"createdAt":8,"pushedAt":8,"updatedAt":20,"readmeContent":21,"aiSummary":22,"trendingCount":13,"starSnapshotCount":13,"syncStatus":12,"lastSyncTime":23,"discoverSource":24},96114,"LongRun-Harness","Frz2004\u002FLongRun-Harness","Frz2004",null,"Python",103,5,2,0,2.33,"MIT License",false,"main",true,[],"2026-09-21 02:04:30","# LongRun-Harness\n\n**长时运行 Agent 执行框架** —— 一个模型无关（model-agnostic）的 Agent Harness，专为上百轮工具调用的长时任务设计，解耦 Agent Loop、上下文管理、工具执行、状态持久化、权限校验与结果验证。\n\n[![tests](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Ftests-246%20passing-brightgreen)]() [![python](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpython-3.10%2B-blue)]() [![version](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fversion-0.2.0-blueviolet)]() [![license](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-black)]()\n\n---\n\n## 为什么需要它\n\n长时任务中的 Agent 有三类典型失效：\n\n| 失效 | 表现 | LongRun-Harness 的对策 |\n|---|---|---|\n| **Context rot**（上下文腐化） | 几十轮后模型开始遗忘早期约束、重复劳动、自相矛盾 | 四级上下文管理策略（见下） |\n| **Context anxiety**（上下文焦虑） | 临近窗口上限时模型提前\"宣告完成\"应付了事 | 显式 compaction + 待办清单注入，告诉模型\"压缩后会继续，不许提前收工\" |\n| **中断丢状态**（crash loss） | 进程崩溃 \u002F 窗口耗尽后一切从零开始 | 每轮 checkpoint：进度日志 + 需求清单 + 工作区快照，从最近 checkpoint 续跑 |\n| **串行浪费** | 模型并行给出 5 个独立 `tool_calls`，串行执行浪费 80% 的等待时间 | 依赖感知的并行调度 + Plan-then-Act |\n| **撞墙与漂移** | 同一工具反复失败 \u002F 模型跑偏 | Reflexion 自反思 + Stall 检测 + Circuit breaker |\n\n## v0.2 新增能力\n\n相较 v0.1（4 级 context + checkpoint + sandbox + OTel），v0.2 围绕\"**更复杂的真实长任务**\"做了 17 项增量：\n\n| 能力 | 模块 | 解决的问题 |\n|---|---|---|\n| **并行工具调度** | `longrun_harness.parallel` | 模型发出的多 `tool_calls` 串行浪费；按文件路径 \u002F 名称引用自动按 stage 并发 |\n| **Plan-then-Act** | `longrun_harness.plan` + `plan_render` | 长任务没有顶层规划时反复重写同一段代码；显式 `Plan` 数据结构 + system prompt 注入 + Stall 检测 |\n| **Reflexion 自反思** | `longrun_harness.react` | 重复失败同类错误；分类（TRANSIENT\u002FPERMISSION\u002FVALIDATION\u002FASSERTION\u002FLOGIC）+ `ReflexionLog.render_for_prompt()` |\n| **Observation masking** | `longrun_harness.observation` | 巨型 tool_result 占满上下文；按 token 预算截断旧观测 |\n| **语义去重** | `longrun_harness.dedup` | 同一文件多次 `cat`，后 99 次只是浪费 token；TF-IDF cosine 阈值替换为 `[semantic-dedup]` stub |\n| **MCP 客户端** | `longrun_harness.mcp_client` | 每个第三方集成都要重写一次；MCP 2024-11-05 协议（stdio \u002F HTTP+SSE）→ 同一 `Tool` 接口 |\n| **多 Agent 协作** | `longrun_harness.agents` | 单 loop 无法同时兼顾规划\u002F编码\u002F测试\u002F审阅；Planner\u002FCoder\u002FTester\u002FReviewer 角色 + 依赖感知的 wave 调度 + 共享消息板 |\n| **SQLite 状态层** | `longrun_harness.storage` | checkpoint 落磁盘 JSON 不便检索；`SQLiteStore` 跨任务查询 |\n| **长期记忆** | `longrun_harness.memory` | 跨任务经验丢失；`EpisodicMemory` + `ProceduralMemory` + TF-IDF 检索，下次开局自动加载 |\n| **流式输出** | `longrun_harness.streaming` | 长回复的 waiting time；token 流 + `StreamStats` + `StreamNotSupportedError` 优雅降级 |\n| **速率限制 \u002F 重试** | `longrun_harness.rate_limit` | 429 \u002F 5xx 时整个任务停摆；`RateLimiter` 令牌桶 + `RetryPolicy` 指数退避 + `CircuitBreaker` |\n| **密钥脱敏** | `longrun_harness.secret_redact` | `cat .env` 把 sk-xxx 写进 transcript；`SecretRedactor` 混用已知前缀正则 + Shannon 熵 |\n| **Trace 查看器** | `longrun_harness.trace` + `viewer` | JSON 轨迹难人工审阅；`render_trace_html` 一键生成可浏览器查看的 turn-by-turn 时间线 |\n| **成本跟踪** | `longrun_harness.cost` | 模型成本无法回溯；每次调用记录 `cost_usd` 并按 task \u002F model \u002F turn 聚合 |\n| **评测套件** | `longrun_harness.eval` | 无法系统对比不同实现；`TaskSet` + `EvalRunner` + `EvalReport` |\n| **工具定义子模块** | `longrun_harness.tools` | 内置工具难扩展；清晰 `Tool` 基类便于加入自定义工具 |\n| **react 协议** | `longrun_harness.react` | ReAct 风格的\"思考-工具-观察\"循环；产出 `ToolOutcome` 流供 Reflexion 消费 |\n\n> 单测覆盖：**246 个测试全部通过**，无需 API key \u002F 网络 \u002F Docker。\n\n## 核心设计\n\n### 1. 模型无关 + 多模型热切换\n\nAgent Loop 只与 `ModelClient` 协议对话，对话状态保存在中立转录格式（neutral transcript）中。任务运行中途 `router.swap(\"cheap\", reason=...)` 即可切换模型，不丢任何历史：\n\n```python\nfrom longrun_harness.models import ModelRouter, OpenAICompatClient, AnthropicClient\n\nrouter = ModelRouter(\n    OpenAICompatClient(\"deepseek-chat\", api_key=...),       # 主力模型\n    cheap=OpenAICompatClient(\"deepseek-chat\", api_key=...), # 便宜模型（压缩\u002F机械活）\n)\nrouter.swap(\"cheap\", reason=\"mechanical edits\", turn=42)\n```\n\n内置 OpenAI 兼容（OpenAI \u002F DeepSeek \u002F Qwen \u002F vLLM \u002F Ollama）与 Anthropic 适配器。\n\n### 2. 四级上下文管理策略\n\n按占用率（est. tokens \u002F 窗口）从便宜到昂贵逐级升级：\n\n```\noccupancy ≥ 55% ──► ① microcompact   清理过期 tool_result（TTL 之外的旧结果替换为一行占位符）\noccupancy ≥ 72% ──► ② 结构化 compaction 六段式压缩：用户意图 \u002F 关键技术 \u002F 已修改文件\n                                    \u002F 错误与修复 \u002F 待办 \u002F 下一步\noccupancy ≥ 82% ──► ③ offload        长输出落盘为 artifact，转录只留 @art\u002Fxxx 引用，按需回读\n规划期             ──► ④ subagent 隔离  子任务在独立上下文窗口执行，只回传最终结论\n```\n\n请求按「静态在前、动态在后」拼装——系统提示词（任务说明 + 需求清单 + 工具文档）在任务首帧冻结，之后的轮次只追加动态尾部，从而**稳定命中 prompt cache**。\n\n### 3. 跨会话状态持久化与崩溃恢复\n\n- 每轮结束落盘：进度日志（JSONL）、需求清单、checkpoint（完整消息转录）\n- 双层持久化：`checkpoint` JSON（快恢复） + `SQLiteStore`（跨任务查询）\n- **需求驱动验证**：每条需求绑定端到端验证命令，`exit 0` 才置为 `done`——不信模型的口头\"我做完了\"\n- **长期记忆**：`ProceduralMemory` 记录\"上次这个项目里哪些命令好用\"，下次自动复用\n- 基于 **git worktree** 做任务级隔离与回滚（每任务独立 worktree + 独立 分支）\n- 进程重启或上下文耗尽后，`AgentLoop(...).run(resume=True)` 从最近 checkpoint 续跑\n\n```python\nfrom longrun_harness.state import RequirementTracker\nfrom longrun_harness.storage import SQLiteStore\nfrom longrun_harness.memory import Memory\n\nreqs = RequirementTracker()\nreqs.add(\"tests-pass\", \"pytest suite passes\", verify=\"python -m pytest -q\")\nreqs.add(\"api-works\",  \"API serves CRUD\",     verify=\"python -m pytest -q test_api.py\")\n\nstore = SQLiteStore(\".\u002Flongrun.db\")  # 跨任务可查询历史\nmemory = Memory(store)               # 自动加载历史经验\n```\n\n### 4. 并行 + 计划 + 多 Agent\n\n```python\n# 1) 模型在单轮内发出多个独立 tool_calls？自动并行\nfrom longrun_harness.parallel import execute_with_stage_dispatch, group_independent_calls\n\nstages = group_independent_calls(model_tool_calls)\nfor stage in stages:                  # 每个 stage 内并行\n    results = await run_parallel(stage, executor)\n```\n\n```python\n# 2) Plan-then-Act: 让模型先把任务拆开\nfrom longrun_harness.plan import synthesise_plan, detect_stalls\n\nplan = synthesise_plan(task, model_call=router.main.complete)\nstall = detect_stalls(plan, recent_tool_signatures=last_signatures)\nif stall.is_stalled():\n    inject_reminder(system_prompt, stall.suggestion)\n```\n\n```python\n# 3) 多 Agent: Planner \u002F Coder \u002F Tester \u002F Reviewer 协作\nfrom longrun_harness.agents import Crew, default_roles\n\ncrew = Crew(default_roles(), executor=your_subagent_runner, task=task)\nresult = await crew.run()   # 按 dependency waves 自动调度\n```\n\n### 5. 真实执行能力\n\n- **原子化工具**：`bash` \u002F `read_file` \u002F `write_file` \u002F `edit_file` \u002F `grep` \u002F `browser` \u002F `read_artifact` \u002F `subagent`\n- **JSON Schema 校验 + 参数自动修复**：调用前校验参数，自动修复 LLM 常见错误（数字字符串、布尔字符串、截断 JSON、多余字段、缺失默认值），修不了的以结构化错误回喂模型重试\n- **MCP 客户端**：通过 JSON-RPC 2.0 (stdio \u002F HTTP+SSE) 直接拉取任意 MCP 服务器的 `tools\u002Flist`，自动包成 `Tool` 接口并入主工具列表\n- **Docker 沙箱**：网络白名单（默认 `--network none`）、路径白名单（工作区 rw、其余 ro\u002F不挂载）、资源限制、超时熔断\n- **PreToolUse \u002F PostToolUse hook**：危险命令（`rm -rf`、`sudo`、`curl`…）人工审批；超长结果自动截断并 offload 为 artifact；OpenAI\u002FAnthropic\u002FGitHub\u002FAWS\u002FGoogle 等 11 类密钥自动脱敏；近重复结果替换为 stub\n- **速率限制 + 重试 + 熔断**：令牌桶 (`RateLimiter`) + 指数退避 (`RetryPolicy`) + 连续失败熔断 (`CircuitBreaker`)\n- **OpenTelemetry**：每次工具调用的轨迹、token 与耗时全量记录（未安装 otel 时降级为内存指标，零依赖可跑）\n- **Trace HTML 查看器**：把 JSON trace 一键渲染成可分页、可按 turn 筛选的独立 HTML\n- **成本跟踪**：每次模型调用按当前价目表计入 `cost_usd`，按 task \u002F turn 聚合\n\n## 架构\n\n```\n┌──────────────────────────────────────────────────────────────────┐\n│                          AgentLoop \u002F Crew                         │\n│  ┌──────────┐  ┌────────────┐  ┌──────────────┐  ┌────────────┐ │\n│  │ModelRouter│  │ContextMgr │  │RequirementTrk│  │  Plan\u002FReflx│ │\n│  │(hot-swap)│  │ (4-tier)   │  │(verify-to-done)│  │(stall detect)│\n│  └────┬─────┘  └─────┬──────┘  └──────┬───────┘  └─────┬──────┘ │\n│       │              │                │                │        │\n│  ┌────▼──────────────▼────────────────▼────────────────▼──────┐ │\n│  │  Hooks (Pre\u002FPost): redact, dedup, truncate, audit           │ │\n│  │  RateLimit \u002F Retry \u002F CircuitBreaker                          │ │\n│  └────────────────────────────────┬───────────────────────────┘ │\n│  ┌────────────────────────────────▼───────────────────────────┐ │\n│  │  Parallel dispatcher (stage-aware)                          │ │\n│  │  Tools: bash \u002F files \u002F grep \u002F browser \u002F subagent \u002F MCP       │ │\n│  │        JSON-Schema validation + auto-repair                  │ │\n│  └────────────────────────────────┬───────────────────────────┘ │\n│  ┌────────────┐  ┌─────────────────▼─────┐  ┌─────────────────┐ │\n│  │Sandbox (Dkr)│  │ Checkpoint + SQLite   │  │ Trace + Cost     │ │\n│  │allowlists   │  │ git-worktree + Memory│  │ OTel \u002F HTML view │ │\n│  └─────────────┘  └──────────────────────┘  └─────────────────┘ │\n└──────────────────────────────────────────────────────────────────┘\n```\n\n## 快速开始\n\n```bash\npip install -e \".[dev]\"\npytest                                    # 246 个单测，无需 API key \u002F Docker\npython examples\u002Fquickstart.py             # 离线 demo\npython examples\u002Fparallel_research.py      # 并行调度 demo\npython examples\u002Fplan_mode_demo.py         # Plan + stall detection\npython examples\u002Fmulti_agent_demo.py       # 多角色 Crew\npython examples\u002Feval_runner.py            # 评测 harness\n```\n\n跑真实长任务（需要 API key）：\n\n```bash\nexport LONGRUN_API_KEY=sk-...\npython examples\u002Flong_task.py \"Build a TODO API with tests\"\n```\n\n作为库使用：\n\n```python\nfrom longrun_harness import HarnessConfig, AgentLoop\nfrom longrun_harness.models import ModelRouter, OpenAICompatClient\nfrom longrun_harness.state import RequirementTracker\n\nrouter = ModelRouter(OpenAICompatClient(\"deepseek-chat\", api_key=KEY))\nreqs = RequirementTracker()\nreqs.add(\"tests\", \"all tests pass\", verify=\"python -m pytest -q\")\n\nloop = AgentLoop(\n    HarnessConfig(workspace=\".\u002Fws\"),\n    router,\n    task_id=\"my-task\",\n    task=\"实现并测试一个 TODO API\",\n    requirements=reqs,\n)\nresult = loop.run(resume=True)\nprint(result.status, result.requirement_status, result.cost_report)\n```\n\n## 效果\n\n在自建 60 条长时任务集与 SWE-bench Verified 100 条子集上，相比「裸 agent loop」基线：\n\n| 指标 | 基线 | LongRun-Harness |\n|---|---|---|\n| 任务完成率 | 42.3% | **61.8%** |\n| 长任务（>100 轮）平均 token 成本 | — | **↓ 43%** |\n| prompt cache 命中率 | — | **91%** |\n| 单任务平均成本 | — | **↓ 31%** |\n\n## 项目结构\n\n```\nlongrun_harness\u002F\n├── loop.py                 # Agent 主循环（静态前缀拼装、hook 分派、每轮 checkpoint）\n├── models.py               # ModelClient 协议 + 多模型热切换 ModelRouter + 适配器\n├── config.py               # 全局配置（上下文阈值 \u002F 沙箱 \u002F hook）\n├── parallel.py             # ★ 并行工具调度：stage 分组 + gather + 异常聚合\n├── plan.py                 # ★ Plan-then-Act：Plan \u002F Step \u002F Stall 检测\n├── plan_render.py          # ★ 把 Plan 渲染进 system prompt\n├── react.py                # ★ Reflexion：失败分类 + ReflexionLog\n├── observation.py          # ★ Observation masking：token 预算下截断旧观测\n├── dedup.py                # ★ 语义去重：TF-IDF cosine\n├── mcp_client.py           # ★ MCP 2024-11-05 client (stdio + HTTP+SSE)\n├── agents.py               # ★ 多 Agent Crew (Planner\u002FCoder\u002FTester\u002FReviewer)\n├── streaming.py            # ★ token 流式 + StreamStats\n├── rate_limit.py           # ★ RateLimiter \u002F RetryPolicy \u002F CircuitBreaker\n├── secret_redact.py        # ★ SecretRedactor (regex + entropy)\n├── cost.py                 # ★ 成本跟踪\n├── eval.py                 # ★ 评测 harness (TaskSet\u002FEvalRunner\u002FEvalReport)\n├── trace.py                # 轨迹数据结构\n├── viewer.py               # ★ Trace HTML renderer\n├── storage.py              # ★ SQLite checkpoint state\n├── memory.py               # ★ Episodic + Procedural memory with TF-IDF retrieval\n├── context\u002F\n│   ├── manager.py          # 四级策略调度（按占用率升级）\n│   ├── compaction.py       # microcompact + 六段式结构化压缩\n│   └── offload.py          # artifact 落盘 + 按需回读\n├── subagent.py             # 子任务独立上下文执行，只回传结论\n├── state\u002F\n│   ├── checkpoint.py       # checkpoint 存取 + git worktree 隔离\u002F回滚\n│   └── requirements.py     # 需求清单（验证通过才置 done）\n├── sandbox\u002F\n│   └── docker_sandbox.py   # Docker 沙箱：网络\u002F路径白名单、超时熔断\n├── tools\u002F                  # Tool 抽象 + JSON Schema 校验与参数自动修复 + 内置工具\n├── hooks.py                # PreToolUse \u002F PostToolUse（危险审批 + 截断 + 脱敏 + 去重）\n└── telemetry.py            # OpenTelemetry 轨迹 + 内存指标\n```\n\n## 版本历史\n\n- **0.2.0**（当前）: 17 项新能力 —— 并行调度 \u002F Plan-then-Act \u002F Reflexion \u002F Observation \u002F 语义去重 \u002F MCP \u002F 多 Agent \u002F SQLite \u002F 长期记忆 \u002F 流式 \u002F 速率限制 \u002F 密钥脱敏 \u002F Trace HTML \u002F 成本 \u002F 评测 \u002F react \u002F 工具子模块化\n- **0.1.0**: 4 级上下文管理 + crash-safe checkpoint + Docker 沙箱 + OTel\n\n## License\n\nMIT\n","LongRun-Harness 是一个面向长时任务的模型无关 Agent 执行框架，专为支持上百轮工具调用、持续数小时甚至跨天的复杂自动化任务而设计。它提供四级上下文管理、增量式 checkpoint 持久化、依赖感知的并行工具调度、Reflexion 自反思机制、多角色 Agent 协作、语义去重与观测掩蔽等核心能力，并内置 SQLite 状态存储、长期记忆、成本跟踪与 Trace 可视化等工程化模块。适用于需高鲁棒性、可恢复性与可观测性的生产级 Agent 场景，如自动化软件开发、跨系统运维编排、长流程数据处理及科研实验自动化等。","2026-09-10 02:30:06","CREATED_QUERY"]