My Blog
← Back to home

Agent Company OS 上手指南

Agent Company OS 上手指南

版本:V1.0 | 快速上手 → 熟练掌握


一、这个系统是什么

一句话:你只管提任务,系统自动分配 Agent 执行,产出结果交给你验收。

你(Human)只做三件事:

提任务  →  审结果  →  做决策

剩下的:谁来做、什么时候做、怎么做、结果放哪,全部自动化。


二、系统架构(5 分钟理解)

┌──────────────────────────────────────────────┐
│  Human                                      │
│  $ hermes task create --goal "..."          │
└────────────────┬───────────────────────────┘
                 │ 写任务文件
                 ▼
┌──────────────────────────────────────────────┐
│  Hermes Core(CLI)                          │
│  任务 CRUD、状态查询、Agent 管理              │
└────────────────┬───────────────────────────┘
                 │ 轮询扫描
                 ▼
┌──────────────────────────────────────────────┐
│  Orchestrator(调度器)                       │
│  分配任务 → 写信号文件 → 监控心跳 → 回收结果    │
└────────┬───────────────────────┬─────────────┘
         │ 写 signals/{agent}/   │ 检测 outbox/
         │   current_task.json   │
         ▼                       ▼
┌─────────────────┐    ┌─────────────────────────────┐
│  tmux pane      │    │  outbox/{agent}/{task_id}/  │
│  (Runner 常驻)   │    │  summary.md + DONE          │
│                  │    │                             │
│  while true:     │    │  Orchestrator 检测到 DONE   │
│    检测信号文件   │    │  → 任务流转到 review        │
│    执行任务      │    └─────────────────────────────┘
│    写 outbox     │
└─────────────────┘

关键概念:

概念 说明
Task 一个任务,有 todo/doing/blocked/review/done 五种状态
Agent 一个执行者,有自己的 tmux pane、workspace、记忆目录
Signal 文件 signals/{agent}/current_task.json,Orchestrator 通知 Runner"有新任务"
outbox Agent 交付物目录,每个任务一个子目录,含 summary.md 和 DONE
.lock 文件 任务锁定信息,防止重复分配

三、前置准备

3.1 检查依赖

python hermes.py doctor

预期输出全部 [OK]

[OK] tmux installed
[OK] jq installed
[OK] claude CLI installed (2.1.105)
[OK] python dependencies (click, yaml, ulid, pytest)
[OK] directory structure complete
[OK] 1 agent registered (laohuang)

3.2 目录结构

agent-os-laohuang-self/
├── hermes.py              # CLI 入口
├── orchestrator.py        # 调度器(你需要单独启动)
├── lib/                   # 核心库
├── config/
│   ├── agents.yaml        # Agent 注册表
│   └── company.yaml       # 全局配置
├── runners/
│   ├── claude_runner.md   # Agent 执行模板
│   ├── render_prompt.py   # 模板渲染器
│   └── mock_runner.py     # E2E 测试用 mock
├── tasks/                 # 任务文件(按状态分目录)
│   ├── todo/              # 待执行
│   ├── doing/             # 执行中
│   ├── blocked/           # 被阻塞
│   ├── review/            # 待验收
│   └── done/              # 已完成
├── signals/               # Orchestrator → Runner 信号
│   └── {agent}/
│       └── current_task.json
├── outbox/                # Agent 交付物
│   └── {agent}/
│       └── {task_id}/
│           ├── summary.md
│           └── DONE
├── agents/                # Agent 身份和运行时状态
│   └── {agent}/
│       ├── profile.json
│       └── runtime.json
├── memory/                # Agent 记忆
├── logs/                  # 执行日志
└── company/
    └── AGENT_WORK_RULES.md

3.3 启动 Orchestrator

python orchestrator.py --poll-interval 5

后台运行(推荐):

python orchestrator.py --poll-interval 5 &

四、从简单到复杂示例

示例 1:最小闭环(1 分钟体验)

目标: 创建一个任务,看它自动从 todo → review。

步骤 1:创建任务

python hermes.py task create \
  --title "Hello World" \
  --owner laohuang \
  --goal "在 /tmp/hello_agent.py 写入: print('hello from agent company os')"

输出:

Created task: 01KQXXXXXXX
File: tasks/todo/01KQXXXXXXX.md

步骤 2:看 Orchestrator 自动 pickup

Orchestrator 每 5 秒扫描一次 todo 目录,发现任务后:

[INFO] Assigning task 01KQXXXXXXX to agent laohuang (pane: agent_laohuang)

任务从 tasks/todo/ 移动到 tasks/doing/,同时:

  • 创建 tasks/doing/01KQXXXXXXX.lock(锁定信息)
  • 创建 signals/laohuang/current_task.json(通知 Runner)
  • 更新 agents/laohuang/runtime.json(标记 busy)

步骤 3:Runner 执行(约 3 秒)

