# How To Build Your First AI Loop in 2026
**作者**: Rahul
**日期**: 2026-07-10T07:16:33.000Z
**来源**: [https://x.com/sairahul1/status/2075479271032942658](https://x.com/sairahul1/status/2075479271032942658)
---


Two of the most senior AI engineers alive said the same thing last month.
Peter Steinberger, creator of OpenClaw, now at OpenAI:
"You shouldn't be prompting coding agents anymore. You should be designing loops that prompt your agents."
Boris Cherny, head of Claude Code at Anthropic:
"I don't prompt Claude anymore. I have loops running that prompt Claude and figure out what to do. My job is to write loops."
Most people read that and thought: what does that actually mean?
And more importantly: how do I build one?
This article tells you exactly how.
No theory without code. No code without context. Real steps. Real commands. Copy and run.

Slate orchestrating GPT-5.6, Claude, and specialized subagents across a real migration task. The model got smarter. The bigger change is that tools like Slate can finally keep those models busy continuously instead of waiting for human prompts.
## The way most people use AI is already outdated
Write prompt. Wait. Read output. Fix it manually. Write another prompt.
You are the loop.
Every step runs through you. The AI waits. You decide. The AI waits again.
The moment you stop, everything stops.
The builders moving fastest in 2026 are not writing better prompts.
They are building systems that do the prompting for them.
The leverage point has moved.
From typing prompts → to designing loops.

## What changed with GPT-5.6?
GPT-5.6 doesn't change the need for loops.
It increases the value of them.
The better the model gets, the more expensive it becomes to leave it idle between prompts.
In terminal workflows, GPT-5.6 is noticeably better at:
→ understanding large codebases
→ maintaining implementation consistency
→ following multi-step plans
→ recovering from failed attempts
→ acting as a strict verifier
The result isn't "better prompting."
It's fewer human interventions per task.
## What a loop actually is
Simple definition:
A prompt answers once and stops.
A loop keeps working until the job is actually done.
Not until it generates an answer.
Until it reaches a verified outcome.
Every serious AI agent runs the same underlying cycle:
→ Discover — what needs doing?
→ Execute — do the work
→ Verify — did it actually work?
→ Iterate — not done? fix and repeat
→ Stop — condition met, or hard limit hit
Claude Code. Cursor. Codex.
Underneath, they all run this loop.
The difference between a prompt and a loop is not the model.
It is whether something checks the work and keeps going until it passes.

## The 4-condition test — run this before building anything
Most loops fail here.
A loop earns its setup cost only when all 4 conditions are true.
Miss one and the loop costs more than it returns.
1. The task repeats. At least weekly. A one-off task is still better served by one good prompt.
2. Verification is automated. Something must fail the work without you in the room. Tests. Linters. Builds. Type checks. No gate = the agent is grading its own homework.
3. Your token budget can absorb the waste. Loops re-read the full context on every iteration. They retry, explore, burn tokens whether or not the run ships anything. This is the cost nobody mentions.
4. "Done" is objective. A test that passes or fails. A build that compiles or doesn't. Not "when it looks good." If done requires a human opinion, keep it manual.
Pass all 4 → build the loop.
Fail any 1 → use a prompt instead.
The honest version: most developers don't need heavy loops yet. What everyone can use is a simple loop. We'll build one shortly.
## Install Slate
Slate is an AI coding agent built for exactly this — running long, parallel, multi-step tasks in your terminal.
Built by RandomLabs. The first agent built specifically for swarm orchestration.
What makes it different from Claude Code or Cursor:
→ Automatically selects the right model for each step. Plan with Claude, search with another, execute with Codex — Slate decides.
→ Runs parallel subagents simultaneously across your codebase
→ Manages its own context across long multi-hour sessions
→ Works alongside you — not just for you
Install it in one line:
```
npm i -g @randomlabs/slate
```
Navigate to your project and start it:
```
cd /path/to/your/project
slate
```
That opens the Slate TUI — a terminal interface where you give it tasks and watch it work.

## Step 1 — Set up your workspace
Before Slate can run loops on your project, it needs to understand your codebase.
Create an AGENTS.md file in your project root. This is the context Slate reads at the start of every session.
```
# AGENTS.md
## What this codebase does
[One paragraph description of the project]
## Architecture
- src/api/ — Express API routes
- src/services/ — Business logic
- src/db/ — Database models (PostgreSQL via Prisma)
- tests/ — Jest test suite
## Key commands
- npm test — run the full test suite
- npm run build — TypeScript compile
- npm run lint — ESLint check
- npm run typecheck — tsc --noEmit
## Rules
- Never modify src/billing/ or src/auth/ without human approval
- Always run tests before marking any task complete
- Use the existing error handling pattern in src/utils/errors.ts
## Environment
- .env.slate contains all env vars Slate needs
```
Slate reads this file automatically at startup — no need to paste it every session.
Add your workspace directories inside Slate:
```
/workspace add ./src
/workspace add ./tests
/workspace list
```
Or reference specific files inline using @ mentions:
```
Please review @src/api/routes.ts and suggest improvements
```

## Step 2 — Configure Slate
Create slate.json in your project root to control how Slate behaves.
```
{
"$schema": "https://randomlabs.ai/config.json",
"permission": {
"*": "allow",
"bash": "ask"
},
"models": {
"main": { "default": "anthropic/claude-opus-4.6" },
"subagent": { "default": "anthropic/claude-sonnet-4.6" },
"search": { "default": "anthropic/claude-haiku-4.5" },
"reasoning": { "default": "openai/gpt-5.6" }
}
}
```
What this does:
→ "*": "allow" — Slate can read and write files without asking each time
→ "bash": "ask" — Slate asks before running shell commands (keep this on until you trust it)
→ Models config — cheap fast model for search, expensive model for main reasoning
For CI or automation runs where you want zero prompts:
```
slate run "Run the test suite and fix any failures" --dangerously-skip-permissions --output-format stream-json
```
## Step 3 — Your first task (not a loop yet)
Before building a loop, get a single manual run reliable.
This is the most skipped step. And the reason most loops fail in production.
Give Slate a real task:
```
Please review the architecture of my entire codebase.
Create an ARCH.md with:
- current structure
- dependencies between modules
- 3 things to improve
Look at @src/ first, then @tests/
```
Watch Slate work. It will:
1. Search through your files
2. Build understanding of the architecture
3. Draft the ARCH.md
4. Review it against your request before stopping
This is already a mini-loop — it checks its own output before finishing.
For a longer task:
```
Hey Slate, research my codebase for the authentication flow,
then make a plan for adding OAuth2 support.
Make sure you look at @src/auth/ and @src/api/routes.ts
```
Slate returns a plan. You iterate on it:
```
No, don't add a new auth provider class.
Make it follow the same pattern as the existing ApiKeyAuth in src/auth/api-key.ts
```
Approve the plan. Slate executes autonomously.

## Step 4 — Create a Skill (make the loop reusable)
A Skill is how you stop re-explaining your project every session.
Write it once. Slate reads it on every relevant run.
Create the folder structure:
```
mkdir -p .slate/skills/ci-triage
touch .slate/skills/ci-triage/SKILL.md
```
Write the skill:
```
---
name: "ci-triage"
description: "Classify CI failures by root cause and draft fixes for the easy ones."
---
# CI Triage Skill
## What I do
When a CI run fails, I:
1. Read the test output
2. Classify the failure: env issue / flaky test / real bug / dependency bump / infra
3. Draft fixes for bugs and dependency issues
4. Escalate env and infra issues to humans
## Classification rules
- env: missing secret, wrong env var → flag for human
- flake: passes on retry without code change → retry once, then file issue
- bug: deterministic failure tied to recent commit → draft fix
- dependency: failure tied to version bump → draft rollback PR
- infra: timeout, OOM, runner issue → escalate immediately
## Fix patterns
- Auth test failures → check src/auth/middleware.ts first
- Database test failures → verify migration ran in CI env
- E2E failures → check UI selectors against latest snapshot
## Never do
- Disable failing tests
- Modify CI config without asking
- Touch src/billing/ or src/payments/
## State
Update STATE.md after every run:
- Files checked
- Classifications made
- PRs opened
- Items escalated
```
List available skills inside Slate:
```
/skills
```
Activate one manually:
```
@ci-triage please triage today's failing tests
```
Or Slate activates skills automatically when it decides they are relevant to the current task.
## Step 5 — Add state (the loop's memory)
The agent forgets.
The file does not.
Create STATE.md in your project root:
```
# Loop State — CI Triage
## Last run
2026-06-28 03:30 UTC — 7 failures classified, 3 fixes drafted, 4 escalated
## In progress
- claude/fix-auth-token-refresh — tests passing locally, awaiting CI
- claude/fix-flaky-payment-webhook — retry pattern applied, monitoring
## Completed
- claude/bump-axios-1.7.4 → merged (CI green)
- claude/lint-fix-pass-june-28 → merged
## Escalated to humans
- src/billing/refund.ts — tests failing in 3 ways, root cause unclear
- ci/staging-runner — infra timeouts, not a code issue
## Lessons learned
- 2026-06-27: PowerShell hits TLS 1.2 issue on this Windows runner. Use bash.
- 2026-06-26: tests/e2e/checkout requires Stripe webhook secret in env. Skip if missing.
```
Tell Slate to use it at the start of every session by adding to AGENTS.md:
```
## Session start
Always read STATE.md first. Pick up where the last run stopped.
Update STATE.md at the end of every run with what was done and what is next.
```
Without state: every run starts from zero.
With state: every run resumes and compounds on the last.
## Step 6 — Build the actual loop
Now you have:
→ Workspace set up (AGENTS.md)
→ Config set (slate.json)
→ One reliable manual run proven
→ A skill written (ci-triage)
→ State file created (STATE.md)
Time to wrap it into a real loop.
Option A: Queue file loop (simplest)
Create loop.md:
```
Read STATE.md to understand what was already tried.
Run the CI triage skill across all failing tests in the last build.
For each failure:
- Classify it using the ci-triage skill rules
- Draft a fix for bugs and dependency issues
- Escalate env and infra issues
Run the fixes. Check if tests pass.
If tests pass → open PR.
If tests still fail → record in STATE.md and stop.
Update STATE.md with everything done this run.
Hard stop: 8 attempts maximum. On limit, report current state.
```
Run it:
```
slate --queue loop.md
```
Slate reads the queue file and runs each block as a queued message.
Option B: Headless/CI loop (automated)
Run non-interactively in a GitHub Action or cron job:
```
slate run "$(cat loop.md)" --output-format stream-json --dangerously-skip-permissions
```
In a GitHub Actions workflow:
```
name: CI Triage Loop
on:
workflow_run:
workflows: ["CI"]
types: [completed]
jobs:
triage:
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Slate
run: npm i -g @randomlabs/slate
- name: Run triage loop
env:
SLATE_API_KEY: ${{ secrets.SLATE_API_KEY }}
run: |
slate run "$(cat loop.md)" \
--output-format stream-json \
--dangerously-skip-permissions \
--workspace ./src \
--workspace ./tests
```
Now every CI failure automatically triggers the triage loop.
No human needed until escalation.

## Step 7 — Add sub-agents (the maker-checker split)
The single most important structural improvement to any loop.
Never let the same agent grade its own homework.
The model that wrote the fix is too generous a grader.
In Slate, you can set different models for different roles:
```
{
"models": {
"main": { "default": "anthropic/claude-opus-4.6" },
"subagent": { "default": "anthropic/claude-sonnet-4.6" },
"search": { "default": "anthropic/claude-haiku-4.5" }
}
}
```
Then write your task so Slate uses this split naturally:
```
Please fix the failing auth tests.
Step 1: Have a search agent explore src/auth/ to understand the current implementation.
Step 2: Have a separate agent implement the fix based on what was found.
Step 3: Have a third agent verify the fix against the original test requirements —
this agent should NOT have seen the implementation.
Step 4: Only open the PR if the verifier approves.
```
Slate orchestrates the subagents automatically.
The search agent uses a fast cheap model. The implementation agent uses a stronger model. The verifier uses a strict model with no access to the maker's reasoning.
This split is why Slate can run 5 parallel subagents on a single task — each specialized, each isolated.

## Step 8 — The state loop pattern (for long-running tasks)
For tasks that run over hours or days, use this pattern in your task prompt:
```
You are running a multi-session loop.
GOAL: Migrate all Express routes to the new ApiError pattern.
Track progress in STATE.md.
START OF EVERY SESSION:
1. Read STATE.md
2. Find the first incomplete item in "Remaining routes"
3. Do that item only
END OF EVERY SESSION:
1. Move completed items to "Done routes" in STATE.md
2. Record any blockers in "Blockers"
3. Update "Last run" timestamp
4. Stop cleanly
STATE.md format:
---
## Done routes
- [x] /api/users (2026-06-27)
- [x] /api/auth/login (2026-06-28)
## Remaining routes
- [ ] /api/payments/checkout
- [ ] /api/payments/refund
- [ ] /api/admin/users
## Blockers
- /api/payments/refund — requires human review (touches billing logic)
## Last run
2026-06-28 14:30 UTC
---
HARD RULES:
- Never touch src/billing/ without human approval
- Always run tests after each route migration
- Stop after completing ONE route per session
```
Run this every morning:
```
slate --continue "$(cat loop.md)"
```
--continue picks up the most recent session instead of starting fresh.
Each day, one more route. STATE.md tracks everything.
The loop resumes exactly where it stopped.
## Step 9 — Custom commands for your most-used loops
Add custom slash commands to slate.json so your loops are always one keystroke away:
```
{
"command": {
"triage": {
"description": "Run CI triage loop",
"template": "Read STATE.md. Run the ci-triage skill on all failing tests. Update STATE.md when done.",
"agent": "build"
},
"review": {
"description": "Review a file for correctness",
"template": "Review @$ARGUMENTS for correctness, edge cases, and consistency with surrounding code."
},
"migrate": {
"description": "Migrate one route to ApiError pattern",
"template": "Read STATE.md. Migrate the next incomplete route to ApiError pattern. Run tests. Update STATE.md."
}
}
}
```
Now inside Slate:
```
/triage
/review src/api/payments.ts
/migrate
```
Each runs your pre-written loop prompt instantly.
## 3 complete loops you can run today
Loop 1: CI failure triage (the one we built)
When: every CI failure What: classify → fix easy ones → escalate hard ones → open PRs State: STATE.md Gate: tests pass Time to set up: 30 minutes
```
# trigger
slate run "$(cat loop.md)" --dangerously-skip-permissions --output-format stream-json
# or in GitHub Actions — see Step 6 above
```
Loop 2: Morning brief
When: 7am every weekday (cron job) What: scan last 24h of commits, PRs, and open issues → write a 5-bullet brief → post to Slack
```
# loop.md for morning brief
cat > morning-brief-loop.md << 'EOF'
Read the last 24 hours of:
- git log --since="24 hours ago" --oneline
- Open PRs in draft or review
- GitHub Issues opened or updated in the last 24h
Write a morning brief:
- 3 most important things that happened
- 2 things that need attention today
- 1 thing at risk of blocking someone
Keep it under 120 words. Post to the #engineering Slack channel.
EOF
# run on a schedule with cron
0 7 * * 1-5 slate run "$(cat morning-brief-loop.md)" --dangerously-skip-permissions
```
Loop 3: Dependency bump loop
When: every Monday What: scan for outdated packages → test compatibility → open PRs for safe bumps
```
cat > deps-loop.md << 'EOF'
Read STATE.md.
Run: npm outdated
For each outdated package:
1. Check if the version bump is major (breaking) or minor/patch (safe)
2. For minor/patch: update the package, run npm test
3. If tests pass: open a PR
4. If tests fail: record in STATE.md as "needs human review"
5. For major bumps: always escalate to humans
Hard rules:
- Never bump more than 5 packages in a single loop
- Never bump packages in the "peer dependencies" section
- Always run the full test suite after each bump, not just related tests
Update STATE.md with what was bumped and what was escalated.
EOF
# run every Monday
0 9 * * 1 slate run "$(cat deps-loop.md)" --dangerously-skip-permissions
```

# The failure modes that cost money
Know these before you schedule anything.
The Ralph Wiggum Loop
The agent declares done on a half-finished job.
Exits early. Loop keeps spending. Silently.
Fix: hard stop condition checked by a fresh model.
```
STOP CONDITION: All tests in tests/auth/ pass AND lint returns 0.
Verify using a separate check run, not the agent's own judgment.
Hard limit: 8 iterations. On limit: report state and stop.
```
Goal drift
On long sessions, early constraints disappear.
"Never touch src/billing/" from message 3 is gone by message 47.
Fix: add a VISION.md that Slate rereads at the start of every session.
```
# VISION.md — Read at start of every session
## Core goal
Migrate all Express routes to ApiError pattern.
## Hard constraints (never violate)
- Never touch src/billing/ without human approval
- Never disable failing tests
- Always run full test suite before opening any PR
## Current priority
Routes in src/api/payments/ — handle with extra care
```
Self-preferential bias
The maker grades its own homework. Always gives itself a pass.
Fix: verifier subagent with zero access to the maker's reasoning.
Tell Slate explicitly:
```
The verifier agent should NOT see the implementation agent's work.
It should only see: the original test requirements and the test output.
If tests pass → approve. If tests fail → reject. No opinion otherwise.
```
Agentic laziness
Loop calls a task "done enough" at partial completion.
Especially on vague success criteria.
Fix: objective stop condition only.
```
DONE WHEN: npm test returns exit code 0 AND npm run lint returns exit code 0.
Not when "tests look good." Not when "most tests pass."
Exit code 0 on both commands. That is the only done.
```
## The Slate-specific tricks that matter
A few things that make Slate different from other agents in practice.
Queuing messages while it works
Slate is running a long task. You think of something important.
Press Tab to queue the message — it runs after the current task finishes, not interrupting it.
```
[Slate is working on migration task...]
You: Actually, make sure the new pattern also handles the case where userId is null
[Tab — queued]
[Slate finishes current step, then reads your queued message]
```
Steering mid-run
If Slate is going in the wrong direction, you don't have to stop it:
```
[Slate is halfway through implementing the fix...]
You: Wait — don't add a new class for this. Use the existing BaseError in src/utils/errors.ts
[Enter — steers immediately]
Slate: Understood, switching approach to use BaseError...
```
Use /enter-mode-next to cycle between steer / queue / interrupt modes.
Shell commands directly
Run commands inside the Slate session without switching to another terminal:
```
!npm test # run tests and send output to Slate
!git diff HEAD # check what changed
!git status # see current state
```
Slate reads the output and uses it in its next action.
Server mode for team setups
Run Slate as a server and attach to it from multiple terminals:
```
# Terminal 1 — start server
slate serve --port 7777
# Terminal 2 — attach TUI
slate attach http://localhost:7777 --dir /path/to/project
```
Useful for pair-programming with Slate or running it on a remote machine.
## The full setup checklist
Before running your first real loop:
```
□ npm i -g @randomlabs/slate installed
□ AGENTS.md created with project overview, commands, rules
□ slate.json created with permissions and model config
□ One manual run completed and verified reliable
□ SKILL.md written for your first repeated task
□ STATE.md created and referenced in AGENTS.md
□ loop.md written with explicit stop condition
□ Hard limit on iterations (8 max to start)
□ Verifier is NOT the same agent as the maker
□ Human review gate on any irreversible action (PRs, deploys)
```
Check every box before scheduling anything.
Skip one and the loop either fails silently or bills you for nothing.
## For more loop inspiration
Once you understand the pattern, the bottleneck shifts from "how do I build a loop" to "what loop should I build next."
The Forward Future Loop Library at signals.forwardfuture.com/loop-library is a good place to browse real running loops across categories — content, engineering, operations, research.
When you see 20 working loops in one place, you stop thinking in one-off prompts.
## The uncomfortable truth
Two builders can run the exact same loop and get opposite results.
One uses it to move faster on work they already understand deeply.
The other uses it to avoid understanding the work at all.
The loop does not know the difference.
You do.
Loop design is harder than prompt engineering — not easier.
The point is not that the work got easier.
The leverage point moved.
Build the loop.
But build it like someone who intends to stay the engineer.
Not just the person who presses go.
And the new GPT-5.6 doesn't replace this principle. If anything, it reinforces it.
The frontier is no longer who writes the cleverest prompt.
It's who designs the best systems around increasingly capable models.
## The 60-second recap
What a loop is:
→ Prompt = question. Loop = job.
→ Discover → Execute → Verify → Iterate → Stop
The 4-condition test:
→ Task repeats / Verification automated / Budget absorbs waste / Done is objective
The 5 setup steps:
→ AGENTS.md → slate.json → one manual run → SKILL.md → STATE.md
Then wrap it:
→ loop.md queue file OR headless slate run in CI
The failure modes:
→ Ralph Wiggum (exits early) / Goal drift (forgets constraints) / Self-preferential bias (maker = checker) / Agentic laziness (done enough)
The Slate advantage:
→ Auto model selection per step → Parallel subagents with isolation → Long session management → Your loop, your design
## If this was useful:
→ Repost to share it with every builder you know
→ Follow @sairahul1 for more systems like this
→ Bookmark this — the setup checklist alone is worth saving
Subscribe to theaibuilders.co for more such interesting articles
I write about AI, building products, and systems that run while you sleep.
## Tools mentioned:
→ Programs by Slate: randomlabs.ai/s | @wearerandomlabs
→ Slate docs: docs.randomlabs.ai
→ Forward Future Loop Library: signals.forwardfuture.com/loop-library
## 相关链接
- [Rahul](https://x.com/sairahul1)
- [@sairahul1](https://x.com/sairahul1)
- [591K](https://x.com/sairahul1/status/2075479271032942658/analytics)
- [signals.forwardfuture.com/loop-library](https://signals.forwardfuture.com/loop-library)
- [@sairahul1](https://x.com/@sairahul1)
- [theaibuilders.co](https://theaibuilders.co/)
- [randomlabs.ai/s](https://randomlabs.ai/s)
- [@wearerandomlabs](https://x.com/@wearerandomlabs)
- [docs.randomlabs.ai](https://docs.randomlabs.ai/)
- [signals.forwardfuture.com/loop-library](https://signals.forwardfuture.com/loop-library)
- [Upgrade to Premium](https://x.com/i/premium_sign_up)
- [3:16 PM · Jul 10, 2026](https://x.com/sairahul1/status/2075479271032942658)
- [591.1K Views](https://x.com/sairahul1/status/2075479271032942658/analytics)
- [View quotes](https://x.com/sairahul1/status/2075479271032942658/quotes)
---
*导出时间: 2026/7/13 10:27:49*
---
## 中文翻译
# 如何在 2026 年构建你的第一个 AI 循环
**作者**: Rahul
**日期**: 2026-07-10T07:16:33.000Z
**来源**: [https://x.com/sairahul1/status/2075479271032942658](https://x.com/sairahul1/status/2075479271032942658)
---


上个月,两位最资深的 AI 工程师说了同样的话。
OpenClaw 的创造者,现任职于 OpenAI 的 Peter Steinberger:
“你不应该再手动去提示编码代理了。你应该设计能替你去提示代理的循环。”
Anthropic Claude Code 的负责人 Boris Cherny:
“我不再手动提示 Claude 了。我有正在运行的循环来提示 Claude 并弄清楚该做什么。我的工作是编写循环。”
大多数人读到这些想法:这到底意味着什么?
更重要的是:我该如何构建一个?
这篇文章将确切地告诉你如何做。
没有代码就没有理论。没有语境就没有代码。真实的步骤。真实的命令。复制并运行。

Slate 正在一个真实的迁移任务中编排 GPT-5.6、Claude 和专门的子代理。模型变得更聪明了。更大的变化在于,像 Slate 这样的工具终于能让这些模型持续忙碌,而不是等待人类的提示。
## 大多数人使用 AI 的方式已经过时了
写提示词。等待。阅读输出。手动修复。再写一个提示词。
你就是那个循环。
每一步都经过你。AI 等待。你决定。AI 再次等待。
当你停下的那一刻,一切都停止了。
在 2026 年行动最快的构建者们不是在写更好的提示词。
他们在构建能替他们去提示的系统。
杠杆点已经转移。
从输入提示词 → 转向设计循环。

## GPT-5.6 带来了什么变化?
GPT-5.6 并没有改变对循环的需求。
它增加了循环的价值。
模型越好,让它闲置在提示之间的代价就越昂贵。
在终端工作流中,GPT-5.6 在以下方面有明显优势:
→ 理解大型代码库
→ 保持实现的一致性
→ 遵循多步计划
→ 从失败的尝试中恢复
→ 充当严格的验证者
结果不是“更好的提示词”。
而是每个任务需要更少的人工干预。
## 循环到底是什么
简单的定义:
提示词回答一次就停止了。
循环会一直工作直到工作真正完成。
不是直到它生成一个答案。
直到它达到一个验证过的结果。
每一个严肃的 AI 代理都运行相同的底层循环:
→ 发现 — 需要做什么?
→ 执行 — 去做工作
→ 验证 — 真的起作用了吗?
→ 迭代 — 没做完?修复并重复
→ 停止 — 条件满足,或达到硬性限制
Claude Code。Cursor。Codex。
在底层,它们都运行这个循环。
提示词和循环的区别不在于模型。
而在于是否有东西检查工作并一直进行直到通过。

## 4 条件测试 —— 在构建任何东西之前先运行这个
大多数循环在这里失败了。
只有在所有 4 个条件都为真时,循环才值得其设置成本。
错过一个,循环的成本就高于其回报。
1. 任务会重复。至少每周一次。一次性任务用一个好的提示词仍然更好。
2. 验证是自动化的。必须有东西在没有你在场的情况下让工作失败。测试。Linter。构建。类型检查。没有关卡 = 代理在批改自己的家庭作业。
3. 你的 token 预算能承受这种浪费。循环在每次迭代时都会重读完整的上下文。它们会重试、探索、消耗 token,无论运行是否交付了任何东西。这是没人提及的成本。
4. “完成”是客观的。一个通过或失败的测试。一个编译成功或不成功的构建。而不是“当它看起来不错时”。如果完成需要人类意见,保持手动。
全部通过 4 条 → 构建循环。
任何 1 条失败 → 改用提示词。
诚实的版本:大多数开发者还不需要繁重的循环。每个人都能用的是简单的循环。我们马上就会构建一个。
## 安装 Slate
Slate 是一个专为此构建的 AI 编码代理 —— 在你的终端中运行长时间、并行、多步骤的任务。
由 RandomLabs 构建。第一个专门为群体编排构建的代理。
它区别于 Claude Code 或 Cursor 的地方在于:
→ 自动为每个步骤选择合适的模型。用 Claude 计划,用另一个搜索,用 Codex 执行 —— 由 Slate 决定。
→ 在你的代码库中同时运行并行子代理
→ 在长时间的多小时会话中管理自己的上下文
→ 与你一起工作 —— 而不仅仅是为你
用一行命令安装:
```
npm i -g @randomlabs/slate
```
导航到你的项目并启动它:
```
cd /path/to/your/project
slate
```
这会打开 Slate TUI —— 一个终端界面,你在那里给它任务并看着它工作。

## 步骤 1 —— 设置你的工作空间
在 Slate 能对你的项目运行循环之前,它需要理解你的代码库。
在你的项目根目录创建一个 AGENTS.md 文件。这是 Slate 在每次会话开始时读取的上下文。
```
# AGENTS.md
## 此代码库的作用
[项目的一段描述]
## 架构
- src/api/ — Express API 路由
- src/services/ — 业务逻辑
- src/db/ — 数据库模型(通过 Prisma 连接 PostgreSQL)
- tests/ — Jest 测试套件
## 关键命令
- npm test — 运行完整测试套件
- npm run build — TypeScript 编译
- npm run lint — ESLint 检查
- npm run typecheck — tsc --noEmit
## 规则
- 未经人工批准,永远不要修改 src/billing/ 或 src/auth/
- 在标记任何任务完成之前始终运行测试
- 使用 src/utils/errors.ts 中现有的错误处理模式
## 环境
- .env.slate 包含 Slate 需要的所有环境变量
```
Slate 在启动时自动读取此文件 —— 无需每次会话都粘贴。
在 Slate 中添加你的工作空间目录:
```
/workspace add ./src
/workspace add ./tests
/workspace list
```
或者使用 @ 提及内联引用特定文件:
```
Please review @src/api/routes.ts and suggest improvements
```

## 步骤 2 —— 配置 Slate
在你的项目根目录创建 slate.json 以控制 Slate 的行为。
```
{
"$schema": "https://randomlabs.ai/config.json",
"permission": {
"*": "allow",
"bash": "ask"
},
"models": {
"main": { "default": "anthropic/claude-opus-4.6" },
"subagent": { "default": "anthropic/claude-sonnet-4.6" },
"search": { "default": "anthropic/claude-haiku-4.5" },
"reasoning": { "default": "openai/gpt-5.6" }
}
}
```
它的作用:
→ "*": "allow" — Slate 可以读写文件无需每次都询问
→ "bash": "ask" — Slate 在运行 shell 命令前会询问(在你信任它之前保持开启)
→ 模型配置 —— 搜索使用廉价快速模型,主推理使用昂贵模型
对于你想要零提示的 CI 或自动化运行:
```
slate run "Run the test suite and fix any failures" --dangerously-skip-permissions --output-format stream-json
```
## 步骤 3 —— 你的第一个任务(还不是循环)
在构建循环之前,先让单次手动运行变得可靠。
这是最常被跳过的步骤。也是大多数循环在生产环境中失败的原因。
给 Slate 一个真实的任务:
```
Please review the architecture of my entire codebase.
Create an ARCH.md with:
- current structure
- dependencies between modules
- 3 things to improve
Look at @src/ first, then @tests/
```
观察 Slate 工作。它会:
1. 搜索你的文件
2. 构建对架构的理解
3. 起草 ARCH.md
4. 在停止之前根据你的请求进行审查
这已经是一个迷你循环 —— 它在完成之前检查自己的输出。
对于一个更长的任务:
```
Hey Slate, research my codebase for the authentication flow,
then make a plan for adding OAuth2 support.
Make sure you look at @src/auth/ and @src/api/routes.ts
```
Slate 返回一个计划。你进行迭代:
```
No, don't add a new auth provider class.
Make it follow the same pattern as the existing ApiKeyAuth in src/auth/api-key.ts
```
批准计划。Slate 自主执行。

## 步骤 4 —— 创建技能(让循环可重用)
技能是你停止每次会话重新解释项目的方式。
写一次。Slate 在每次相关运行时读取它。
创建文件夹结构:
```
mkdir -p .slate/skills/ci-triage
touch .slate/skills/ci-triage/SKILL.md
```
编写技能:
```
---
name: "ci-triage"
description: "Classify CI failures by root cause and draft fixes for the easy ones."
---
# CI Triage Skill
## What I do
When a CI run fails, I:
1. Read the test output
2. Classify the failure: env issue / flaky test / real bug / dependency bump / infra
3. Draft fixes for bugs and dependency issues
4. Escalate env and infra issues to humans
## Classification rules
- env: missing secret, wrong env var → flag for human
- flake: passes on retry without code change → retry once, then file issue
- bug: deterministic failure tied to recent commit → draft fix
- dependency: failure tied to version bump → draft rollback PR
- infra: timeout, OOM, runner issue → escalate immediately
## Fix patterns
- Auth test failures → check src/auth/middleware.ts first
- Database test failures → verify migration ran in CI env
- E2E failures → check UI selectors against latest snapshot
## Never do
- Disable failing tests
- Modify CI config without asking
- Touch src/billing/ or src/payments/
## State
Update STATE.md after every run:
- Files checked
- Classifications made
- PRs opened
- Items escalated
```
在 Slate 中列出可用技能:
```
/skills
```
手动激活一个:
```
@ci-triage please triage today's failing tests
```
或者当 Slate 决定它们与当前任务相关时自动激活技能。
## 步骤 5 —— 添加状态(循环的记忆)
代理会遗忘。
文件不会。
在你的项目根目录创建 STATE.md:
```
# Loop State — CI Triage
## Last run
2026-06-28 03:30 UTC — 7 failures classified, 3 fixes drafted, 4 escalated
## In progress
- claude/fix-auth-token-refresh — tests passing locally, awaiting CI
- claude/fix-flaky-payment-webhook — retry pattern applied, monitoring
## Completed
- claude/bump-axios-1.7.4 → merged (CI green)
- claude/lint-fix-pass-june-28 → merged
## Escalated to humans
- src/billing/refund.ts — tests failing in 3 ways, root cause unclear
- ci/staging-runner — infra timeouts, not a code issue
## Lessons learned
- 2026-06-27: PowerShell hits TLS 1.2 issue on this Windows runner. Use bash.
- 2026-06-26: tests/e2e/checkout requires Stripe webhook secret in env. Skip if missing.
```
通过添加到 AGENTS.md 告诉 Slate 在每次会话开始时使用它:
```
## Session start
Always read STATE.md first. Pick up where the last run stopped.
Update STATE.md at the end of every run with what was done and what is next.
```
没有状态:每次运行都从零开始。
有了状态:每次运行都会从上一次恢复并在此基础上叠加。
## 步骤 6 —— 构建真正的循环
现在你有了:
→ 设置好的工作空间 (AGENTS.md)
→ 设置好的配置 (slate.json)
→ 一个可靠的单次手动运行经验证
→ 编写好的技能
→ 创建好的状态文件 (STATE.md)
是时候把它包装成一个真正的循环了。
选项 A:队列文件循环(最简单)
创建 loop.md:
```
Read STATE.md to understand what was already tried.
Run the CI triage skill across all failing tests in the last build.
For each failure:
- Classify it using the ci-triage skill rules
- Draft a fix for bugs and dependency issues
- Escalate env and infra issues
Run the fixes. Check if tests pass.
If tests pass → open PR.
If tests still fail → record in STATE.md and stop.
Update STATE.md with everything done this run.
Hard stop: 8 attempts maximum. On limit, report current state.
```
运行它:
```
slate --queue loop.md
```
Slate 读取队列文件并将每个块作为排队消息运行。
选项 B:无头/CI 循环(自动化)
在 GitHub Action 或 cron 作业中非交互式运行:
```
slate run "$(cat loop.md)" --output-format stream-json --dangerously-skip-permissions
```
在 GitHub Actions 工作流中:
```
name: CI Triage Loop
on:
workflow_run:
workflows: ["CI"]
types: [completed]
jobs:
triage:
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Slate
run: npm i -g @randomlabs/slate
- name: Run triage loop
env:
SLATE_API_KEY: ${{ secrets.SLATE_API_KEY }}
run: |
slate run "$(cat loop.md)" \
--output-format stream-json \
--dangerously-skip-permissions \
--workspace ./src \
--workspace ./tests
```
现在每次 CI 失败都会自动触发分类循环。
直到升级才需要人工。

## 步骤 7 —— 添加子代理(制定者-检查者分离)
对任何循环最重要的结构性改进。
永远不要让同一个代理批改自己的家庭作业。
编写修复的模型太宽容了。
在 Slate 中,你可以为不同的角色设置不同的模型:
```
{
"models": {
"main": { "default": "anthropic/claude-opus-4.6" },
"subagent": { "default": "anthropic/claude-sonnet-4.6" },
"search": { "default": "anthropic/claude-haiku-4.5" }
}
}
```
然后编写你的任务,让 Slate 自然地使用这种分离:
```
Please fix the failing auth tests.
Step 1: Have a search agent explore src/auth/ to understand the current implementation.
Step 2: Have a separate agent implement the fix based on what was found.
Step 3: Have a third agent verify the fix against the original test requirements —
this agent should NOT have seen the implementation.
Step 4: Only open the PR if the verifier approves.
```
Slate 自动编排子代理。
搜索代理使用快速廉价模型。实现代理使用更强的模型。验证者使用严格的模型,无法访问制定者的推理。
这种分离就是 Slate 可以在单个任务上运行 5 个并行子代理的原因 —— 每个都是专门化的,每个都是隔离的。

## 步骤 8 —— 状态循环模式(用于长时间运行的任务)
对于运行数小时或数天的任务,在你的任务提示中使用此模式:
```
You are running a multi-session loop.
GOAL: Migrate all Express routes to the new ApiError pattern.
Track progress in STATE.md.
START OF EVERY SESSION:
1. Read STATE.md
2. Find the first incomplete item in "Remaining routes"
3. Do that item only
END OF EVERY SESSION:
1. Move completed items to "Done routes" in STATE.md
2. Record any blockers in "Blockers"
3. Update "Last run" timestamp
4. Stop cleanly
STATE.md format:
---
## Done routes
- [x] /api/users (2026-06-27)
- [x] /api/auth/login (2026-06-28)
## Remaining routes
- [ ] /api/payments/checkout
- [ ] /api/payments/refund
- [ ] /api/admin/users
## Blockers
- /api/payments/refund — requires human review (touches billing logic)
## Last run
2026-06-28 14:30 UTC
---
HARD RULES:
- Never touch src/billing/ without human approval
- Always run tests after each route migration
- Stop after completing ONE route per session
```
每天早上运行:
```
slate --continue "$(cat loop.md)"
```
--continue 接续最近的会话,而不是从头开始。
每一天,多一条路由。STATE.md 跟踪一切。
循环精确地从它停止的地方恢复。
## 步骤 9 —— 为你最常用的循环添加自定义命令
向 slate.json 添加自定义斜杠命令,让你的循环总是只需一次按键:
```
{
"command": {
"triage": {
"description": "Run CI triage loop",
"templat