0xfauzi/kstrl

GitHub: 0xfauzi/kstrl

kstrl 是一个为 AI 编程 agent 量身打造的自动化 harness,通过规格驱动、对抗性验证和结构化反馈循环,确保 agent 输出真正可运行的代码并自动生成可合并的 PR。

Stars: 0 | Forks: 0

kstrl mark: a hovering kestrel

kstrl

AI agents 编写代码。kstrl 确保它们真正能运行。

[![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/0xfauzi/kstrl/actions/workflows/ci.yml) [![PyPI](https://img.shields.io/pypi/v/kstrl)](https://pypi.org/project/kstrl/) [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](pyproject.toml) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) kstrl(发音同“kestrel”)是一个为 AI 编程 agents 量身打造的 harness。就像这种鸟一样,它通过悬停来狩猎:它牢牢锁定你的代码库,监控 agent 的一举一动,并在出现问题时精准出击。你只需把功能规格说明书交给它,然后就可以离开了。它会利用代码库上下文来引导 agent,通过结构化检查来验证输出,根据可操作的反馈进行重试,并从多次运行中的错误里不断学习。 它解决的核心问题是:AI 编程 agents 虽然强大,但它们每次只能处理一个 prompt。如果 agent 无法一次性完成,你就得手动重新输入 prompt、检查进度,并决定下一步尝试什么。而且,即使 agent 说“已完成”,也无法保证代码真的能运行。kstrl 自动化了外部循环——迭代、验证和改进——因此 agent 输出的是真正能工作的代码,而不仅仅是号称能运行的代码。此外,因为只有当你能看到它做了什么时,“离开后自动运行”的自动化才值得信任,所以每次运行都会输出一个 typed event log(类型化事件日志),你可以直接在终端仪表盘中实时观看、从另一个终端 attach(接入),或者在事后进行 replay(回放)。 ## kstrl 的不同之处 大多数 agent wrappers 只是重试循环:运行 agent,检查是否完成,若未完成则重试。kstrl 采用了 harness engineering(harness 工程)——结合了 feedforward 控制(在 agent 行动前进行引导)和 feedback 传感器(在 agent 行动后进行验证),以系统化地提升对 agent 输出的信心。 ``` flowchart LR Spec["Feature spec"] --> Context["Computed context
(no LLM)"] Context --> Agent["Implementing
agent"] Agent --> Gauntlet["Adversarial gauntlet
mechanical checks -> code review -> security review"] Gauntlet -->|"fail: structured feedback"| Agent Gauntlet -->|pass| PR["PR + merge"] PR --> Learn["Evolution journal"] Learn -.->|"harness improvements"| Context ``` 这种严苛考验(gauntlet)是核心所在:独立的对抗性 reviewer,其职责就是不信任执行任务的 agent;同时 harness 本身也不信任这些 reviewer(空的、部分的或过大的审查都会判定为 fail closed)。完整的阶段性 pipeline 及本 README 曾使用的所有图表,都可以在 [ARCHITECTURE.md](ARCHITECTURE.md) 中找到。 **文档**:[ARCHITECTURE.md](ARCHITECTURE.md) 是详细的系统导览(pipeline、迭代循环、factory 调度、状态布局),[docs/adversarial-design.md](docs/adversarial-design.md) 涵盖了完整的 8 种角色分类,[docs/env-vars.md](docs/env-vars.md) 介绍了每个环境变量,[docs/runbook.md](docs/runbook.md) 提供了运维故障恢复指南,[docs/linear-integration.md](docs/linear-integration.md) 介绍了可选的 Linear 镜像。[examples/](examples/) 包含一个配置好的 uv 项目和两个示例功能规格说明书。 ## 快速开始 从 PyPI 安装(或者 clone 源码用于开发): ``` uv tool install kstrl # installs `ks` and `kstrl` (requires Python 3.11+, uv) # 或:git clone https://github.com/0xfauzi/kstrl.git && cd kstrl && uv tool install -e . cd your-project ks init . # scaffold kstrl.toml and prompt/PRD templates $EDITOR scripts/kstrl/prd.json # define what to build (user stories + acceptance criteria) ks run 25 # let the agent work for up to 25 iterations ``` 每一个长时间运行的命令都会自动在终端打开其专属的实时仪表盘(使用 `--no-tui` 可关闭),直接输入 `ks` 会打开一个 home shell,包含运行浏览器和命令启动器;`ks dash` 可以让你从另一个终端对任何运行中(无论正在进行还是已完成)的任务接入只读视图;`ks status` 则为脚本和 CI 输出相同的状态(并且在你交互式运行它时会打开仪表盘)。 你至少需要一个 AI 编程 agent CLI: | Agent | 安装方式 | 示例模型 | |-------|---------|----------------| | Claude Code(推荐) | [claude.ai/code](https://claude.ai/code) | `opus`, `sonnet`, `haiku`, `claude-fable-5` | | OpenAI Codex | [github.com/openai/codex](https://github.com/openai/codex) | `gpt-5.5`, `gpt-5.4` | | Custom | 任何读取 stdin 的命令 | - | 模型名称更新于 2026 年 7 月:claude 别名追踪每个层级中的最新版本(今天是 Opus 4.8, Sonnet 5, Haiku 4.5),其中 `claude-fable-5` 是最前沿的旗舰模型,而 codex 默认使用 `gpt-5.5`(旧的 `gpt-5.x-codex` id 正在被逐步弃用)。 kstrl 不会验证模型名称:`[agent].model` 会直接传递给 CLI(`claude --model` / `codex -m`),因此任何已安装 CLI 接受的模型都可以工作。 此外还有一个可选的进程内 adapter,即 `[agent] type = "claude-sdk"`,它通过 [Claude Agent SDK](https://docs.claude.com/en/api/agent-sdk/overview) 驱动 Claude,而不是使用 CLI 子进程,并支持循环内的 USD 预算上限(`[agent].budget_usd`)。它需要安装 `sdk` extra(`uv sync --extra sdk`),且永远不会通过自动检测被选中。 **Python 优先**:kstrl 在使用 uv 管理的 Python 项目上表现最好。Feedforward 接口和依赖分析能够解析 Python(`ast` 和 import 语句),默认的验证命令是 `uv run pytest` / `uv run mypy` / `uv run ruff check`。其他技术栈可以通过覆盖 kstrl.toml 中的 `[verify]` 命令来运行,但它们获得的 feedforward 上下文会减少(仅包含模块映射和约定)。 ## 工作原理 ### 在 agent 行动前:计算得出的上下文 kstrl 会对代码库进行静态分析——模块映射、公开接口、依赖图、当前活跃的约定——并将其注入到 prompt 中。没有 LLM 调用,也没有 token 成本。在开始之前,agent 就能知道“这个项目使用 httpx,而不是 requests”,而不是在第 3 次迭代时才从 linter 报错中得知。 ### 在 agent 行动后:严苛的考验 当 agent 发出完成信号时,kstrl 不会仅仅选择相信它。每一次运行都要经过机械化的验证: - **机械化检查**(快速,计算性质):测试、typecheck、lint、不允许修改指定路径之外的文件、无泄漏的 secrets。 - **对抗性审查**(LLM):一位独立的 reviewer 会根据验收标准检查 diff,接着一位安全 reviewer 会寻找漏洞——在 `hard` 模式下,它们的判定失败会直接阻断流程。 - **契约测试**(多组件运行):组件分支逐层合并,并在每一层进行集成测试。 当验证失败时,kstrl 不会把原始的 stderr 直接塞进重试 prompt 中。它会将工具输出解析为结构化的失败信息,包含文件路径、源代码上下文和修复提示。以下是 typecheck 失败后,agent 获得的重试上下文示例: ``` [mypy] Found 1 error in 1 file (checked 14 source files) src/api/auth.py:23 [arg-type] Argument 1 to "verify_password" has incompatible type "str | None"; expected "str" | 21 | password = request.form.get("password") | 22 | user = get_user(username) | > 23 | if verify_password(password, user.password_hash): | 24 | return create_token(user) hint: Type mismatch in argument - convert or check the value before passing it. ``` ### 持续学习——harness 的自我提升 在每次 factory 运行之后,kstrl 会将结构化的失败特征记录到一个进化日志中。经过多次运行,它会识别出反复出现的模式,并提出 harness 改进建议——这些建议以 markdown 文件的形式供人类审查,绝不会进行悄无声息的自我修改。 ``` ks evolve # analyze recent runs, find patterns ks evolve --status # show experiment trends (retry rate over time) ``` 如果 agent 在不同组件中不断触发同一条 linter 规则,`ks evolve` 就会提议在 CLAUDE.md 中添加一条新约定。如果 Optional 类型上反复出现 typecheck 失败,它就会提议修改 mypy 配置。这些建议都会以 markdown 文件的形式提交给人类审查。 这就是所谓的元循环:kstrl 不仅仅是在重试——它会找出导致失败的原因,并更新自身的控制逻辑以防止问题再次发生。 ## Factory 模式——并行的多组件执行 对于大型功能,kstrl 会将规格说明书拆解为独立的组件,并并行运行它们: ``` kstrl decompose --spec features.md --project-name myproject kstrl factory --manifest scripts/kstrl/manifest.json --max-parallel 4 ``` 每个组件都在一个隔离的 git worktree(`.kstrl/worktrees//`)中运行,并拥有专属的 PRD。`ks run` 实际上就是只包含单个组件的 factory 模式——无论你是在构建一个功能还是二十个,运行的验证 pipeline 都是一样的。 关于调度、worktree 隔离、合并门控以及契约测试的二分查找,在 [ARCHITECTURE.md](ARCHITECTURE.md#factory-mode) 中都有图表展示。 ## Linear 集成——自动映射到你 tracker 中的 factory 启用镜像功能后,每一次 factory 运行都会自动出现在 Linear 中,而你完全不需要操心: ``` [linear] enabled = true team_id = "your-team-uuid" ``` ``` export KSTRL_LINEAR_TOKEN="lin_api_..." ``` `ks decompose` 会创建一个项目,并为每个组件生成一个 issue(用户故事作为 checklist 包含在 issue 内容中);非阻塞性质的规格分析结果会被归档到 Triage 中。状态流转直接依托于 Linear 自身的 GitHub 集成:组件分支携带 issue 标识符,而 PR 内容中带有 `Fixes ENG-42` 的 trailer,因此在开启 PR 时状态变为 In Progress,合并时变为 Done,这一切都不需要 kstrl 消耗任何 API 调用。失败和预算耗尽的情况会作为评论添加到 issue 中,重试操作则会更新同一个 issue——绝不会产生重复记录,因为 issue id 会持久保存在 manifest 中。 从设计上讲,该镜像仅用于可观测性目的:任何 Linear 的故障都会发出警告并优雅降级,pipeline 绝不会因为 Linear 的问题而中断。设置、各团队的自动化配置以及速率限制行为请参考:[docs/linear-integration.md](docs/linear-integration.md)。 ## TUI——完整的操作界面,而不仅仅是 factory kstrl 那些需要长时间运行的操作界面都可以通过终端 UI 访问。直接输入 `ks` 会打开 home shell:包含项目身份信息、一个涵盖所有类型已记录运行任务的浏览器(包含折叠的结果/token/成本摘要,以及在计算时诚实显示的 `·` 单元格),还有一个命令启动器——factory 和 decompose 直接从表单启动,retry 则可以从 manifest 中挑选失败的组件,config、evolve 以及初始化向导都会以全屏形式打开。非 TTY 环境下的调用与以前完全一致(`ks` 会打印帮助信息,并返回 exit code 2);设置 `KSTRL_NO_TUI=1` 则可以在全局禁用此功能。 kstrl home shell: project masthead, run browser across kinds, command launcher 每一个长时间运行的命令(`ks factory`, `ks run`, `ks retry`, `ks understand`, `ks feature`, `ks decompose`)都会记录可回放的事件流,并在终端上打开其内嵌的仪表盘;对于非 TTY 环境,纯文本输出依然是默认选项。这些截图都是真实的,截取自一个实时的玩具项目 factory 运行过程。 概览板会显示每个组件的状态、权威阶段、尝试次数、最后事件发生的时间以及开销——在这里,`auth-core` 和 `api-routes` 正在并行 worker 中运行,而 `ui-shell` 正在等待它的依赖: kstrl dashboard overview: component board with statuses, phases and cost meter 按下 `enter` 可以深入查看某个组件:阶段时间轴及其判定结果、带有审查模型归属信息的类型化分析结果流、实时的工程师对话记录,以及相关证据路径。 如果启用了 `pause_before_pr_merge`,E6 人工检查点就会作为一个真正的检查界面开启——展示 diff 片段、两个分析结果流以及本次尝试的消耗——而不是一个简单的 y/n 提示。`a` 表示批准,`r` 表示拒绝(判定组件失败并跳过依赖项),`t` 消耗一次重试机会,`escape` 则让它保持挂起状态,方便你在仪表盘里四处查看: kstrl E6 checkpoint modal: diff, findings and spend before approving the PR 快捷键:`enter` 查看详情,`escape` 返回,`f` 跟踪对话记录,`c` 重新打开检查点,`q` 退出(作为内嵌界面时为优雅退出;再按一次 `q` 则强制退出)。 TUI 只是一个视图,永远不是唯一的记录来源:每次运行都会将类型化的、带有 schema 版本信息的事件追加到 `.kstrl/runs//events.jsonl` 中,正因如此,在运行中途接入、回放已完成的运行,以及从仪表盘崩溃中恢复,这些功能从架构设计上就得到了保障([详情](ARCHITECTURE.md#the-event-stream-substrate))。成本数据由 CLI 自行汇报:任何未上报的调用都会标记一个 `+` 符号,此时的总计数字仅代表下限——仪表盘绝不会把一个真实的数据粉饰成虚假的完美数字。 ## 已批准的 fixtures——由你掌控的行为验证 Agent 生成的测试有时会被轻易写成无条件通过。已批准的 fixtures 则是在 PRD 中声明的输入/输出对,agent 编写的代码必须满足这些条件——它们在第一阶段的机械化验证期间运行,独立于项目自身的 pytest 之外,因此即便 conftest 被恶意篡改也无法取消选中这些测试。 Fixtures **默认是关闭的**。你可以在 kstrl.toml 中启用它们(除非 PRD 中包含一个 `fixtures` 数组,否则它们也不会起作用): ``` [fixtures] enabled = true ``` ``` { "branchName": "kstrl/auth", "fixtures": [ { "description": "Login returns token", "fixture_type": "cli", "input_data": {"command": "curl -s localhost:8000/api/login -d '{\"user\":\"test\"}'"}, "expected": {"exit_code": 0, "stdout_contains": ["token"]} } ], "userStories": [...] } ``` 共有三种 fixture 类型:`cli`(运行一个命令,检查输出)、`function`(导入并调用,检查返回值)、`file`(检查文件是否存在及内容)。Fixture 的定义由 LLM 生成,因此被视为不受信任的内容:命令会在经过净化的环境中脱离 shell 执行,函数会在沙盒子进程中运行,文件路径也无法跳出 worktree 目录——完整的安全处理机制和快照回归机制详见 [ARCHITECTURE.md](ARCHITECTURE.md#the-fixtures-sandbox)。请参阅下方配置参考中的 `[fixtures]` 键。 ## 为什么不直接使用 Claude Code? 你可以直接用,而且对于小任务来说你应该这么做。kstrl 适用于当你想要进行以下操作时: - **在开始前定义成功标准**——明确验收标准、路径限制——而不仅仅是“让它能跑就行” - **直接放手不管**——kstrl 依靠结构化验证进行无人值守运行,而不只是一个简单的完成标记 - **无需贴身看护即可监控进度**——通过实时仪表盘查看可回放的事件日志;随时接入、断开或事后审查 - **为 agent 提供上下文**——feedforward 注入意味着能减少为了解代码库而浪费的迭代次数 - **获得结构化的重试反馈**——解析出的失败信息包含源代码上下文和修复提示,而不是原始的 stderr - **并行构建多个组件**——支持 worktree 隔离和契约测试的 factory 模式 - **随着时间不断改进**——进化日志会跟踪错误模式,避免同样的错误反复出现 - **在构建之前对规格说明书进行红蓝对抗**——架构师阶段会在遇到阻断级别的规格歧义时停止,而不是靠瞎猜 ## CLI 参考 ``` ks autonomy demote Drop the autonomy level by one and start the cool-down. ks autonomy history Show every recorded level transition. ks autonomy promote Raise the autonomy level by one. ks autonomy replay Replay the ladder's thresholds over recorded run history. ks autonomy status Show the current level, its flag bundle, and what promotion needs. ks config show Print the fully resolved config with the source of each value. ks dash Live dashboard over a factory run (observe-only). ks decompose Decompose a spec into components and generate PRDs. ks evolve Analyze factory runs and propose harness improvements. ks factory Run the software factory - decompose and execute a spec. ks feature Run feature understanding, then implementation. ks inbox approve ITEM_ID Accept the exception and close the item. ks inbox ls List items awaiting a decision. ks inbox reject ITEM_ID Refuse the exception, recording why. ks inbox retry ITEM_ID Requeue the item's component and close the item. ks inbox show ITEM_ID Show one item in full, including its evidence. ks inbox snooze ITEM_ID Defer an item; it returns when the TTL lapses. ks init [DIRECTORY] Initialize kstrl in a project directory. ks retry COMPONENT_ID Retry a FAILED component from the factory manifest (R3.3). ks run [MAX_ITERATIONS] Run the agentic loop as a single-component factory invocation. ks status Show per-component status from the manifest + progress log. ks understand [MAX_ITERATIONS] Run codebase understanding loop (read-only mode). ``` 运行 `ks COMMAND --help` 可获取任何命令的完整选项列表。 ## 配置 kstrl 会读取项目根目录下的 `kstrl.toml`;复制 [kstrl.toml.example](kstrl.toml.example) 即可快速开始。优先级顺序:CLI flags > 环境变量 > kstrl.toml > 数据类默认值。`ks config show` 会打印出完全解析后的配置,并附带每个值的来源。 ## PRD PRD(`prd.json`)是一个包含可测试验收标准的用户故事列表: ``` { "branchName": "kstrl/login-feature", "allowedPaths": ["src/", "tests/"], "userStories": [ { "id": "US-001", "title": "User can log in with email", "acceptanceCriteria": [ "Login form accepts email and password", "Invalid credentials show error message", "Tests pass: uv run pytest tests/test_auth.py" ], "priority": 1, "passes": false, "notes": "" } ] } ``` Agent 会在工作过程中更新 `passes` 和 `notes`。kstrl 会在各次迭代之间读取这些信息,以决定是否继续。验收标准应当具体且可测试——也就是 agent 能够运行的命令,或它能够验证的行为。 `allowedPaths` 对于手写的 PRD 是可选的(它用于第一阶段的 diff 范围检查);但对于架构师来说,每个被拆解的组件都必须包含它。 ## 架构 详细的系统导览——包括完整的 pipeline 图表、迭代生命周期、factory 调度、事件流底层机制、运行时状态布局以及 fixtures 沙箱——都可以在 [ARCHITECTURE.md](ARCHITECTURE.md) 中找到。对抗性角色分类和设计准则详见 [docs/adversarial-design.md](docs/adversarial-design.md)。 ## 开发 ``` git clone https://github.com/0xfauzi/kstrl.git cd kstrl uv sync uv tool install -e . uv run pytest tests/ # 1777 tests collected at the time of writing (2026-07) uv run mypy kstrl/ --strict uv run ruff check kstrl/ tests/ ``` 本 README 中的 CLI 参考和配置参考部分是自动生成的:修改源码(click 命令 / config 数据类)或 `scripts/gen_docs.py`,然后运行 `uv run python scripts/gen_docs.py`。如果生成的部分已过期,CI 将会报错失败。 ## 贡献 欢迎各种形式的贡献,也包括 AI 辅助的贡献——但由于 AI 生成的代码绝不能仅由 AI 自我审查来决定是否合格,因此每一项修改都必须经过人工审查,并且 PR 应当声明是否由 agent 编写。请从 [CONTRIBUTING.md](CONTRIBUTING.md) 开始了解项目配置、流程规则以及如何推进路线图上的工作;[项目 wiki](https://github.com/0xfauzi/kstrl/wiki) 深入涵盖了项目的愿景、架构和路线图。如需报告漏洞,请参阅 [SECURITY.md](SECURITY.md)。版本发布历史记录在 [CHANGELOG.md](CHANGELOG.md) 中。 ## 许可证 MIT
标签:AI代理, Python, SOC Prime, 代码验证, 开发工具, 无后门, 逆向工具