Runner pane 检测到信号文件后:

  1. 渲染 prompt 模板({{task_id}} → 实际值)
  2. 调用 claude 执行(或 mock_runner 无网时)
  3. 写入 outbox/laohuang/01KQXXXXXXX/summary.md
  4. 写入 outbox/laohuang/01KQXXXXXXX/DONE

步骤 4:Orchestrator 检测到 DONE,流转 review

[INFO] Task 01KQXXXXXXX completed by laohuang, moving to review

步骤 5:Human 验收

python hermes.py task show 01KQXXXXXXX
cat outbox/laohuang/01KQXXXXXXX/summary.md

验收通过后,手动移入 done:

python hermes.py task move 01KQXXXXXXX done

示例 2:并发多任务(理解调度)

同时提交 3 个任务,观察并发执行。

python hermes.py task create --title "任务A" --owner laohuang --goal "echo A > /tmp/task_a.txt"
python hermes.py task create --title "任务B" --owner laohuang --goal "echo B > /tmp/task_b.txt"
python hermes.py task create --title "任务C" --owner laohuang --goal "echo C > /tmp/task_c.txt"

观察 Orchestrator 行为:

# 初始状态:3 个 todo
$ python hermes.py task list
[TODO] 01KQ...AAA — 任务A (owner: laohuang)
[TODO] 01KQ...BBB — 任务B (owner: laohuang)
[TODO] 01KQ...CCC — 任务C (owner: laohuang)

Orchestrator 启动后顺序分配(因为只有 1 个 agent laohuang):

[INFO] Assigning task 01KQ...AAA to agent laohuang
[INFO] Task 01KQ...AAA completed, moving to review
[INFO] Assigning task 01KQ...BBB to agent laohuang
[INFO] Task 01KQ...BBB completed, moving to review
[INFO] Assigning task 01KQ...CCC to agent laohuang
[INFO] Task 01KQ...CCC completed, moving to review

注册第二个 Agent,测试真实并发:

python hermes.py agent register \
  --name market01 \
  --role marketing_writer \
  --capabilities "copywriting,seo" \
  --workspace-root /home/laohuang/projects

再同时提交 2 个任务:

python hermes.py task create --title "写文案" --owner laohuang --goal "echo 1"
python hermes.py task create --title "SEO文章" --owner market01 --goal "echo 2"

Orchestrator 会同时分配给两个 idle 的 agent(默认 max_concurrent=3)。


示例 3:任务失败与恢复(理解 blocked + recovery)

场景:Runner 执行超时 → 自动 blocked → 手动 retry。

步骤 1:制造一个超长任务(修改 mock_runner 的 sleep 时间,或创建一个执行时间很长的任务)。

步骤 2:观察超时(30 分钟,config/company.yaml 里的 task_timeout_seconds: 1800)。

步骤 3:超时后任务自动进入 blocked:

[WARNING] Task 01KQ...XXX timed out after 1800s, moving to blocked

步骤 4:Human 排查问题后重试:

python hermes.py task show 01KQ...XXX
# 查看 outbox/summary.md 分析失败原因
# 解决问题后:
python hermes.py task move 01KQ...XXX todo

步骤 5:Orchestrator 再次 pickup(recovery 机制保证 crash 后也能恢复)。


示例 4:真实 claude 执行(生产环境)

当前默认是 mock_runner(无网/E2E 测试用)。换到有网络的环境后:

步骤 1:确认 API Key 可用

export ANTHROPIC_API_KEY="sk-ant-..."
# 或
export ANTHROPIC_API_KEY="your-key-here"

步骤 2:修改 runner 脚本

编辑 runners/runner_{agent}.sh 中的 _run_claude() 函数:

_run_claude() {
    if curl -s --max-time 3 --fail "$API_ENDPOINT" > /dev/null 2>&1; then
        claude -p --system-prompt-file "$SIGNAL_DIR/rendered_prompt.md"
    else
        python3 "$MOCK_RUNNER" "$SIGNAL_DIR"  # ← 注释掉这行
    fi
}

或者直接注释掉整个 network check,强制走真实 runner:

_run_claude() {
    claude -p --system-prompt-file "$SIGNAL_DIR/rendered_prompt.md"
}

步骤 3:重建 Runner pane

tmux kill-window -t hermes:agent_laohuang
# Orchestrator 会在下次检测到 pane 不存在时自动重建

步骤 4:重启 Orchestrator

pkill -f orchestrator.py
python orchestrator.py --poll-interval 5 &

五、CLI 命令速查

# === 任务 ===
python hermes.py task create --title "标题" --owner laohuang --goal "做什么"
python hermes.py task list                  # 列出所有任务
python hermes.py task list --state todo     # 只看某种状态
python hermes.py task show <task_id>         # 详情
python hermes.py task move <task_id> review  # 流转状态
 
# === Agent ===
python hermes.py agent register --name market01 --role writer --capabilities "copywriting,seo"
python hermes.py agent list
python hermes.py agent status <name>         # 当前任务、状态
 
