-
Notifications
You must be signed in to change notification settings - Fork 0
PRD
版本: v1.1 日期: 2026-04-10 状态: 已确认 作者: BOSS
Catown — AI 软件工厂。输入原始需求,输出可发布的产品。全流程自动化,人可在必要时介入。
公司 BOSS / 技术管理者,管理多个 AI Agent 协作完成软件项目开发。
- 自动化:从原始需求到可发布产品,端到端自动化
- 可观测:BOSS 能实时看到 Agent 在做什么、在讨论什么
- 可介入:任意阶段可以暂停、审批、打回、直接发指令
- 可配置:LLM 模型、Pipeline 流程、Agent 角色全部可配置
| 能力 | OpenClaw | AutoGen / CrewAI | Catown |
|---|---|---|---|
| Agent 间实时消息 | ❌ 无 | ✅ 轻量 + 可观测 | |
| 软件开发流程 | ❌ 通用 | ✅ 内置流水线 | |
| 人工介入 | ❌ 无概念 | ✅ Web UI 原生支持 | |
| 产出物管理 | ❌ | ✅ 项目 workspace | |
| 部署复杂度 | 低 | 高 | 低(单进程 Docker) |
| 定位 | 个人 AI 助手 | 多 Agent 框架 | AI 软件工厂 |
关键差异:
- vs OpenClaw:OpenClaw 不支持 Agent 间实时消息,极大限制了 Agent 交互
- vs AutoGen/CrewAI:这些方案偏重且通用,Catown 只聚焦软件开发流程
作为 BOSS,我提交一段原始需求(如「做一个用户管理系统,支持注册登录、权限管理」),系统自动完成需求分析 → 架构设计 → 开发 → 测试 → 发布的全流程。
作为 BOSS,我可以在 Pipeline 运行时看到每个 Agent 的实时输出,在需求分析完成后审批是否进入架构设计,发现问题时可以打回重做。
作为 Developer Agent,在开发过程中遇到接口定义不清晰时,我可以直接给 Architect Agent 发消息询问,而不是等用户来转达。
作为 BOSS,我可以为不同 Agent 配置不同的 LLM 模型(分析用便宜模型,开发用强模型),也可以自定义 Pipeline 的阶段顺序。
Pipeline 由 5 个专业 Agent + 1 个人角色组成:
| # | 角色名称 | 角色 | 职责 | 输入 | 输出 |
|---|---|---|---|---|---|
| 1 | analyst |
需求分析师 | 理解原始需求,输出结构化 PRD | 用户原始需求文本 | PRD.md |
| 2 | architect |
架构师 | 技术选型、架构设计、可行性评估 | PRD.md | tech-spec.md |
| 3 | developer |
开发工程师 | 编写代码、单元测试 | tech-spec.md | src/ 目录 |
| 4 | tester |
测试工程师 | 测试执行、bug 发现、报告 | src/ + PRD.md | reports/tests/--.md |
| 5 | release |
发布经理 | 版本管理、changelog、发布 | reports/tests/ + src/ | CHANGELOG.md, Git tag |
| 6 | assistant |
助理 | 打杂:协助其他 Agent、处理杂项任务 | 任意 | 视任务而定 |
| — | PM (人) | BOSS | 审批、介入、打回、发指令 | 任意阶段 | 审批结果 / 指令 |
每个 Agent 的运行时配置默认存储在 ${CATOWN_HOME}/config/agents.json,源码模板位于 backend/configs/agents.json。配置结构采用三层:灵魂 → 角色 → 规则。
当前问题:现有 system_prompt 是一段静态扁平文本,只有职责和规则,没有个性、价值观、沟通风格。各 Agent 辨识度低,读起来像岗位说明书。
改进方案:将 system_prompt 拆解为结构化的 SOUL 体系,由引擎动态组装:
{
"developer": {
"name": "Dev",
"soul": {
"identity": "一个注重代码质量的资深工程师,信奉'代码是写给人看的,顺便让机器执行'",
"values": ["可读性优先于聪明", "测试覆盖是底线", "遇到不确定的先问再写"],
"style": "说话简洁,技术问题不废话,给出代码示例比文字解释更高效",
"quirks": "对命名有强迫症,看到不规范的变量名会忍不住改掉"
},
"role": {
"title": "开发工程师",
"responsibilities": ["基于 tech-spec 编写代码", "编写单元测试", "用 execute_code 验证"],
"rules": ["代码写到 src/", "测试写到 tests/", "遇到接口歧义问 architect"]
},
"tools": ["read_file", "write_file", "list_files", "execute_code", "search_files", "retrieve_memory"],
"skills": ["code-generation", "unit-testing", "refactoring", "knowledge-graph"],
"provider": { "baseUrl": "...", "apiKey": "...", "models": [...] },
"default_model": "gpt-4"
}
}Prompt 组装逻辑(引擎动态生成):
def build_system_prompt(agent_config, project_memory="", long_term_memory=""):
parts = []
soul = agent_config["soul"]
# 1. 灵魂层:身份、价值观、风格
parts.append(f"你是 {agent_config['name']}。{soul['identity']}")
parts.append("你的原则:\n" + "\n".join(f"- {v}" for v in soul["values"]))
parts.append(f"沟通风格:{soul['style']}")
# 2. 角色层:职责
role = agent_config["role"]
parts.append("## 职责\n" + "\n".join(f"- {r}" for r in role["responsibilities"]))
# 3. 规则层
parts.append("## 规则\n" + "\n".join(f"- {r}" for r in role["rules"]))
# 4. 项目记忆注入
if project_memory:
parts.append(f"## 项目上下文\n{project_memory}")
# 5. 长期记忆注入
if long_term_memory:
parts.append(f"## 你的经验\n{long_term_memory}")
return "\n\n".join(parts)生成的 system_prompt 示例:
你是 Dev。一个注重代码质量的资深工程师,信奉"代码是写给人看的,顺便让机器执行"。
你的原则:
- 可读性优先于聪明
- 测试覆盖是底线
- 遇到不确定的先问再写
沟通风格:说话简洁,技术问题不废话,给出代码示例比文字解释更高效。
## 职责
- 基于 tech-spec 编写代码
- 编写单元测试
- 用 execute_code 验证代码
## 规则
- 代码写到 src/ 目录
- 测试写到 tests/ 目录
- 遇到接口歧义问 architect
## 项目上下文
[从项目记忆注入的关键决策和约定]
## 你的经验
[从长期记忆注入的通用模式和教训]
配置字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | Agent 显示名 |
soul.identity |
string | 一句话定义 Agent 是谁、信奉什么 |
soul.values |
string[] | 行为原则,决定 Agent 的决策优先级 |
soul.style |
string | 沟通风格(简洁/详细/严谨/幽默) |
soul.quirks |
string | 个性特征,增加辨识度(可选) |
role.title |
string | 角色头衔 |
role.responsibilities |
string[] | 职责列表 |
role.rules |
string[] | 硬性规则 |
tools |
string[] | 白名单工具(见 §4.5) |
skills |
string[] | 白名单技能(见 §4.5) |
provider |
object | LLM 配置(见 §10) |
default_model |
string | 默认模型 |
SOUL 的价值:
- 辨识度:BOSS 看输出能感受到不同"人"在做事
- 记忆注入点:长期记忆的内容直接影响 Agent 行为,而不只是被动检索
- 可调性:BOSS 调整 soul 配置即可改变 Agent 风格,不动职责和规则
- 可扩展:未来可以支持 BOSS 在 Web UI 中编辑 Agent 个性
| Agent | 可用工具 |
|---|---|
| analyst | web_search, web_fetch, retrieve_memory, read_file, write_file, list_files, execute_code, send_direct_message, consult_agent |
| architect | web_search, web_fetch, retrieve_memory, read_file, write_file, list_files, execute_code, send_direct_message, consult_agent |
| developer | web_search, web_fetch, retrieve_memory, read_file, write_file, list_files, execute_code, search_files, send_direct_message, consult_agent |
| tester | web_fetch, retrieve_memory, read_file, execute_code, list_files, search_files, send_direct_message, consult_agent |
| release | web_fetch, retrieve_memory, read_file, write_file, list_files, execute_code, send_direct_message, consult_agent, github_manager |
| assistant | web_search, web_fetch, retrieve_memory, read_file, write_file, list_files, execute_code, search_files, send_direct_message, consult_agent |
- 可在
agents.json中新增 Agent 角色(如security_auditor) - 可在
pipelines.json中引用新角色 - Agent 的 system_prompt 和工具配置完全独立
每个 Agent 仅能调用其配置中声明的工具和技能。 工具访问不是全局共享的,而是严格的白名单控制。
| 维度 | 说明 |
|---|---|
| 工具声明 | 在 agents.json 的 tools 数组中明确定义 |
| 运行时检查 | 每次工具调用前,引擎验证 Agent 是否有权使用该工具 |
| 拒绝策略 | 无权调用时返回明确错误,不静默忽略 |
| 动态调整 | 修改 agents.json 后热加载,无需重启 |
工具白名单示例:
{
"analyst": {
"tools": ["web_search", "web_fetch", "read_file", "write_file", "list_files", "execute_code", "retrieve_memory", "send_direct_message", "consult_agent"],
"skills": ["document-analysis", "requirement-decomposition", "user-story-writing"]
},
"developer": {
"tools": ["web_search", "web_fetch", "read_file", "write_file", "list_files", "execute_code", "search_files", "retrieve_memory", "send_direct_message", "consult_agent"],
"skills": ["code-generation", "unit-testing", "refactoring", "debugging"]
},
"release": {
"tools": ["read_file", "write_file", "list_files", "execute_code", "retrieve_memory", "send_direct_message", "consult_agent", "github_manager"],
"skills": ["changelog-generation", "version-tagging", "release-management"]
}
}临时授权机制:
当 Agent 需要使用白名单之外的工具时(例如 developer 在编码时需要 web_search 查阅 API 文档),Agent 可主动发起临时授权请求:
Agent 需要 web_search,但不在白名单中
│
├── Agent 发送授权请求(含理由)
│ │
│ ├── 请求格式:
│ │ "需要临时使用 web_search 查询 FastAPI WebSocket 文档,
│ │ 当前 tech-spec.md 中的实现方案需要补充细节。"
│ │
│ └── 前端弹出交互卡片:
│ ┌──────────────────────────────────────┐
│ │ 🔐 developer 请求临时授权 │
│ │ 工具: web_search │
│ │ 理由: 查询 FastAPI WebSocket 文档 │
│ │ │
│ │ [✅ 本次允许] [🔄 本阶段允许] [❌ 拒绝] │
│ └──────────────────────────────────────┘
│
├── BOSS 审批:
│ ├── 本次允许 → 单次调用授权,不改变白名单
│ ├── 本阶段允许 → 在当前 Stage 内加入白名单,Stage 结束后移除
│ └── 拒绝 → Agent 收到拒绝通知,调整方案
│
└── 记录审计: 所有授权请求和审批结果写入 audit_logs
Skills 体系:
Skills 是 Agent 能力的高层封装。每个 Skill 定义了一种专业行为模式,由指令片段(注入 system prompt)和依赖工具组成。Agent 配置中声明的 skills 决定了它的行为风格和可用能力边界。
配置文件:configs/skills.json。采用三级渐进式披露,按需注入,避免 token 浪费。
{
"code-generation": {
"name": "代码生成",
"description": "根据技术规范生成高质量代码",
"required_tools": ["read_file", "write_file", "list_files"],
"category": "development",
"levels": {
"hint": "代码生成: 遵循项目风格,函数须有 docstring,代码写 src/",
"guide": "## 代码生成规范\n- 遵循项目已有代码风格和约定\n- 每个函数必须有 docstring\n- 写代码前先 read_file 了解现有结构\n- 代码写入 src/ 目录,测试写入 tests/ 目录",
"full": "## 代码生成完整指南\n\n### 流程\n1. 先 read_file 了解项目结构\n2. 设计函数签名\n3. 实现代码,每个函数必须有 docstring\n4. 写完后 execute_code 验证\n\n### 命名约定\n- snake_case / PascalCase / UPPER_SNAKE_CASE\n\n### 代码审查清单\n- [ ] 函数 < 50 行\n- [ ] 无硬编码配置\n- [ ] 错误处理完善"
}
}
}| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | Skill 显示名 |
description |
string | 一句话说明 Skill 做什么 |
required_tools |
string[] | 该 Skill 依赖的工具列表 |
category |
string | 分类标签 |
levels.hint |
string | 一句话能力提示,始终注入 system prompt(~30 token) |
levels.guide |
string | 核心用法指引,stage 激活时注入(~150 token) |
levels.full |
string | 完整文档,写入文件系统按需读取(~800 token) |
三级注入策略:
| 层级 | 注入时机 | Token/技能 | 用途 |
|---|---|---|---|
hint |
始终注入 system prompt | ~30 | Agent 知道自己"能做什么" |
guide |
Agent 进入对应 stage 时注入 | ~150 | 指导"怎么做" |
full |
Agent 自主 read_file 读取 |
~800 | 深度参考,按需查阅 |
1. 三级 Prompt 注入
引擎根据 pipeline stage 配置决定注入 hint 还是 guide:
def build_system_prompt(agent_config, skill_configs, stage_config=None):
parts = []
# ... 灵魂层、角色层、规则层(见 §4.2)...
# hint — 始终注入(轻量)
hints = []
for skill_name in agent_config.get("skills", []):
skill = skill_configs.get(skill_name)
if skill and "hint" in skill.get("levels", {}):
hints.append(skill["levels"]["hint"])
if hints:
parts.append("## 可用技能\n" + "\n".join(f"- {h}" for h in hints))
# guide — 仅当前 stage 的 active_skills 注入
if stage_config and stage_config.get("active_skills"):
guides = []
for skill_name in stage_config["active_skills"]:
skill = skill_configs.get(skill_name)
if skill and "guide" in skill.get("levels", {}):
guides.append(skill["levels"]["guide"])
if guides:
parts.append("\n\n".join(guides))
# ... 项目记忆、长期记忆 ...
return "\n\n".join(parts)2. Full 层存储与读取
full 内容不注入 system prompt,引擎在 Pipeline 启动时写入项目 workspace:
projects/{project_id}/
└── .catown/
└── skills/
├── code-generation.md
├── unit-testing.md
└── ...
Agent 需要深入时通过 read_file 按需读取。
3. Pipeline stage 技能绑定
pipelines.json 的 stage 配置控制哪些 skill 注入 guide 层:
{
"name": "development",
"agent": "developer",
"active_skills": ["code-generation", "unit-testing", "refactoring"],
"hint_only_skills": ["knowledge-graph", "debugging"]
}| 字段 | 行为 |
|---|---|
active_skills |
注入 guide 层到 system prompt |
hint_only_skills |
只保留 hint
|
| 未列出的 skill | 不注入任何内容 |
4. 工具访问联动
Skills 声明的 required_tools 不直接授予工具权限,而是作为参考依据:
- Agent 的工具白名单仍由
agents.json的tools字段控制(权限来源) - Skills 的
required_tools用于校验一致性:如果 Agent 配置了某 Skill 但缺少其依赖工具,启动时发出警告 - BOSS 在配置 Agent 时可以参考 Skill 的
required_tools来决定工具白名单
5. 可扩展性
- 新增 Skill:在
skills.json添加条目即可,无需改代码 - Agent 配置新 Skill:在
agents.json的 agent skills 数组中添加名称 - 热加载:修改
skills.json后调用POST /api/config/reload生效 - 自定义 Skill:BOSS 可编写自有 Skill,只要 levels(hint/guide/full)和 required_tools 定义正确
6. 与工具白名单的关系
┌─────────────────────────────────────────────────┐
│ agents.json │
│ agent.tools: [read_file, write_file, ...] │ ← 权限来源(硬限制)
│ agent.skills: [code-generation, unit-testing] │ ← 行为来源(软引导)
└──────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ skills.json │
│ levels.hint → 始终注入 system prompt │
│ levels.guide → stage 激活时注入 │
│ levels.full → 写入 .catown/skills/ 按需读取 │
│ required_tools → 校验一致性(不授予权限) │
└─────────────────────────────────────────────────┘
- tools = Agent 能做什么(权限边界)
- skills = Agent 怎么做(行为指引)
- 两者独立配置,通过校验机制确保一致性
每个 Agent 支持三层记忆,分别服务于不同时间尺度的认知需求:
┌─────────────────────────────────────────────────┐
│ Agent 长期记忆 │
│ (agent-level, 持久存储) │
│ 工作模式、原则、通用经验、教训 │
├─────────────────────────────────────────────────┤
│ 项目记忆 │
│ (project-level, 项目周期) │
│ 项目上下文、关键决策、架构约定 │
├─────────────────────────────────────────────────┤
│ 短期记忆 │
│ (session-level, 会话生命周期) │
│ 当前任务的对话上下文、中间状态 │
└─────────────────────────────────────────────────┘
| 属性 | 说明 |
|---|---|
| 生命周期 | 单个 Stage 执行期间 |
| 存储位置 | 内存,Stage 结束后可选持久化 |
| 内容 | 当前对话历史、工具调用记录、中间推理过程 |
| 清理策略 | Stage 完成后自动归档到项目记忆(摘要化) |
| 属性 | 说明 |
|---|---|
| 生命周期 | 项目创建 → 项目归档 |
| 存储位置 | projects/{project_id}/.catown/memory/ |
| 内容 | 项目关键决策、架构约定、遇到的问题及解决方案、代码约定 |
| 组织方式 | 按类别分文件(decisions.md, conventions.md, issues.md) |
| 访问方式 | Agent 通过 retrieve_memory 工具检索项目记忆 |
| 属性 | 说明 |
|---|---|
| 生命周期 | Agent 存续期间,跨项目保留 |
| 存储位置 | configs/agents/{agent_name}/memory/ |
| 内容 | 工作模式、设计原则、通用经验、偏好设置、过往教训 |
| 组织方式 | 向量数据库 + 关键词索引,支持语义检索 |
| 访问方式 | Agent 通过 retrieve_memory 工具按语义查询 |
长期记忆持久化规则 — 基础判定矩阵:
| 记忆类型 | 是否泛化 | 判定标准 | 示例 |
|---|---|---|---|
| 工作模式 | ✅ 是 | 可重复使用的做事方法 | "先写测试再写实现"、"API 设计遵循 REST 规范" |
| 设计原则 | ✅ 是 | 跨项目适用的决策标准 | "优先选择活跃维护的开源库"、"数据库设计第三范式" |
| 通用经验 | ✅ 是 | 与具体业务无关的技术知识 | "FastAPI 的 WebSocket 在测试环境需用 TestClient" |
| 常见坑 | ✅ 是 | 可避免的重复错误 | "Python 3.10 下 pydantic v2 需显式声明 Optional" |
| 偏好 | ✅ 是 | Agent 的风格与习惯 | "测试文件命名 test_xxx.py 而非 xxx_test.py" |
| 项目特定细节 | ❌ 否 | 与具体项目强绑定 | "用户管理系统用 PostgreSQL,表结构是..." |
| 一次性决策 | ❌ 否 | 无复用价值 | "这次选了红色主题色" |
| 上下文片段 | ❌ 否 | 临时对话内容 | "BOSS 说下周三交付" |
不确定记忆 → BOSS 确认:当 Agent 无法确定某条记忆是否应该写入长期记忆时,不自行决定,而是通过聊天框的交互选择框提交给 BOSS 确认:
┌─────────────────────────────────────────────────────────────┐
│ 🧠 developer 发现一条可能值得长期记忆的经验 │
│ │
│ "在 WebSocket 连接中,心跳超时设置为 30s 会导致移动端 │
│ 在弱网环境下频繁断线重连。建议改用自适应心跳: │
│ 基础间隔 60s,指数退避。" │
│ │
│ 这条记忆应该: │
│ │
│ ○ 💾 写入长期记忆(作为通用模式,所有项目适用) │
│ ○ 📁 写入项目记忆(仅限当前项目) │
│ ○ 🗑️ 忽略(不需要持久化) │
│ ○ ✏️ 编辑后保存 │
│ │
│ [确认选择] │
└─────────────────────────────────────────────────────────────┘
聊天框不仅支持文本消息,还支持交互式选择框(Choice Box),用于 BOSS 发表意见、做出选择。
交互组件类型:
| 组件类型 | 用途 | 数据格式 |
|---|---|---|
choice |
单选/多选 | 选项列表 + 默认值 |
confirm |
确认/取消 | 二元决策 |
rating |
评分 | 1-5 星,用于记忆价值评估 |
edit |
文本编辑 | 预填文本,BOSS 可修改后提交 |
Choice Box 数据结构:
{
"id": "choice_20260407_001",
"type": "choice",
"source_agent": "developer",
"context": "记忆持久化决策",
"question": "这条记忆应该:",
"options": [
{"id": "save_long", "label": "💾 写入长期记忆", "description": "作为通用模式,所有项目适用"},
{"id": "save_project", "label": "📁 写入项目记忆", "description": "仅限当前项目"},
{"id": "ignore", "label": "🗑️ 忽略", "description": "不需要持久化"},
{"id": "edit", "label": "✏️ 编辑后保存", "description": "修改内容后保存"}
],
"multi": false,
"timeout_seconds": null,
"created_at": "2026-04-07T14:30:00Z"
}Choice Box 使用场景:
| 场景 | 触发方 | 选项 |
|---|---|---|
| 记忆持久化不确定 | Agent | 写入长期 / 写入项目 / 忽略 / 编辑 |
| 工具临时授权 | Agent | 本次允许 / 本阶段允许 / 拒绝 |
| Pipeline 阶段审批 | 系统 | 通过 / 打回 / 修改后继续 |
| 产出物确认 | Agent | 确认满意 / 需要修改 / 重做 |
| 设计方案选择 | Agent | 方案 A / 方案 B / 都不用 |
BOSS 响应流程:
BOSS 在聊天框看到 Choice Box
│
├── 点选选项 → 即时响应,Agent 立刻收到结果
├── 选择 "编辑" → 弹出文本编辑框,BOSS 修改后提交
├── 超时未响应 → 使用默认选项(如有),或 Agent 主动提醒
└── 取消 → Agent 收到取消通知,调整策略
Agent 在空闲时自动进行记忆整理和优化。触发条件是连续空闲时长,而非固定时间段。
Agent 进入空闲状态(无活跃 Pipeline Stage)
│
├── 记录空闲开始时间 idle_start
│
├── 连续空闲 > idle_threshold(可配置) → 触发整理
│ │
│ ├── 1. 短期记忆 → 项目记忆(摘要提取)
│ ├── 2. 项目记忆审查 → 按规则判定是否泛化到长期记忆
│ │ ├── 明确可泛化(工作模式/原则/通用经验) → 自动写入
│ │ └── 不确定 → 生成 Choice Box 等 BOSS 确认
│ ├── 3. 长期记忆去重和压缩
│ └── 4. 标记 low-value 记忆待清理
│
└── 有新任务到来 → 立即中断整理,恢复工作
睡眠配置项(agents.json):
| 配置项 | 默认值 | 说明 |
|---|---|---|
sleep.enabled |
true | 是否启用睡眠整理 |
sleep.idle_threshold_minutes |
30 | 连续空闲多少分钟后触发整理 |
sleep.preferred_window_start |
"23:00" | 优先整理时段(非强制,空闲时可随时触发) |
sleep.preferred_window_end |
"07:00" | 优先整理时段结束 |
sleep.max_retain_days |
30 | 短期记忆最大保留天数 |
sleep.long_term_max_tokens |
100000 | 长期记忆最大 token 数 |
sleep.auto_generalize |
false | 是否自动泛化(false=每次都问 BOSS) |
睡眠整理流程:
- 短期 → 项目记忆:对每个完成的 Stage,提取关键信息(决策、问题、解决方案)写入项目记忆
-
项目记忆审查:逐条审查,按判定矩阵判断是否泛化到长期记忆
- 类型匹配"工作模式/原则/通用经验" → 自动写入长期记忆
- 类型不明确 → 生成 Choice Box 等待 BOSS 确认
-
auto_generalize=true时全部自动处理(省 BOSS 时间,但可能误判)
-
长期记忆压缩:超过
max_retain_tokens时,按价值评分淘汰低价值条目 -
清理:删除超过
max_retain_days的短期记忆归档文件 - 可中断:新任务到来时立即中止整理,下次空闲继续
用户提交原始需求
│
▼
[Pipeline 启动]
│
▼
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Stage: 分析 │────▶│ Stage: 架构 │────▶│ Stage: 开发 │
│ Agent: analyst│ │ Agent: architect│ │ Agent: developer│
│ Gate: 人工审批│ │ Gate: 自动通过 │ │ Gate: 测试通过│
└─────────────┘ └──────────────┘ └─────────────┘
│
┌──────────────────────┘
▼
┌─────────────┐ ┌─────────────┐
│ Stage: 测试 │────▶│ Stage: 发布 │
│ Agent: tester│ │ Agent: release│
│ Gate: 自动 │ │ Gate: 人工审批│
└─────────────┘ └─────────────┘
Pipeline:一个工作流定义,包含多个 Stage。每个项目关联一个 Pipeline。
Stage:流水线阶段。每个 Stage 绑定一个 Agent,定义产出物类型。
Gate:阶段间门禁,控制何时进入下一阶段:
| Gate 类型 | 行为 |
|---|---|
auto |
上一阶段完成,自动进入下一阶段 |
manual |
等待 BOSS 审批(approve / reject) |
condition |
基于条件自动判定(如测试通过率 > 95%) |
Artifact:阶段产出物。存储在项目 workspace 中,记录文件路径和摘要。
Workspace:每个项目独立的文件目录,Agent 通过工具读写。
配置文件:configs/pipelines.json
{
"default": {
"name": "标准软件开发流水线",
"description": "需求分析 → 架构设计 → 开发 → 测试 → 发布",
"stages": [
{
"name": "analysis",
"display_name": "需求分析",
"agent": "analyst",
"gate": "manual",
"timeout_minutes": 30,
"expected_artifacts": ["PRD.md"]
},
{
"name": "architecture",
"display_name": "架构设计",
"agent": "architect",
"gate": "auto",
"timeout_minutes": 30,
"expected_artifacts": ["tech-spec.md"]
},
{
"name": "development",
"display_name": "软件开发",
"agent": "developer",
"gate": "auto",
"timeout_minutes": 60,
"expected_artifacts": ["src/"]
},
{
"name": "testing",
"display_name": "测试",
"agent": "tester",
"gate": "auto",
"timeout_minutes": 30,
"expected_artifacts": ["reports/tests/"]
},
{
"name": "release",
"display_name": "版本发布",
"agent": "release",
"gate": "manual",
"timeout_minutes": 15,
"expected_artifacts": ["CHANGELOG.md"]
}
]
}
}PipelineRun 状态:
┌────────────────────────────────┐
│ │
▼ │
┌──────────┐ ┌──────────┐ │
────创建────▶│ PENDING │────▶│ RUNNING │────完成──▶ COMPLETED
└──────────┘ └────┬─────┘ │
│ │
暂停 │ 失败 │
▼ │
┌──────────┐ │
│ PAUSED │─────────┘──▶ FAILED
└──────────┘
Stage 状态:
PENDING → RUNNING → COMPLETED
→ BLOCKED (等待人工审批)
→ FAILED
阶段 N 完成
│
├── Gate = auto ──────────▶ 自动进入阶段 N+1
│
├── Gate = manual ────────▶ Pipeline 暂停,等待 BOSS 审批
│ │
│ approve ──▶ 进入阶段 N+1
│ reject ──▶ 打回阶段 N 重做
│
└── Gate = condition ─────▶ 引擎评估条件
│
通过 ──▶ 进入阶段 N+1
不通过 ──▶ 打回阶段 N 重做
| 级别 | 触发条件 | 处理方式 |
|---|---|---|
| LLM 调用失败 | API 超时 / 429 / 500 | 自动重试 3 次,指数退避(1s, 2s, 4s) |
| 工具执行失败 | execute_code 报错 | 错误信息回传 LLM,让 Agent 自行修复(最多 3 轮) |
| 阶段失败 | Agent 反复失败超过上限 | Pipeline 暂停,通知 BOSS,等人工介入 |
| 超时 | 阶段运行超过 timeout_minutes | Pipeline 暂停,通知 BOSS |
核心约束:项目之间完全隔离。每个项目是一个独立沙箱,互不可见、互不影响、互不干扰。
┌──────────────────┐ ✗ 不可见 ┌──────────────────┐
│ Project A │◄─────────────►│ Project B │
│ │ │ │
│ PRD.md │ │ PRD.md │
│ src/ │ │ src/ │
│ .catown/ │ │ .catown/ │
│ ├── memory/ │ │ ├── memory/ │
│ └── pipeline │ │ └── pipeline │
│ .git/ │ │ .git/ │
└──────────────────┘ └──────────────────┘
两个项目之间:无共享文件、无共享记忆、无共享状态、无交叉引用。
每个项目独立目录结构:
projects/
└── {project_id}/
├── .git/ # 独立 Git 仓库(项目间无共享)
├── PRD.md # Analyst 产出
├── tech-spec.md # Architect 产出
├── src/ # Developer 产出
│ ├── main.py
│ └── ...
├── tests/ # Tester 产出
│ ├── reports/tests/<timestamp>--<subject>.md
│ └── ...
├── CHANGELOG.md # Release 产出
└── .catown/ # 项目私有元数据(其他项目不可见)
├── pipeline.json # Pipeline 运行状态
├── stage_context/ # 各阶段上下文快照
└── memory/ # 项目记忆存储(隔离)
├── decisions.md # 关键决策记录
├── conventions.md # 代码/架构约定
└── issues.md # 遇到的问题与方案
隔离维度:
| 维度 | 隔离方式 | 说明 |
|---|---|---|
| 文件系统 | 目录隔离 | 每个项目独立目录树,物理上不存在交叉 |
| Git 仓库 | 仓库隔离 | 每个项目独立 .git/,无共享分支/提交历史 |
| 记忆存储 | .catown 隔离 | 项目记忆存于 .catown/memory/,其他项目无法访问 |
| Pipeline 状态 | 状态隔离 | 每个 PipelineRun 绑定唯一 project_id,引擎不跨项目调度 |
| Agent 上下文 | 会话隔离 | Agent 执行 Stage 时注入 PROJECT_WORKSPACE,只指向当前项目 |
| LLM Prompt | 注入隔离 | 传入 LLM 的上下文只包含当前项目文件,不包含其他项目内容 |
防逃逸机制(技术保障):
| 机制 | 说明 |
|---|---|
| 路径白名单 | Agent 工具读写限定在 projects/{project_id}/ 下 |
| 路径校验 |
read_file / write_file / execute_code 执行前校验路径前缀 |
| 绝对路径拒绝 | Agent 传入的绝对路径强制转为项目相对路径 |
| Symlink 防护 | 解析所有符号链接,校验最终路径仍在项目目录内 |
| 跨项目禁止 | Agent 不可访问其他项目的 .catown/、.git/ 或任何产出物 |
| API 层校验 | 所有涉及项目的 API 调用验证 project_id 归属 |
隔离的目的:
- 安全:防止项目 A 的 Agent 读取项目 B 的敏感代码或记忆
- 可预测:每个项目的行为完全独立,不受其他项目干扰
- 并行安全:多项目并行运行时不会产生文件冲突或状态污染
- 审计清晰:所有操作可追溯到具体项目,不会混淆
当前一个 Agent 完成后,向下一个 Agent 传递:
[Stage output from: analyst]
Stage: analysis
Status: completed
Files created: PRD.md
Workspace: /path/to/projects/{id}/
Summary:
完成了用户管理模块的需求分析,包含 5 个用户故事和 12 条验收标准。
核心功能:用户注册/登录、角色权限管理、操作审计日志。
PRD.md 内容(截断):
# 用户管理系统 PRD
## 1. 概述
...
Agent 通过 read_file 工具可以读取完整文件。
- 每个 Stage 完成自动 Git commit(message:
[pipeline] stage: {stage_name} completed) - Release 阶段自动打 Git tag(
v1.0.0) - BOSS 可以查看各阶段的 diff
Pipeline 运行时
│
├── Developer 遇到接口问题
│ │
│ ├── 发消息给 Architect(Agent → Agent 消息)
│ │ │
│ │ └── Architect 回复澄清
│ │
│ └── WebSocket 广播到前端(BOSS 实时可见)
│
└── 继续开发
| 类型 | 说明 | 示例 |
|---|---|---|
STAGE_OUTPUT |
阶段完成时的产出摘要 | Analyst → Pipeline Engine |
AGENT_QUESTION |
Agent 向另一 Agent 提问 | Developer → Architect |
AGENT_REPLY |
Agent 回答另一个 Agent | Architect → Developer |
HUMAN指令 |
BOSS 发给 Agent 的指令 | PM → Developer |
STATUS_UPDATE |
Agent 状态更新 | Developer → Pipeline Engine |
Agent 间协作消息持久化到 pipeline_messages 表,BOSS 可事后回顾。
Agent 同时接收来自 BOSS、其他 Agent、Pipeline Engine 的消息,需要根据来源和 Agent 状态动态选择调度策略,而非全局固定一种模式。
用户面模式(面向交互体验):
| 模式 | 行为 | 典型场景 |
|---|---|---|
steer |
立即注入当前流程,可能中断正在执行的任务 | BOSS 紧急指令(暂停、修改方向) |
followup |
排队等候,Agent 完成当前轮次后再处理 | Agent 正在推理,BOSS 发了非紧急备注 |
collect |
短时间内多条消息合并为一条,再统一处理 | BOSS 连续补充需求细节 |
steer-backlog |
立即干预当前运行 + 保留到下一轮 | BOSS 修改决策,需打断又需后续记住 |
底层策略(面向系统资源):
| 策略 | 行为 | 典型场景 |
|---|---|---|
queue |
严格 FIFO | 测试用例批量处理 |
debounce |
时间窗口内只取最后一条 | 实时参数调整 |
concurrent |
全部并行 | 互不依赖的独立任务 |
drop |
系统繁忙时直接丢弃 | 非关键状态更新 |
按消息来源 + Agent 当前状态自动选择:
BOSS → Agent:
| Agent 状态 | 消息特征 | 选择模式 |
|---|---|---|
| 任意 | 含 stop/pause/rollback 关键词 | steer |
| 空闲 | 任意 | 直接处理 |
| 忙 | 任意 | steer-backlog |
Agent → Agent:
| 目标 Agent 状态 | 选择模式 |
|---|---|
| 空闲 | 直接处理 |
| LLM 推理中 | followup |
| 工具执行中 |
collect(合并窗口 1-3s) |
Pipeline Engine → Agent:
| 触发类型 | 选择模式 |
|---|---|
| 下一阶段启动 | followup |
| 超时/错误恢复 | steer |
| 优先级 | 消息来源 | 处理策略 |
|---|---|---|
| P0 | BOSS 紧急指令 |
steer — 立即中断当前任务 |
| P1 | BOSS 普通指令 |
steer-backlog — 插队并保留 |
| P1 | Pipeline Engine 错误恢复 | steer |
| P2 | Agent 间协作 |
followup / collect
|
| P3 | Pipeline Engine 阶段推进 | followup |
多个 Agent 向同一 Agent 发消息时,按来源 Agent 轮转处理,防止饿死。BOSS 消息始终插队到最前。
新增 configs/agents.json 队列相关配置:
{
"queue": {
"collect_window_ms": 3000,
"backpressure_threshold": 50,
"stale_ttl_seconds": 300,
"fair_scheduling": true
}
}| 配置项 | 默认值 | 说明 |
|---|---|---|
collect_window_ms |
3000 | 消息合并窗口(毫秒) |
backpressure_threshold |
50 | 队列积压超过此值触发背压 |
stale_ttl_seconds |
300 | 消息过期时间(秒),超时丢弃 |
fair_scheduling |
true | 是否启用公平调度 |
┌─────────────────────────────────────────────────────────────┐
│ Catown Pipeline Dashboard │
├─────────────────────────────────────────────────────────────┤
│ │
│ 📋 项目: 用户管理系统 │
│ 状态: ██████████░░░░ 开发中 (Stage 3/5) │
│ 已用时间: 2h 15m │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ ✅ 分析 │──│ ✅ 架构 │──│ 🔄 开发 │──│ ⏳ 测试 │ │
│ │ 25min │ │ 18min │ │ 进行中... │ │ 等待中 │ │
│ │ PRD.md │ │ tech-spec│ │ src/ │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ 💬 Agent 实时通信: │
│ ┌────────────────────────────────────────────────────┐ │
│ │ [developer] 接口 /api/users 的认证方式需要确认 │ │
│ │ [architect] 用 JWT,schema 在 tech-spec.md 第3节 │ │
│ │ [developer] 收到,继续实现 │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 📦 产出物: │
│ ├── PRD.md (12KB, analyst, 2h15m前) │
│ ├── tech-spec.md (8KB, architect, 1h57m前) │
│ ├── src/main.py (3KB, developer, 12m前) │
│ └── src/models.py (2KB, developer, 8m前) │
│ │
│ ⚡ 操作: │
│ [⏸ 暂停] [⏪ 打回上一阶段] [💬 发指令给 Agent] [▶️ 继续] │
└─────────────────────────────────────────────────────────────┘
| 操作 | 说明 | API |
|---|---|---|
| 观察 | 实时看 Agent 对话、看产出物、看进度 | WebSocket + GET |
| 暂停 | 暂停整个 Pipeline | POST /api/pipelines/{id}/pause |
| 继续 | 恢复暂停的 Pipeline | POST /api/pipelines/{id}/resume |
| 审批 | Gate=manual 时 approve/reject | POST /api/pipelines/{id}/approve |
| 打回 | 打回某个阶段重做 | POST /api/pipelines/{id}/rollback |
| 发指令 | 直接给指定 Agent 发消息 | POST /api/pipelines/{id}/instruct |
| 修改产出物 | 直接编辑 Agent 生成的文件 | 文件编辑器 |
所有交互事件以卡片形式渲染在聊天流中,按时间顺序排列,形成完整的执行叙事线。BOSS 看到的不再是 Agent 的最终回复,而是完整的"想了什么→搜了什么→写了什么→问了谁→谁回答了"的过程。
永久 UX 原则:
- 禁止浏览器原生弹窗(
alert/confirm/prompt)介入聊天流程 - 所有确认、审批、二次选择都必须在聊天窗口内以卡片/内联面板呈现
- 能用点击完成的交互,不要求用户额外输入文本
- 必须采集文本时,通过正常聊天对话获取,不额外弹出输入框
- 例外:如果用户是通过聊天窗口外的显式 UI 入口创建项目,则该流程可使用其所属 UI 的标准交互,不受“必须在聊天窗口内完成”的约束
在现有调用链上增加旁路审计写入点,不修改 Agent 决策逻辑和执行流程。详见 ADR-010。
Agent 执行引擎
│
├── ① LLM 调用层 ──▶ llm_calls 表
│ (system_prompt, messages, response, tool_calls, tokens, 耗时)
│
├── ② 工具执行层 ──▶ tool_calls 表
│ (工具名, 入参, 返回摘要, 耗时, 成功/失败)
│
└── ③ 事件层 ──────▶ events 表
(event_type, 关联方, 摘要, payload)
| 卡片 | 图标 | 默认状态 | 触发事件 | 展开内容 |
|---|---|---|---|---|
| 🧠 LLM 调用 | 🧠 | 折叠 | 每次 LLM 请求/响应 | system_prompt(标注来源片段)→ messages 历史 → response |
| 🔧 工具调用 | 🔧/📖/✏️/ |
折叠 | 每次工具执行 | 入参 JSON + 返回值/摘要 + 耗时 + diff(文件类工具) |
| 💬 Agent 间消息 | 💬 | 展开 | Agent 间 ask/reply | 完整消息 + 上下文关联(回答哪条提问) |
| 展开 | 阶段开始/完成 | 产出物列表 + 耗时 + git commit | ||
| 🚧 Gate 卡片 | 🚧 | 展开 | manual gate 阻塞 | 产出物摘要 + [Approve] [Reject] 按钮 |
| ⚡ Skill 注入 | ⚡ | 折叠 | 阶段开始时 | hint/guide/full 各层注入内容 + token 估算 |
| 👤 BOSS 指令 | 👤 | 展开 | BOSS 发出指令 | 指令内容 + 系统确认(注入了哪个 Agent) |
展开规则:
- 默认折叠:LLM 卡片、工具卡片、Skill 卡片——避免刷屏
- 默认展开:Agent 间消息(协作叙事线索)、阶段事件(进度标记)、Gate 卡片(需要操作)
- 自动展开:工具调用失败(红色边框)、LLM 调用出错
- 合并连续同类卡片:连续多个同类型工具调用合为一个卡片
LLM 对话的完整 prompt 可能包含数万 token,直接展示没有意义。LLM 卡片的设计原则是展示 BOSS 真正关心的信息:
🧠 developer · LLM #3 · gpt-4 · 1247 tok in / 583 out · 7.2s
── 默认显示 ──────────────────────────────────────────────────
"我将实现 JWT 讁证模块,先读取现有的 main.py 确认路由结构"
── ⮟ 展开后 ─────────────────────────────────────────────────
┌── System Prompt (847 tok) ────────────────────────────────┐
│ 你是 Dev。一个注重代码质量的资深工程师... │
│ 来源: soul.identity(42tok), role.rules(25tok), │
│ skills.hint(30tok), memory.own(0tok) │
└───────────────────────────────────────────────────────────┘
┌── Messages (本轮输入) ────────────────────────────────────┐
│ [user] # Stage: software development │
│ [assistant - prev] 已读取 tech-spec.md ... │
│ [tool] read_file(tech-spec.md) → 8.2KB │
└───────────────────────────────────────────────────────────┘
┌── Response ───────────────────────────────────────────────┐
│ 我将实现 JWT 认证模块... │
│ 🔧 tool_calls: read_file(src/main.py) │
└───────────────────────────────────────────────────────────┘
| 工具 | 图标 | 成功样式 | 失败样式 |
|---|---|---|---|
read_file |
📖 | 灰色边框 | 红色边框 + 自动展开 |
write_file |
✏️ | 灰色边框 | 红色边框 + 自动展开 |
execute_code |
绿色边框 | 红色边框 + 自动展开 | |
web_search |
🔍 | 灰色边框 | 红色边框 + 自动展开 |
web_fetch |
🌐 | 灰色边框 | 红色边框 + 自动展开 |
list_files |
📂 | 灰色边框 | 红色边框 + 自动展开 |
send_direct_message |
💬 | 灰色边框 | 红色边框 + 自动展开 |
👤 BOSS: "做一个用户管理系统,支持注册登录和权限管理"
▶️ Stage: 需求分析 · analyst · Gate: manual
⚡ Skills: document-analysis(hint), requirement-decomposition(hint)
🧠 analyst · LLM #1 · gpt-4
"我将按以下步骤进行需求分析..."
🔍 web_search(用户管理系统最佳实践)
找到 3 个相关主题
🧠 analyst · LLM #2 · gpt-4
"基于搜索结果,我确定了核心功能模块..."
✏️ write_file(PRD.md) · 12KB
🧠 analyst · LLM #3 · gpt-4
"需求分析完成。PRD 包含 5 个用户故事..."
✅ Stage: 需求分析 · 25min · Artifacts: PRD.md
🚧 Gate: 需求分析完成,等待审批
[👁️ 查看PRD] [✅ Approve] [⏪ Reject]
👤 BOSS: ✅ Approved
▶️ Stage: 架构设计 · architect · Gate: auto
💬 developer ──▶ architect: "用户认证用 JWT 还是 Session?"
🧠 architect · LLM #1 · gpt-4: "JWT 更适合这个场景..."
💬 architect ──▶ developer: "用 JWT,schema 在 tech-spec.md 第3节"
✏️ write_file(tech-spec.md) · 8KB
✅ Stage: 架构设计 · 18min
▶️ Stage: 软件开发 · developer
⚡ Skills: code-generation(guide), unit-testing(guide), refactoring(guide)
🧠 developer · LLM #1 · gpt-4: "先读取 tech-spec..."
📖 read_file(tech-spec.md) · 8.2KB
🧠 developer · LLM #2 · gpt-4: "开始实现 JWT 认证模块..."
✏️ write_file(src/auth.py) · 3.2KB
▶️ execute_code(python3 -m pytest tests/) · exit_code: 0 · 12 passed
...
聊天室 SSE 流扩展为全事件推送,与 Pipeline WebSocket 事件结构统一。所有事件携带 source 字段(chatroom 或 pipeline),用于前端视觉区分。
| 事件类型 | 字段 | 说明 |
|---|---|---|
llm_call |
source, agent, model, turn, tokens_in, tokens_out, duration_ms, system_prompt, response, tool_calls | LLM 调用完整记录(system_prompt 截断 5K,response 截断 3K) |
tool_call |
source, agent, tool, arguments, success, result, duration_ms | 工具调用记录 |
skill_inject |
source, agent, skills[{name, hint, guide}] | Skill 注入内容 |
agent_message |
source, from, to, content, message_type | Agent 间消息 |
stage_start |
source, stage, agent, skills_active, gate_type, expected_artifacts | 阶段开始 |
stage_end |
source, stage, duration, artifacts, status | 阶段结束 |
gate_blocked |
source, stage, artifact_summary | Gate 阻塞 |
gate_approved |
source, stage | Gate 通过 |
gate_rejected |
source, stage | Gate 拒绝 |
boss_instruction |
source, agent, content | BOSS 指令确认 |
每张卡片根据 source 字段应用不同样式:
| 来源 | 视觉标记 | 含义 |
|---|---|---|
chatroom |
无特殊标记 | BOSS 在聊天室主动触发的交互 |
pipeline |
左侧蓝色竖线 + 🔧 Pipeline 标签 |
流水线自动执行 |
- Pipeline Dashboard(§8.1):宏观视角——阶段进度条、状态、耗时、产出物列表
- 聊天窗口卡片(§8.3):微观视角——所有 LLM/Tool/Skill/Agent 事件的完整卡片流
- 两者通过
run_id关联,Dashboard 中点击阶段可跳转到聊天窗中对应的事件时间线 - Pipeline 的 WebSocket 事件与聊天室 SSE 事件结构完全统一,前端共用
handlePipelineEvent()渲染
- 前端单文件(Vanilla JS),卡片渲染函数内嵌
index.html - 审计写入异步执行,不阻塞 Agent 执行循环
- LLM 审计不存大文件:
read_file返回值只存摘要(前 500 字),完整内容通过 Tee 机制追溯(见 §21 CC-008) -
input_context改为存储实际内容:~10KB/阶段,总计 ~50KB/pipeline - 聊天室 SSE 和 Pipeline WebSocket 事件结构统一(含
source字段),前端共用卡片渲染逻辑 - 详见 ADR-011: 聊天室全事件卡片统一
聊天框是 BOSS 与系统交互的核心入口。通过消息历史、指令系统、联想补全三项机制,大幅提升操作效率。
输入框支持历史记录回溯,快速复用之前的消息或指令。
| 操作 | 行为 |
|---|---|
| ↑ 向上 | 回溯到上一条输入历史(当前已输入内容暂存) |
| ↓ 向下 | 前进到下一条输入历史,直到回到最新(恢复暂存内容) |
| 输入新内容后 ↑ | 从当前输入位置开始,在历史中搜索匹配前缀 |
| ESC | 清空当前输入,放弃历史回溯 |
规则:
- 仅记录 BOSS 主动发送的消息(指令 + 自由文本),不记录 Agent 回复
- 历史按时间倒序存储,最近的在最前面
- 跨会话持久化(存储在
projects/{id}/.catown/input_history.json) - 默认保留最近 50 条,可配置
输入框以 / 开头触发指令模式,用于快速执行系统管理操作。
指令分类与列表(第一版·只读):
| 指令 | 别名 | 分类 | 说明 |
|---|---|---|---|
/help |
/h |
基础 | 显示所有可用指令及说明 |
/skills list |
/sl |
Skills | 列出已安装 Skills |
/skills info <name> |
/si |
Skills | 查看 Skill 详情(描述、依赖工具、适用 Agent) |
/tools list |
/tl |
Tools | 列出所有可用工具 |
/tools info <name> |
/ti |
Tools | 查看工具详情(参数、权限) |
/agents list |
/al |
Agent | 列出所有 Agent 角色及状态 |
/agents info <name> |
/ai |
Agent | 查看 Agent 详情(SOUL、工具、模型) |
/config get |
/cg |
配置 | 查看当前全局配置 |
/pipeline status |
/ps |
Pipeline | 查看当前 Pipeline 运行状态 |
第一版仅提供只读查询指令。写操作类指令(
/skills enable、/config set、/service restart等)后续版本迭代。
指令特性:
- 指令在聊天框中以特殊样式渲染(左侧紫色竖线 + 等宽字体),与普通消息区分
- 指令执行结果以系统消息卡片返回,区分成功(绿色)和失败(红色)样式
- 可扩展:在
configs/commands.json中定义新指令,支持注册自定义指令
指令数据结构:
{
"commands": {
"skills.list": {
"trigger": "/skills list",
"category": "skills",
"description": "列出已安装 Skills",
"params": [],
"handler": "system",
"dangerous": false
},
"service.restart": {
"trigger": "/service restart",
"category": "service",
"description": "重启后端服务",
"params": [],
"handler": "system",
"dangerous": true,
"confirm_message": "确认重启服务?当前 Pipeline 将中断。"
}
}
}输入框实时分析当前输入内容,提供上下文相关的补全建议。
触发方式:
| 触发 | 行为 |
|---|---|
输入 /
|
显示所有指令列表,按分类分组 |
输入 /skills
|
显示 skills 子命令列表 |
输入 /agents
|
显示 Agent 名称列表 |
| 输入历史匹配前缀 | 显示匹配的历史消息(最多 5 条) |
输入 @
|
显示 Agent 名称列表(用于定向发指令) |
| Tab | 接受当前选中的补全项 |
| ↑ / ↓ | 在补全列表中上下选择 |
| ESC | 关闭补全面板 |
联想面板 UI:
┌──────────────────────────────────────┐
│ /skills info <name> │
├──────────────────────────────────────┤
│ 📋 指令 │
│ /skills list 列出已安装 Skills│
│ /skills info 查看 Skill 详情 │
│ /skills enable 启用 Skill │
│ /skills disable 禁用 Skill │
│ │
│ 🕐 历史 │
│ 做一个用户管理系统,支持注册登录 │
│ 把架构设计打回,补充数据库选型理由 │
│ 暂停 Pipeline │
└──────────────────────────────────────┘
补全来源:
- 指令匹配 — 当前输入匹配指令前缀(最高优先级)
- 历史匹配 — 历史消息中匹配当前输入前缀的结果(最多 5 条)
补全面板数据流:
用户输入
│
├─ 以 / 开头 ──→ 命令解析器 ──→ 匹配指令 + 参数提示
│
├─ 以 @ 开头 ──→ Agent 注册表 ──→ Agent 名称列表
│
└─ 普通文本 ──→ 历史搜索 ──→ 匹配的历史消息
│
▼
联想面板(WebSocket 实时推送)
技术要求:
- 联想响应延迟 < 100ms(本地计算,不走 LLM)
- 补全面板使用虚拟滚动,支持大量候选项
数据库记录 Agent 与 LLM 的每一次交互、每一次工具调用及结果,并支持记忆滚动和定期清理。
| 审计项 | 字段 | 说明 |
|---|---|---|
| LLM 对话 | prompt, response, model, tokens | Agent 向 LLM 发送的每次请求和收到的回复 |
| 工具调用 | tool_name, params, result, duration | 每次工具执行的入参和返回值 |
| 记忆操作 | action, memory_layer, content | 每次记忆读写操作(含查询条件和写入内容) |
| Agent 消息 | from, to, content, type | Agent 间及 Agent 与人的通信 |
| Pipeline 事件 | event, stage, status, timestamp | Pipeline 状态变迁 |
三张表各司其职,通过 run_id + stage_id 关联。详见 ADR-010。
llm_calls — LLM 对话全记录
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | |
| run_id | INTEGER FK | Pipeline run(聊天室场景 nullable) |
| stage_id | INTEGER FK | 阶段(nullable) |
| agent_name | TEXT | Agent 名 |
| turn_index | INTEGER | 该 Agent 在本轮阶段中的第几轮对话 |
| model | TEXT | 实际调用的模型 |
| system_prompt | TEXT | 完整 system prompt |
| messages | TEXT | 本次传入的完整 messages JSON |
| response_content | TEXT | LLM 返回的文本 |
| response_tool_calls | TEXT | LLM 返回的工具调用 JSON |
| token_input | INTEGER | prompt_tokens |
| token_output | INTEGER | completion_tokens |
| duration_ms | INTEGER | 调用耗时 |
| error | TEXT | 错误信息 |
| created_at | DATETIME |
tool_calls — 工具执行记录
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | |
| llm_call_id | INTEGER FK | 关联哪次 LLM 调用触发的 |
| run_id | INTEGER FK | 归属 |
| stage_id | INTEGER FK | |
| agent_name | TEXT | 谁调的 |
| tool_name | TEXT | 工具名 |
| arguments | TEXT | 入参 JSON |
| result_summary | TEXT | 返回值摘要(前 500 字) |
| result_length | INTEGER | 完整返回值长度 |
| success | BOOLEAN | 是否成功 |
| duration_ms | INTEGER | 耗时 |
| created_at | DATETIME |
events — 事件流
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | |
| run_id | INTEGER FK | 归属 |
| event_type | TEXT |
stage_start / stage_end / stage_retry / gate_blocked / gate_approved / gate_rejected / rollback / agent_message / boss_instruction / error / timeout
|
| agent_name | TEXT | 相关 Agent |
| stage_name | TEXT | 相关阶段 |
| summary | TEXT | 一句话摘要 |
| payload | TEXT | 完整详情 JSON |
| created_at | DATETIME |
保留原有的 audit_logs + audit_details 双表设计,作为跨类型汇总查询和长期保留使用。三表采集模型写入明细,audit_logs 写入汇总(由定时任务从三表聚合生成)。
audit_logs — 审计日志主表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 主键 |
| run_id | INTEGER FK | 关联 PipelineRun |
| agent_name | TEXT | Agent 名称 |
| stage_name | TEXT | 所在阶段 |
| event_type | TEXT | llm_chat / tool_call / memory_op / agent_msg / pipeline_event |
| timestamp | DATETIME | 事件时间 |
| duration_ms | INTEGER | 执行耗时(毫秒) |
| token_input | INTEGER | LLM 输入 token 数 |
| token_output | INTEGER | LLM 输出 token 数 |
| summary | TEXT | 事件摘要(用于列表展示) |
audit_details — 审计详情(大字段分离)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 主键 |
| log_id | INTEGER FK | 关联 audit_logs |
| request_payload | TEXT | 请求内容(JSON,LLM prompt 或工具入参) |
| response_payload | TEXT | 响应内容(JSON,LLM 回复或工具返回) |
| error_info | TEXT | 错误信息(如有) |
审计日志有生命周期,过期自动清理,避免无限膨胀。
| 日志类型 | 默认保留期 | 说明 |
|---|---|---|
| LLM 对话详情 | 7 天 | prompt/response 占空间大,快速清理 |
| 工具调用详情 | 14 天 | 保留期稍长,便于排障 |
| 工具调用摘要 | 90 天 | 摘要(工具名+结果状态)保留更久 |
| Pipeline 事件 | 180 天 | 项目流水线状态变更 |
| Agent 消息 | 30 天 | Agent 间通信 |
清理机制:
# 清理任务(由 sleep 机制或定时 cron 触发)
cleanup_rules = {
"llm_chat": {"detail_days": 7, "summary_days": 90},
"tool_call": {"detail_days": 14, "summary_days": 90},
"memory_op": {"detail_days": 7, "summary_days": 30},
"agent_msg": {"detail_days": 30, "summary_days": 30},
"pipeline_event": {"detail_days": 180, "summary_days": 180},
}日志锁定机制:
当某个 PipelineRun 需要事后调查(出问题、争议复盘),BOSS 可以锁定其审计日志,跳过自动清理:
BOSS 发现 Pipeline 运行异常
│
├── POST /api/audit/lock { run_id: 42, reason: "产出物质量问题追溯" }
│ │
│ ├── audit_logs 表增加 locked=true 标记
│ ├── audit_details 中关联 run_id 的记录同步锁定
│ └── 清理任务扫描时跳过所有 locked=true 的记录
│
├── 调查期间,日志完整保留,不受 retention 策略影响
│
└── 调查完毕:
POST /api/audit/unlock { run_id: 42 }
→ 标记移除,恢复正常的清理周期(从解锁时间重新计算)
清理流程:
- 定期(每日凌晨)扫描
audit_details表,删除超过保留期且未锁定的详情记录 - 定期扫描
audit_logs表,删除超过摘要保留期且未锁定的记录 - 清理前导出统计:清理条目数、释放空间大小
- 可配置
audit.retention_override覆盖默认保留期(如项目合规需要)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/audit/logs |
查询审计日志(支持 agent/stage/type/time 过滤) |
| GET | /api/audit/logs/{id} |
获取单条审计日志详情 |
| GET | /api/audit/logs/{id}/detail |
获取请求/响应完整内容 |
| GET | /api/audit/stats |
审计统计(token 用量、工具调用次数等) |
| POST | /api/audit/cleanup |
手动触发清理(管理员) |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/audit/llm |
LLM 调用记录(支持 run_id/agent/时间过滤) |
| GET | /api/audit/llm/{id} |
单条 LLM 调用完整 prompt + response |
| GET | /api/audit/tools |
工具调用记录(支持 run_id/agent/tool_name 过滤) |
| GET | /api/audit/events |
事件流(支持 run_id/event_type 过滤) |
| GET | /api/audit/tokens/summary |
Token 汇总(按 agent/stage/模型分组 + 成本估算) |
| GET | /api/audit/timeline |
聚合时间线(LLM + 工具 + 事件混合排序,用于聊天窗回溯) |
| POST | /api/audit/lock |
锁定审计日志(跳过自动清理) |
| POST | /api/audit/unlock |
解锁审计日志 |
- 审计日志仅限项目成员和 BOSS 访问
- LLM 对话详情可能包含敏感信息(代码、业务数据),按保留期自动销毁
- 导出审计日志时可选择脱敏(隐藏 prompt/response 内容,仅保留摘要)
✅ 已实现。运行时主配置源为 ${CATOWN_HOME}/config/agents.json,首次启动由 backend/configs/agents.json 初始化,两级配置架构。
配置优先级:Agent 自身 provider → global_llm provider → 环境变量
| 配置项 | 级别 | 说明 |
|---|---|---|
global_llm.provider.baseUrl |
全局 | 所有未配置 Agent 的默认 LLM 服务 |
global_llm.provider.apiKey |
全局 | 默认 API Key |
global_llm.default_model |
全局 | 默认模型 |
agent.provider.baseUrl |
per-Agent | 该 Agent 专用 LLM 服务(覆盖全局) |
agent.provider.apiKey |
per-Agent | 独立 API Key(覆盖全局) |
agent.default_model |
per-Agent | 指定默认模型(覆盖全局) |
| Agent | 建议模型等级 | 原因 |
|---|---|---|
| analyst | 中等 | 理解需求 + 结构化输出 |
| architect | 强 | 需要深度推理和权衡 |
| developer | 强 | 代码质量直接影响产出 |
| tester | 中等 | 执行测试 + 生成报告 |
| release | 弱 | 主要是机械性操作 |
以上仅为建议,实际由
agents.json决定,随时可调。
修改 agents.json 后调用 POST /api/config/reload,无需重启服务。
pipelines — Pipeline 定义
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 主键 |
| project_id | INTEGER FK | 关联项目 |
| pipeline_name | TEXT | 使用的 pipeline 模板名 |
| status | TEXT | pending / running / paused / completed / failed |
| current_stage_index | INTEGER | 当前阶段索引 |
| created_at | DATETIME | 创建时间 |
| updated_at | DATETIME | 最后更新时间 |
pipeline_runs — Pipeline 运行实例
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 主键 |
| pipeline_id | INTEGER FK | 关联 Pipeline |
| run_number | INTEGER | 第几次运行(支持重跑) |
| status | TEXT | pending / running / paused / completed / failed |
| input_requirement | TEXT | 用户原始需求 |
| started_at | DATETIME | 开始时间 |
| completed_at | DATETIME | 完成时间 |
pipeline_stages — 阶段记录
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 主键 |
| run_id | INTEGER FK | 关联 PipelineRun |
| stage_name | TEXT | 阶段名称 |
| stage_order | INTEGER | 阶段顺序 |
| agent_name | TEXT | 执行 Agent |
| status | TEXT | pending / running / blocked / completed / failed |
| gate_type | TEXT | auto / manual / condition |
| input_context | TEXT | 传入的上下文(JSON) |
| output_summary | TEXT | 产出摘要 |
| started_at | DATETIME | 开始时间 |
| completed_at | DATETIME | 完成时间 |
| error_message | TEXT | 错误信息 |
stage_artifacts — 产出物记录
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 主键 |
| stage_id | INTEGER FK | 关联 PipelineStage |
| artifact_type | TEXT | file / directory |
| file_path | TEXT | workspace 中的相对路径 |
| summary | TEXT | 内容摘要 |
| created_at | DATETIME | 创建时间 |
pipeline_messages — Agent 间协作消息
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER PK | 主键 |
| run_id | INTEGER FK | 关联 PipelineRun |
| stage_id | INTEGER FK | 关联当前阶段 |
| message_type | TEXT | STAGE_OUTPUT / AGENT_QUESTION / AGENT_REPLY / HUMAN_INSTRUCT |
| from_agent | TEXT | 发送方 Agent 名称 |
| to_agent | TEXT | 接收方 Agent 名称(NULL=广播) |
| content | TEXT | 消息内容 |
| created_at | DATETIME | 创建时间 |
agents, projects, chatrooms, messages, memories, agent_assignments 保持不变。
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/pipelines |
创建 Pipeline(关联项目 + 选择模板) |
| GET | /api/pipelines |
列出所有 Pipeline |
| GET | /api/pipelines/{id} |
获取 Pipeline 详情 |
| POST | /api/pipelines/{id}/start |
启动 Pipeline(传入原始需求) |
| POST | /api/pipelines/{id}/pause |
暂停 Pipeline |
| POST | /api/pipelines/{id}/resume |
恢复 Pipeline |
| POST | /api/pipelines/{id}/approve |
审批通过当前 Gate |
| POST | /api/pipelines/{id}/reject |
拒绝当前 Gate(打回重做) |
| POST | /api/pipelines/{id}/rollback |
打回到指定阶段 |
| POST | /api/pipelines/{id}/instruct |
给指定 Agent 发指令 |
| GET | /api/pipelines/{id}/messages |
获取 Agent 协作消息 |
| GET | /api/pipelines/{id}/artifacts |
获取产出物列表 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/config |
获取配置(agents.json) |
| POST | /api/config/reload |
热加载 agents.json |
| POST | /api/config/test |
测试指定 Agent 的 LLM 连接 |
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/audit/llm |
LLM 调用记录(run_id/agent/时间过滤) |
| GET | /api/audit/llm/{id} |
单条 LLM 调用完整 prompt + response |
| GET | /api/audit/tools |
工具调用记录(run_id/agent/tool_name 过滤) |
| GET | /api/audit/events |
事件流(run_id/event_type 过滤) |
| GET | /api/audit/tokens/summary |
Token 汇总(按 agent/stage/模型分组 + 成本估算) |
| GET | /api/audit/timeline |
聚合时间线(LLM + 工具 + 事件混合排序) |
| GET | /api/audit/logs |
通用审计日志查询 |
| GET | /api/audit/stats |
审计统计 |
| POST | /api/audit/lock |
锁定审计日志 |
| POST | /api/audit/unlock |
解锁审计日志 |
| POST | /api/audit/cleanup |
手动触发清理 |
| 层级 | 技术 | 说明 |
|---|---|---|
| 后端 | Python 3.10+ / FastAPI | 异步 Web 框架 |
| LLM | OpenAI 兼容接口 | agents.json per-agent 配置 |
| 数据库 | SQLite(可扩展 PostgreSQL) | SQLAlchemy ORM |
| 前端 | Vanilla JS 单文件 + TailwindCSS | 不做 React 重写 |
| 实时通信 | WebSocket + SSE | Agent 消息 + 流式输出 |
| 部署 | Docker + docker-compose | 单进程 |
backend/
├── pipeline/
│ ├── __init__.py ✅
│ ├── config.py ✅ Pipeline 配置加载
│ ├── engine.py ⏳ Pipeline 引擎(核心)
│ └── models.py ⏳ Pipeline 数据模型(如需要独立)
├── routes/
│ └── pipeline.py ⏳ Pipeline API 路由
├── configs/
│ ├── agents.json ✅ 6 个角色,独立 LLM 配置
│ └── pipelines.json ✅ 默认 5 阶段流水线模板
└── models/
└── database.py ✅ 新增 5 张 Pipeline 表
| 决策 | 选择 | 理由 |
|---|---|---|
| Pipeline 配置 | 可配置(pipelines.json) | 不同项目需要不同流程 |
| 产出物传递 | Workspace + 文本摘要 | Agent 读写文件,引擎注入摘要 |
| 并发 | 单项目串行 | 第一版不处理并发,够用 |
| 错误恢复 | 重试 → 暂停等人工 | 简单可靠 |
| 代码沙箱 | 基础隔离(超时+禁import) | 第一版不上 Docker-in-Docker |
| 前端 | 继续 Vanilla JS | 不做 React 重写,Pipeline Dashboard 直接加 |
| 阶段 | 状态 | 日期 |
|---|---|---|
| P0 — 数据模型与配置 | ✅ | 2026-04-07 |
| P1 — 引擎与 API | ✅ | 2026-04-07 |
| P1 — 前端 Dashboard | ✅ | 2026-04-07 |
| P2 — 增强(Git 集成 + 产出物查看器) | ✅ | 2026-04-07 |
| P3 — 扩展(多项目并行 + 测试覆盖) | ✅ | 2026-04-07 |
| 测试修复 + Agent 协作 + 两级 LLM 配置 | ✅ | 2026-04-08 |
| Agent 配置路径修复 | ✅ | 2026-04-08 |
| 新增 assistant 助理角色 | ✅ | 2026-04-08 |
| Skills 三级注入 (ADR-008) | ✅ | 2026-04-10 |
| 工具白名单校验 + Workspace 隔离 | ✅ | 2026-04-10 |
| 知识图谱 Skill 定义 (ADR-004) | ✅ | 2026-04-10 |
| 监控审计三表采集 + 审计 API (ADR-010: 0a-0c) | ✅ | 2026-04-11 |
| Pipeline WebSocket 卡片可视化 (ADR-010: 0d-0e Pipeline 部分) | ✅ | 2026-04-11 |
详细变更记录见 Git history。
补齐数据采集管道和可视化,为后续所有开发提供可观测性。详见 ADR-010。聊天室全事件卡片统一详见 ADR-011。
| # | 模块 | 内容 | 依赖 |
|---|---|---|---|
| 0a | LLM Client 改造 |
chat_with_tools() 返回 usage 字段(prompt/completion/total tokens) |
无 |
| 0b | 三表采集管道 | llm_calls + tool_calls + events 三张表,engine.py/api.py 埋点写入 | #0a |
| 0c | 审计 API |
GET /api/audit/* 查询端点(按 run/agent/时间/类型过滤 + 汇总 + 时间线聚合) |
#0b |
| 0d | SSE 事件扩展 | 聊天室 SSE 流补全 llm_call / tool_call / skill_inject / agent_message / gate_* / boss_instruction 事件,统一带 source 字段 | #0b |
| 0e | 聊天窗卡片前端 | 8 种卡片渲染 + renderMessages() 混合卡片流 + 来源视觉区分(pipeline 左侧蓝线+标签)+ 折叠/展开/合并 | #0d |
| 0f | Token 面板 | 按 agent/stage/模型分组的消耗统计 + 成本估算 | #0b |
补齐 Agent 的记忆和决策能力,让 Agent 从"执行器"变成有认知的协作者。
| # | 模块 | 内容 | 依赖 |
|---|---|---|---|
| 1 | 短期记忆 | 内存 + JSON 落盘,Stage 结束摘要归档到项目记忆 | 无 |
| 2 | 项目记忆 | Markdown 文件 + grep 检索,存储在 .catown/memory/
|
#1 |
| 3 | Choice Box 交互组件 | 前端:单选/多选/确认/编辑组件,用于 BOSS 审批和决策 | 无 |
完善 BOSS 与系统的交互体验和 Agent 授权流程。
| # | 模块 | 内容 | 依赖 |
|---|---|---|---|
| 4 | 聊天框输入体验 | 消息历史(↑↓)、指令系统(/help 等)、输入联想补全 | #3 |
| 5 | 工具临时授权流程 | Agent 请求 → Choice Box → BOSS 审批(本次/本阶段/拒绝) | #3 |
| 6 | 知识图谱集成 | agents.json 中 developer/architect 加入 knowledge-graph skill;建图审批接入 Choice Box | #3, #5 |
从结构化存储升级到语义检索。
| # | 模块 | 内容 | 依赖 |
|---|---|---|---|
| 7 | 长期记忆 (ChromaDB) | Agent 级向量数据库,语义检索,跨项目保留 | #1, #2 |
| 8 | 睡眠整理调度器 | 空闲触发记忆压缩、短期→项目→长期迁移、不确定项提交 Choice Box | #1, #2, #3 |
多模态和专业 Agent 角色。
| # | 模块 | 内容 | 依赖 |
|---|---|---|---|
| 9 | OMNI 多模态集成 | 图片理解(P0)、视频/音频处理(P1) | 无 |
| 10 | UI/UX Pro Max Phase 2 | 截图对比、ui-designer Agent 角色、设计资产产出物 | #5 |
| 11 | Knowledge Graph 进阶 | 增量更新自动化、图谱可视化、Agent 建图自主决策 | #6, #7 |
- 提交原始需求后,Pipeline 自动执行 5 个阶段
- 每个阶段的 Agent 使用正确的 system_prompt 和工具
- 阶段产出物保存到 workspace,下一阶段能读取
- Gate=manual 的阶段暂停等待人工审批
- BOSS 可以通过 Web UI 暂停/继续/打回/审批
- Agent 间可以互相发消息,BOSS 能实时看到
- 每个 Agent 的 LLM 模型独立配置,来源 agents.json
- 错误自动重试,超过阈值暂停等人工
- 工具白名单运行时校验:Agent 仅能调用 agents.json 中声明的工具
- 项目 Workspace 隔离:路径穿越检测 + symlink 防护 + .catown 目录保护
- LLM 主配置来源 agents.json,密钥可通过
${LLM_API_KEY}/.env注入 - Pipeline 状态持久化到数据库
- Agent 协作消息持久化到数据库
- WebSocket 实时推送 Pipeline 状态变更
- _validate_path 统一路径校验(symlink 解析 + 目录穿越 + .catown 保护)
- _execute_tool 白名单校验(区分未配置/空列表/白名单三种状态)
- [~] Docker 部署正常 (Dockerfile/docker-compose.yml 已配置,待有 Docker 环境时验证)
- 总用例: 233
- 通过: 233
- 失败: 0
- 通过率: 100%
- 覆盖模块: Agent、API 路由、聊天室、协作工具、配置模型、核心模块、数据库、文件操作、LLM 客户端、两级 LLM 配置、启动流程、工具注册、WebSocket
- 总用例: 24
- 通过: 24
- 失败: 0
- 通过率: 100%
- 覆盖: 健康检查、Agent 注册(5 个 Pipeline 角色)、工具注册(14 个工具)、Pipeline API、配置管理、项目 CRUD、消息链路、协作状态
| # | 问题 | 修复 |
|---|---|---|
| 1 |
test_api_integration.py 引用旧 agent 名称(assistant/coder/reviewer/researcher) |
更新为 Pipeline 角色名(analyst/architect/developer/tester/release) |
| 2 |
test_api_integration.py 工具数量断言过时(==13) |
新增 read_file、write_file 工具检查 |
| 3 |
test_api_integration.py Agent 响应断言在无 LLM 环境失败 |
增加 LLM 不可用时的优雅跳过 |
| 4 |
test_api_integration.py 缺少 Pipeline API 测试 |
新增 Pipeline API 集成测试 |
| 5 |
test_regression.py 引用旧 agent 名称 |
更新为新角色名 |
| 6 |
test_regression_v3.py agent 数量断言(==4) |
更新为 5 |
| 7 |
requirements.txt 与 requirements-test.txt pytest 版本冲突 |
统一使用 pytest>=8.0 |
环境: Linux 6.8.0-100-generic, Python 3.12, 从 GitHub 重新 clone 独立验证。
-
命令:
python3 -m pytest backend/tests/ -v - 结果: 233/233 PASSED ✅
- 耗时: 79.17s
- 警告: 343(均为 SQLAlchemy/Pydantic/FastAPI 弃用警告,非功能性问题)
-
命令:
python3 tests/test_api_integration.py(需后端运行) - 结果: 24/24 PASSED ✅
- 覆盖: 健康检查、5 个 Pipeline 角色注册、14 个工具注册、Pipeline API、配置管理、项目 CRUD、消息链路、协作状态
- 结果: 10/14 PASSED(71%)
- 通过: API 端点(status/health/agents/tools)、消息发送、web_search、execute_code
-
失败分析:
-
GET /api/projects→ 预期有项目但无(测试环境无项目数据) -
Agent 自动响应→ 未配置 LLM,Agent 无法生成回复 -
retrieve_memory→ 未配置 LLM,Agent 未调用工具 -
GET / (前端)→ 前端服务未启动(端口 3001)
-
- 结论: 所有失败均为环境限制(无 LLM、无前端),非代码缺陷
-
TODO/FIXME: 仅 2 处
-
collaboration.py:80— 基类抽象方法raise NotImplementedError(设计模式,正确) -
test_chatroom.py:264— 注释中的旧 TODO,实际协作逻辑已完整实现
-
- 未完成功能: 无
系统所有核心功能已实现完成,单元测试和集成测试 100% 通过。回归测试中的失败均为测试环境限制(未配置 LLM、未启动前端),非代码质量问题。
环境: Linux 6.8.0-100-generic, Python 3.12.3, pytest 9.0.3。
-
命令:
python3 -m pytest backend/tests/ backend/test_pipeline.py -v - 结果: 252/252 PASSED ✅
- 耗时: 84.28s
-
命令:
python3 -m pytest tests/test_integration_e2e.py -v - 结果: 35/35 PASSED ✅
- 耗时: 9.80s
-
覆盖模块:
- 健康检查与状态 (3)
- Agent 注册与角色验证 (4)
- 项目 CRUD 完整流程 (5)
- 消息发送与接收 (1)
- Pipeline API 全生命周期:创建/启动/暂停/恢复/阶段查询 (5)
- 两级 LLM 配置管理 (4)
- 工具注册与执行 (2)
- Agent 间协作与任务委托 (3)
- 前端页面 (1)
- 完整业务流程:多阶段 Pipeline + 多项目并行 (2)
- 错误处理与边界情况 (5)
| # | 问题 | 修复 |
|---|---|---|
| 1 |
RateLimitMiddleware 在 TestClient 环境下 request.client 为 None 导致 500 |
增加空值保护:request.client.host if request.client else "testclient"
|
所有 287 个测试(252 单元 + 35 E2E 集成)100% 通过。系统功能完整,覆盖 PRD 中所有验收标准。
问题:页面刷新后,聊天消息和事件卡片全部丢失。
根因:
| 数据 | 存储 | 刷新后 | 说明 |
|---|---|---|---|
messages |
数据库(messages 表) |
❌ 丢失 | 数据库有数据但前端未调 loadMessages() 恢复 |
pipelineCards |
仅前端内存 | ❌ 丢失 | LLM/工具/Skill 卡片无持久化,仅 SSE/WS 实时推送 |
待修复:
-
Messages 恢复(简单):
selectProject()时调用GET /api/chatrooms/{id}/messages拉取历史消息 -
Pipeline Cards 恢复(需后端配合):
- 需要
GET /api/audit/timeline接口回放历史事件 - 或在
pipeline_stages/events表中存储卡片数据 - 前端页面加载时调用该接口恢复卡片流
- 需要
优先级:P2(不影响核心功能,但影响体验)
问题:所有 room 的 Agent 共享同一个文件目录,无项目级隔离。
现状:
| 路径 | Workspace | 问题 |
|---|---|---|
| Pipeline 引擎 | data/workspaces/run_{id} |
按 run 隔离,粒度应为 project |
| 聊天室 Tools | 全局 CATOWN_WORKSPACE 或 os.getcwd()
|
所有 room 共享,完全无隔离 |
PRD 设计(§6.1):
projects/
└── {project_id}/
├── PRD.md
├── tech-spec.md
├── src/
├── tests/
└── .catown/
待修复:
- 项目创建时自动创建
projects/{project_id}/目录 - 工具注册改为 per-project:每个 room 的 Agent 拿到指向自己项目目录的工具实例
-
_validate_path校验确保 Agent 无法跨项目读写 - Pipeline 引擎的 workspace 改为
projects/{project_id}/而非data/workspaces/run_{id}
优先级:P1(PRD 核心约束,影响多项目并行安全性)
cd backend && pip install -r requirements.txt推荐先运行 ./run.sh(Windows 用 run.bat)初始化 ${CATOWN_HOME:-~/.catown},然后编辑 ${CATOWN_HOME:-~/.catown}/config/agents.json。
源码模板位于 backend/configs/agents.json,首次启动会自动复制到运行时目录。在 global_llm 段设置 LLM 连接信息:
{
"global_llm": {
"provider": {
"baseUrl": "https://your-openai-compatible-endpoint.example/v1",
"apiKey": "${LLM_API_KEY}",
"models": [{ "id": "your-model-id", ... }]
},
"default_model": "your-model-id"
}
}也可在 ${CATOWN_HOME:-~/.catown}/.env 中配置:LLM_BASE_URL、LLM_API_KEY、LLM_MODEL。
./run.sh或手动启动:
cd backend && uvicorn main:app --reload --host 0.0.0.0 --port 8000- Web 界面: http://localhost:8000
- API 文档: http://localhost:8000/docs
检查 ${CATOWN_HOME:-~/.catown}/config/agents.json 中的 LLM 配置是否正确,API Key 是否有效。可通过 GET /api/config 确认当前配置。
确认 ${CATOWN_HOME:-~/.catown}/config/agents.json 中包含 6 个角色:analyst、architect、developer、tester、release、assistant。
查看后端日志,可能是 LLM 超时或工具执行失败。手动审批 Gate 或通过 API 打回重做。
docker-compose up -d需挂载 /var/lib/catown 持久化运行时数据;如需自定义配置,可挂载 /var/lib/catown/config/agents.json 或设置 CATOWN_HOME。
当前 7 个预置 Skill 全部是文本/代码导向。要让 Catown 成为真正的 AI 软件工厂,需要引入 UI/UX 专业设计类 Skill,让 Agent 能生成高质量前端界面并闭环验证。
| 能力 | 说明 |
|---|---|
| 视觉生成 | 生成 HTML/CSS/组件代码 |
| 视觉验证 | 截图预览,确认渲染效果 |
| 迭代闭环 | 生成 → 截图 → 对比 → 修改 |
| 设计规范注入 | 设计系统/tokens/组件库约束 |
| 响应式测试 | 多分辨率截图对比 |
| 设计稿解析 | 读取截图/设计稿并理解 |
| 维度 | 现状 | 差距 | 优先级 |
|---|---|---|---|
| Skill 配置框架 | ✅ 够用 | 无 | — |
| SOUL 注入 | ✅ 够用 | 无 | — |
| Pipeline 扩展 | ✅ 够用 | 无 | — |
| 工具层(screenshot/browser) | ✅ 已实现 | screenshot ✅ + browser ✅(Playwright) | — |
| 执行环境(Node.js/浏览器) | ✅ 已实现 | execute_code 支持 node 语言 | — |
| 专门 UI Agent 角色 | ❌ 缺失 | 需新增 | P1 |
| 截图式审计/记忆 | ❌ 缺失 | 需新增 | P1 |
| 设计资产产出物类型 | 需扩展 | P2 | |
| 设计稿解析 | ❌ 缺失 | 需新增 | P2 |
核心结论:Skill 配置框架和注入机制完全兼容,但工具层(screenshot + browser)和执行环境(Node.js)是硬瓶颈。
| 新增 | 说明 |
|---|---|
screenshot 工具 |
✅ 已实现 — Headless Chromium 截图,支持全页面/指定元素/多分辨率 |
browser 工具 |
✅ 已实现 — Playwright 自动化(navigate/click/fill/type/screenshot/evaluate 等 15 个动作) |
execute_code 增强 |
✅ 已实现 — 支持 Python + Node.js 双语言沙箱 |
ui-designer Agent |
专门的 UI 设计师角色,独立 SOUL |
| 新增 | 说明 |
|---|---|
| 截图对比能力 | baseline vs actual 差异检测 |
| 截图式审计 | 截图存入审计日志和记忆体系 |
ui-ux-pro-max Skill |
完整的 prompt_fragment + 工具绑定 |
| 新增 | 说明 |
|---|---|
| 设计稿解析 | 图片 → 结构化需求 |
| 多分辨率响应式测试 | 自动化 viewport 切换 |
| 设计资产产出物管理 | design_spec/component/screenshot 类型 |
| 模块 | 改动 |
|---|---|
工具注册 (tools/) |
新增 screenshot、browser 工具实现 |
execute_code |
增加 Node.js 运行时支持 |
agents.json |
新增 ui-designer 角色 |
skills.json |
新增 ui-ux-pro-max Skill |
pipelines.json |
Pipeline 中可引用 ui-designer |
| 审计体系 | 支持截图类型的审计记录 |
| 记忆体系 | 支持截图标注存入长期记忆 |
| 产出物模型 | 新增设计资产类型 |
| 前端 Dashboard | 产出物预览支持截图展示 |
详见 ADR-007。
Catown 多 Agent 工作流中,Agent 需要理解项目代码结构才能高效协作。当前通过 read_file 逐个读取文件,效率低、缺乏全局视角、新 Agent 入驻慢。需要引入代码知识图谱能力,让 Agent 快速获取项目的结构化知识。
采用方案 A:Skills 集成,建图需人控,查询 Agent 自主。(详见 ADR-004)
核心原则:建图由人决策,查询由 Agent 自主。
| 操作 | 决策方 | 理由 |
|---|---|---|
建图(graphify . --no-viz) |
BOSS 审批 | 需要 LLM API 调用,有时间和费用成本;不是所有项目都需要知识图谱 |
查询(graphify query) |
Agent 自主 | 纯本地计算,毫秒级响应,无成本 |
增量更新(graphify . --update) |
BOSS 审批 | 同样涉及 LLM API 调用 |
{
"knowledge-graph": {
"name": "知识图谱",
"description": "基于 graphify 构建和查询项目代码知识图谱",
"required_tools": ["execute_code", "read_file", "write_file"],
"category": "analysis",
"levels": {
"hint": "知识图谱: 代码任务前检查 graphify-out/,查询为本地计算无需审批",
"guide": "## 知识图谱\n- 处理代码相关任务前,检查项目中是否存在 graphify-out/graph.json\n- 不存在 → 向 BOSS 请求建图许可\n- 已存在 → 可直接读取 GRAPH_REPORT.md 获取项目结构概览\n- 具体查询 → 自主执行 graphify query(无需审批)\n- 项目文件变更后 → 向 BOSS 请求增量更新许可",
"full": "## 知识图谱完整指南\n\n### 建图(需 BOSS 审批)\n```bash\ngraphify . --no-viz\n```\n\n### 查询(Agent 自主)\n```bash\ngraphify query \"模块 A 依赖哪些外部库\" --graph graphify-out/graph.json\n```\n\n### 产出物\n- graphify-out/graph.json — 可查询的图数据\n- graphify-out/GRAPH_REPORT.md — 结构概览\n- graphify-out/cache/ — 增量更新缓存"
}
}
}| Agent | 是否配置 | 理由 |
|---|---|---|
| developer | ✅ | 核心使用者,编码时频繁需要理解代码结构 |
| architect | ✅ | 设计架构时需要了解现有代码依赖 |
| analyst | 可选 | 需求分析阶段可能代码尚未存在 |
| tester | 可选 | 测试时可能需要理解代码结构 |
| release | ❌ | 发布阶段不涉及代码理解 |
| 模块 | 改动 | 状态 |
|---|---|---|
configs/skills.json |
新增 knowledge-graph skill 定义(hint/guide/full 三级) | ✅ 完成 |
configs/agents.json |
developer/architect 的 skills 列表加入 knowledge-graph | ⏳ 待做 |
tools/execute_code.py |
用于执行 graphify 命令 | ✅ 无改动(已支持) |
| Agent 建图审批流程 | Agent 发起建图请求 → Choice Box → BOSS 审批 | ⏳ 待做(依赖 Choice Box) |
为什么不选方案 B(Pipeline 集成):
- 不是所有项目都需要;BOSS 失去控制权;graphify 快速迭代,锁定在 pipeline 里维护成本高
为什么不选方案 C(纯手动):
- Agent 无法自主触发;无法融入 Agent 上下文
为什么方案 A 最优:
- 按需激活、成本可控、查询零成本、与 Skills 体系天然契合、独立升级
Catown 6 个 Agent 在 Pipeline 执行中产生大量工具调用输出(代码读取、测试结果、Git 操作、构建日志),直接进入 LLM 上下文窗口。一个中型项目的完整 Pipeline 执行,工具输出可达 100K+ tokens,导致:
- Token 成本飙升
- 上下文窗口被噪声占据,Agent 推理质量下降
- 长对话中关键信息注意力分散
需要在工具执行层引入上下文压缩机制,在不修改 Agent prompt 和 SOUL 体系的前提下,降低全链路 token 消耗。
详细竞品分析见 ADR-009。
| 需求 ID | 需求名称 | 优先级 | 描述 |
|---|---|---|---|
| CC-001 | 工具输出过滤器框架 | P0 | 通用 OutputFilter 模块,按命令类型路由到对应过滤器,支持过滤器注册扩展 |
| CC-002 | 测试输出过滤 | P0 | 状态机解析 pytest/vitest/cargo test/npm test 输出,仅保留失败用例详情 |
| CC-003 | Git 输出过滤 | P0 | 统计提取:status→文件计数、diff→+N/-N、log→提交数+统计、commit/push→ok hash |
| CC-004 | 构建输出过滤 | P0 | 仅保留 error/warning 行,丢弃 stdout 正常输出 |
| CC-005 | Lint 输出过滤 | P1 | 按 error code/rule 分桶计数,按频率降序排列 |
| CC-006 | 文件读取过滤 | P1 | 三级代码过滤:None/Minimal(去注释)/Aggressive(去函数体) |
| CC-007 | 通用过滤器 | P2 | 相邻重复行合并计数 + ANSI 转义序列剥离 |
| CC-008 | Tee 机制 | P0 | 过滤前的原始输出备份到 .catown/tee/,失败时可追溯 |
| CC-009 | Token 追踪 | P1 | 每次工具调用记录原始/过滤后 token 数和压缩率,持久化到 SQLite |
| CC-010 | 跨阶段摘要 | P0 | Agent stage 结束后生成结构化摘要 JSON,注入下一阶段 Agent 上下文 |
| CC-011 | Dashboard Token Savings 面板 | P1 | 前端展示实时压缩率、累计节省、按命令类型分布、趋势图 |
用户故事:作为系统,我需要一个通用的输出过滤框架,使每种工具命令能自动应用对应的压缩策略。
功能要求:
- OutputFilter 类作为过滤器入口,接收 (command, raw_output, exit_code) 参数
- 基于命令前缀的路由机制(如
git status→ git_filter,pytest→ test_filter) - BaseFilter 抽象类定义 apply(raw_output, exit_code) → str 接口
- 过滤器通过 register() 注册,支持动态扩展
- 过滤失败时自动 fallback 到原始输出(Fail-Safe)
非功能要求:
- 过滤延迟 < 5ms(纯字符串处理,无网络/模型调用)
- 不引入额外依赖(标准库 re + json 足够)
验收标准:
- 注册 3 个以上过滤器后,路由正确率 100%
- 过滤器抛异常时返回原始输出并记录错误日志
用户故事:作为 Developer/Tester Agent,我希望测试输出只包含失败用例信息,不需要看到通过的测试。
功能要求:
- 支持 pytest(文本状态机)、vitest/jest(JSON + 文本)、cargo test(Rust test output)、go test(NDJSON)
- 状态机解析:IDLE → TEST_START → PASSED/FAILED → SUMMARY
- 输出格式:FAILED: N/M tests + 失败用例名称 + 失败详情(文件:行号 + assertion)
- 成功用例不输出(或仅输出计数)
验收标准:
- 100 个测试 98 通过 2 失败 → 输出约 20 行(而非 200+ 行)
- 压缩率 ≥ 90%
用户故事:作为全链路 Agent,我希望 Git 操作的输出精简但信息完整。
功能要求:
-
git status→ 修改文件数 + 分类(modified/added/deleted) -
git diff→ 变更统计(N files changed, +X, -Y),不输出完整 diff 内容 -
git log→ 提交数 + 统计(+X/-Y) -
git add→ "ok" -
git commit→ "ok {short_hash}" -
git push→ "ok {branch}" -
git pull→ "ok N files +X -Y"
验收标准:
- git status 输出从 ~50 行压缩到 1-3 行
- 压缩率 ≥ 75%
用户故事:作为 Developer Agent,我只关心构建是否成功以及失败原因。
功能要求:
- 识别 exit_code:0 → "Build succeeded"
- exit_code != 0 → 提取 stderr 中的 error/warning 行
- 支持 cargo build、npm run build、go build
- strip ANSI 转义序列
验收标准:
- 成功构建输出 ≤ 1 行
- 失败构建仅输出 error 行(去除编译进度、链接信息等噪声)
- 压缩率 ≥ 60%
用户故事:作为 Tester Agent,我希望 lint 结果按规则分组,一眼看到问题分布。
功能要求:
- 支持 ruff(JSON 模式)、eslint(JSON 模式)、tsc、golangci-lint
- 按 error code/rule 分桶计数
- 按违规数量降序排列
- 附带受影响文件列表(去重)
验收标准:
- 100 条 lint 错误 → 约 5 行摘要
- 压缩率 ≥ 80%
用户故事:作为所有 Agent,我需要按需控制读取代码的详细程度。
功能要求:
- 三级过滤:None(原样)/ Minimal(去注释)/ Aggressive(去函数体)
- 支持语言:Rust、Python、JS/TS、Go、C/C++、Java、Ruby、Shell
- Minimal:删除单行注释、块注释,保留 doc comments,合并空行
- Aggressive:保留 import + 函数/类签名,丢弃函数体
- Data 格式(JSON/YAML/TOML)不进行代码过滤
验收标准:
- Minimal 压缩率 20-40%
- Aggressive 压缩率 60-90%
- 过滤后代码仍可识别结构(类名、方法签名、import 清晰)
用户故事:作为 BOSS/Agent,当过滤后的输出信息不足时,我能追溯到原始输出。
功能要求:
- 过滤前自动备份原始输出到
.catown/tee/{timestamp}_{command}.log - 保留最近 N 个文件(默认 50),超出自动清理
- FilterResult 中附带 tee_path
- 输出末尾追加
[full output: .catown/tee/xxx.log]标记
验收标准:
- 过滤后输出包含 tee 路径引用
- tee 文件内容与原始输出完全一致
用户故事:作为 BOSS,我能看到每次工具调用和每个 Pipeline 阶段的 token 节省数据。
功能要求:
- 每次工具调用记录:command、raw_tokens、filtered_tokens、savings_pct、timestamp
- 每个 Pipeline 阶段汇总:总输入 token、总输出 token、总节省
- SQLite 持久化(复用现有数据库或新建 token_tracking 表)
- API 端点:GET /api/token-savings(支持按日期/阶段/命令类型过滤)
验收标准:
- 每次工具调用后 token 数据正确写入
- API 返回数据与实际过滤结果一致
用户故事:作为 Pipeline 引擎,我希望下游 Agent 只拿到上游的关键结论,而非完整对话历史。
功能要求:
- 每个 Agent stage 结束后,引擎提取结构化摘要:
- stage 名称
- 产出物列表(文件路径)
- 关键决策(字符串列表)
- 指标数据(dict)
- 警告/风险(字符串列表)
- 下游 Agent 的上下文注入摘要 JSON,替代上游完整消息历史
- 原始对话归档到
.catown/stages/{stage_id}/history.json
验收标准:
- 摘要 JSON 格式正确,包含所有必填字段
- 下游 Agent 能基于摘要理解上游结果并正常执行
- 原始历史可追溯
用户故事:作为 BOSS,我能在 Web UI 上看到 token 节省的实时数据。
功能要求:
- 面板位置:Pipeline Dashboard 新增 Tab / 卡片
- 展示内容:
- 当前 Pipeline 累计 token 节省(数字 + 百分比)
- 按命令类型分布(饼图/柱状图)
- 按时间趋势(折线图,最近 30 次调用)
- Top 5 最高效过滤(节省最多的命令)
- 数据来源:CC-009 的 API 端点
验收标准:
- 面板数据与 token_tracking 表一致
- 页面加载时间 < 2s
| 阶段 | 需求 | 预计工时 | 产出 |
|---|---|---|---|
| Phase 1 | CC-001 框架 + CC-002/003/004 P0 过滤器 + CC-008 Tee | 3 天 | output_filter.py + 3 个过滤器 + tee 机制 |
| Phase 2 | CC-010 跨阶段摘要 | 2 天 | Pipeline 引擎摘要提取 + 上下文注入 |
| Phase 3 | CC-005/006 P1 过滤器 + CC-009 Token 追踪 + CC-011 Dashboard | 3 天 | 2 个过滤器 + tracking + 面板 |
| Phase 4 | CC-007 通用过滤器 | 1 天 | generic_filter.py |
| 场景 | 当前 token 消耗 | 压缩后 | 节省 |
|---|---|---|---|
| 单次 Pipeline (小型项目) | ~80K | ~20K | -75% |
| 单次 Pipeline (中型项目) | ~200K | ~50K | -75% |
| 测试输出 (pytest) | ~25K | ~2.5K | -90% |
| Git 操作 (20 次) | ~15K | ~3K | -80% |
- Agent 零改动:过滤在工具执行层完成,不改 Agent prompt、SOUL、配置
- Fail-Safe:过滤失败必须 fallback 到原始输出
- 可追溯:所有被过滤掉的信息通过 tee 机制可恢复
- 不引入外部依赖:纯 Python 标准库实现(re、json、sqlite3)
| 现有模块 | Pipeline 中的用途 | 改动量 | 状态 |
|---|---|---|---|
config.py |
已去掉 LLM 配置,仅保留基础设施 | — | ✅ 完成 |
llm/client.py |
已改为 per-agent 客户端工厂 | — | ✅ 完成 |
models/database.py |
新增 5 张 Pipeline 表 | 中 | ✅ 完成 |
backend/configs/agents.json |
改为 6 个 Agent 角色模板(5 个 Pipeline + 1 个助理),运行时复制到 ${CATOWN_HOME}/config/agents.json
|
— | ✅ 完成 |
backend/configs/pipelines.json |
新增,默认 5 阶段模板,运行时复制到 ${CATOWN_HOME}/config/pipelines.json
|
— | ✅ 完成 |
pipeline/config.py |
新增,配置加载器 | — | ✅ 完成 |
pipeline/engine.py |
新增,Pipeline 引擎核心 | 大 | ✅ 完成 |
routes/pipeline.py |
新增,Pipeline API 路由 | 中 | ✅ 完成 |
agents/collaboration.py |
Agent 间消息路由,接入 Pipeline | 中 | ✅ 完成 |
agents/registry.py |
注册新角色(已由 agents.json 自动加载) | 小 | ✅ 完成 |
agents/core.py |
Agent 基类不变 | 无 | — |
routes/api.py |
保留现有 API,新增 pipeline 路由 | 小 | ✅ 完成 |
frontend/index.html |
新增 Pipeline Dashboard section | 中 | ✅ 完成 |
- Git history — 详细变更记录
- ADR-010: 监控审计与交互可视化
- ADR-011: 聊天室全事件卡片统一