# === 系统 ===
python hermes.py doctor                      # 依赖检查
python hermes.py init                         # 初始化目录结构
 
# === Orchestrator ===
python orchestrator.py                        # 启动调度器
python orchestrator.py --dry-run              # 只看会做什么,不实际执行
python orchestrator.py --poll-interval 10    # 调整扫描间隔

六、任务文件格式

手动创建任务文件(替代 hermes task create):

<!-- tasks/todo/01KQXXXXXXXXXXXXXXXX.md -->
---
id: 01KQXXXXXXXXXXXXXXXX
title: 开发用户登录页
owner: laohuang
project: myapp
priority: P1
state: todo
created_at: 2026-04-27T10:00:00Z
---
 
## Goal
 
完成用户登录页开发,包括:
- 邮箱/密码输入框
- 登录按钮
- 错误提示
 
## Context
 
- 项目路径:/home/laohuang/projects/myapp
- 技术栈:Next.js 15, Tailwind CSS
- 参考:docs/design/login-v1.figma

七、信号文件格式

signals/laohuang/current_task.json(Orchestrator 写入,Runner 读取):

{
  "task_id": "01KQXXXXXXXXXXXXXXXX",
  "task_file": "/path/to/tasks/doing/01KQXXXXXXXXXXXXXXXX.md",
  "agent_name": "laohuang",
  "workspace_root": "/home/laohuang/projects",
  "project_path": "/home/laohuang/projects/myapp",
  "company_rules": "/path/to/company/AGENT_WORK_RULES.md",
  "memory_path": "/path/to/memory/laohuang",
  "logs_path": "/path/to/logs/laohuang",
  "outbox_path": "/path/to/outbox/laohuang/01KQXXXXXXXXXXXXXXXX",
  "assigned_at": "2026-04-27T10:05:00Z"
}

八、outbox 交付物格式

Agent 执行完成后,outbox/{agent}/{task_id}/ 下应有:

summary.md

# 任务交付总结
 
- 任务 ID:01KQXXXXXXXXXXXXXXXX
- 执行 Agent:laohuang
- 开始时间:2026-04-27T10:05:00Z
- 结束时间:2026-04-27T10:08:00Z
- 结果状态:✅ 成功
 
## 产出清单
 
| 文件 | 说明 |
|------|------|
| pages/login.tsx | 登录页组件 |
 
## 执行摘要
 
1. 阅读了任务文件和项目文档
2. 创建了 pages/login.tsx
3. 实现了邮箱/密码表单
4. 添加了错误提示逻辑
 
## 遇到的问题
 

DONE(空文件或单行文本):

done

九、调试技巧

看 Runner pane 在干什么

tmux attach -t hermes
# 或者只看特定 pane:
tmux capture-pane -t hermes:agent_laohuang -p -S -20

看 Orchestrator 日志

# 实时看 orchestrator 输出:
python orchestrator.py --poll-interval 5 2>&1 | grep -v "^$"
 
# 看 dry-run(不实际执行):
python orchestrator.py --dry-run --poll-interval 5

看信号文件

cat signals/laohuang/current_task.json | python -m json.tool

手动触发 Runner 执行

# 模拟 Runner 检测信号文件并执行:
python runners/mock_runner.py signals/laohuang

清理状态(重置实验环境)

# 清理所有状态,回到干净状态:
rm -rf tasks/doing/* tasks/blocked/* tasks/review/*
rm -rf signals/*/current_task.json
rm -rf outbox/*/*
# 重置 agent runtime:
for f in agents/*/runtime.json; do
  echo '{"status":"idle","current_task_id":null}' > "$f"
done

十、配置文件说明

config/agents.yaml

agents:
  - name: laohuang
    role: fullstack_engineer
    engine: claude-code
    capabilities:
      - frontend
      - backend
      - devops
    workspace_root: /home/laohuang/projects
  - name: market01
    role: marketing_writer
    engine: claude-code
    capabilities:
      - copywriting
      - seo
    workspace_root: /home/laohuang/projects

config/company.yaml

company:
  name: Hermes AI Company
  workspace_root: /home/laohuang/projects
  max_concurrent_agents: 3      # 同时最多分配几个 agent
  task_timeout_seconds: 1800     # 30 分钟超时
  poll_interval_seconds: 10     # 扫描间隔
  max_retries: 3               # blocked 后最多重试几次

十一、故障排查

问题 原因 解法
Orchestrator 启动报错 目录不存在 python hermes.py init
Agent 不 pickup 任务 agent runtime.json 显示 busy 检查 runner pane 是否卡住
outbox 目录是空的 Runner 没有执行 看 runner pane 输出
任务一直留在 doing DONE 文件没生成 检查 runner 是否报错
任务被重复 pickup .lock 文件丢失 hermes task move 重新流转
mock_runner 一直执行 网络不可达 检查 API key 和网络配置