fischer-agentkit/docs/plans/2026-06-05-007-feat-agentki...

317 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
status: active
date: 2026-06-05
---
# feat: AgentKit CLI + 独立部署能力
**类型**: feat
**文件**: `docs/plans/2026-06-05-007-feat-agentkit-cli-deployment-plan.md`
**深度**: Standard — 新增 CLI 模块 + 部署配置改造,涉及 6 个新文件 + 4 个修改
---
## 问题框架
AgentKit v2 Phase 1 + Phase 2 已实现 12 个核心模块、544 个测试通过,但**无法独立部署和使用**
1. **无 CLI** — 没有 `agentkit` 命令行工具,只能写 Python 脚本或手动敲 uvicorn 命令
2. **无 `__main__.py`** — 不能 `python -m agentkit` 启动
3. **无 `init` 脚手架** — 新用户不知道如何初始化配置
4. **Dockerfile 硬编码 GEO**`CMD` 直接调用 `configs.geo_server`,不是通用入口
5. **无生产级 docker-compose** — 只有 `docker-compose.test.yml`(测试用),缺少生产部署配置
---
## 架构总览
```
agentkit CLI (Typer)
├── agentkit init → 生成 agentkit.yaml + .env.example + skills/ + docker-compose.yaml
├── agentkit serve → uvicorn agentkit.server.app:create_app --factory
├── agentkit task submit → AgentKitClient.submit_task()
├── agentkit task status → AgentKitClient.get_task_status()
├── agentkit task list → AgentKitClient.list_tasks()
├── agentkit task cancel → AgentKitClient.cancel_task()
├── agentkit skill list → SkillRegistry.list_skills() (本地) 或 API (远程)
├── agentkit skill load → SkillLoader.load_from_file() (本地)
├── agentkit skill info → Skill 详情
├── agentkit usage → LLMGateway.get_usage_summary()
├── agentkit health → /api/v1/health
└── agentkit version → importlib.metadata.version()
```
**核心设计决策**CLI 是**薄封装层**,底层复用已有的 `AgentKitClient`(远程模式)和 `create_app()` + 各 Registry本地模式
---
## 关键技术决策
### KTD-1: CLI 框架选择 Typer
**决策**: 使用 Typer而非 Click 或 argparse
**理由**:
- 与 FastAPI 同作者,类型注解驱动,团队学习成本最低
- 底层基于 Click可无缝使用 Click 生态
- Rich 集成提供开箱即用的彩色输出、表格、进度条
- 自动生成帮助文档和 shell 补全
- 项目已使用 Pydantic v2 + 类型注解Typer 风格完美契合
### KTD-2: 双模式运行(本地 vs 远程)
**决策**: CLI 支持两种运行模式
- **本地模式**(默认): 直接 import 模块执行,无需 Server 运行
- **远程模式**`--server-url`: 通过 HTTP API 调用 AgentKit Server
**理由**: 开发调试时直接本地运行更方便;生产环境通过 Server 远程调用更安全。`agentkit task submit` 在本地模式下直接创建 Agent 执行,在远程模式下调用 API。
### KTD-3: 配置文件格式 agentkit.yaml
**决策**: 使用 YAML 格式,支持 `${ENV_VAR}` 环境变量替换
**理由**: 与现有 `configs/llm_config.yaml` 格式一致,复用 `_substitute_env_vars()` 逻辑。YAML 比 TOML 更适合嵌套配置,比 JSON 支持注释。
### KTD-4: Dockerfile 入口改为 CLI
**决策**: Dockerfile `ENTRYPOINT` 改为 `agentkit` CLI`CMD` 默认 `serve`
**理由**: 统一入口,支持 `docker run agentkit task submit ...` 等一次性命令,比硬编码 uvicorn 更灵活。
---
## 实施单元
### U1. CLI 框架搭建 + `serve` + `version` + `health`
**Goal**: 建立 CLI 模块骨架,实现最基础的 3 个命令
**Dependencies**: 无
**Files**:
- `src/agentkit/cli/__init__.py` (新建)
- `src/agentkit/cli/main.py` (新建) — Typer app + serve/version/health 命令
- `src/agentkit/__main__.py` (新建) — `python -m agentkit` 入口
- `pyproject.toml` (修改) — 添加 `typer>=0.12` 依赖 + `[project.scripts]` 入口点
- `Dockerfile` (修改) — ENTRYPOINT 改为 `agentkit`
**Approach**:
- `main.py` 创建 `app = typer.Typer()` 并注册子命令
- `serve` 命令调用 `uvicorn.run()` 启动 `create_app()` 工厂函数
- `version` 命令使用 `importlib.metadata.version("fischer-agentkit")`
- `health` 命令调用 `http://localhost:{port}/api/v1/health`
- `__main__.py` 简单调用 `app()`
- pyproject.toml 添加 `[project.scripts] agentkit = "agentkit.cli.main:app"`
**Test scenarios**:
- `agentkit version` 输出正确版本号
- `agentkit serve --help` 显示帮助信息
- `agentkit health` 在 server 未运行时返回连接错误
- `agentkit health` 在 server 运行时返回健康状态
- `python -m agentkit version` 等同于 `agentkit version`
- Dockerfile ENTRYPOINT 正确执行 `agentkit serve`
**Verification**: `pip install -e . && agentkit version` 输出版本号
---
### U2. `task` 命令组submit/status/list/cancel
**Goal**: 实现任务管理的 CLI 命令
**Dependencies**: U1
**Files**:
- `src/agentkit/cli/task.py` (新建) — task 子命令组
- `src/agentkit/cli/main.py` (修改) — 注册 task 子命令
**Approach**:
- `task submit`:
- 本地模式: 创建 Agent → 执行任务 → 输出结果
- 远程模式: `AgentKitClient.submit_task()` / `submit_task_async()`
- `--mode sync|async` 控制同步/异步
- `--stream` 启用 SSE 流式输出
- `task status <task_id>`: 调用 `AgentKitClient.get_task_status()`
- `task list`: 调用 `AgentKitClient.list_tasks()`Rich 表格输出
- `task cancel <task_id>`: 调用 `AgentKitClient.cancel_task()`
- 输入数据通过 `--input` 参数JSON 字符串)或 `--input-file` 参数JSON 文件路径)
**Test scenarios**:
- `agentkit task submit --skill content_generator --input '{"topic":"AI"}'` 提交同步任务
- `agentkit task submit --mode async --skill content_generator --input '{"topic":"AI"}'` 返回 task_id
- `agentkit task status <task_id>` 显示任务状态
- `agentkit task list` 列出所有任务
- `agentkit task list --status completed` 过滤已完成任务
- `agentkit task cancel <task_id>` 取消运行中任务
- `agentkit task submit --input-file input.json` 从文件读取输入
- 远程模式下所有命令正确调用 API
- 本地模式下直接执行无需 Server
**Verification**: `agentkit task submit --help` 显示完整帮助
---
### U3. `skill` 命令组list/load/info
**Goal**: 实现技能管理的 CLI 命令
**Dependencies**: U1
**Files**:
- `src/agentkit/cli/skill.py` (新建) — skill 子命令组
- `src/agentkit/cli/main.py` (修改) — 注册 skill 子命令
**Approach**:
- `skill list`: 列出已注册技能Rich 表格输出name, mode, description
- `skill load <path>`: 从 YAML 文件加载技能到 Registry
- `skill info <name>`: 显示技能详情config 完整信息)
- 本地模式直接操作 SkillRegistry远程模式调用 `/api/v1/skills` API
**Test scenarios**:
- `agentkit skill list` 列出所有技能
- `agentkit skill load ./my_skill.yaml` 加载技能
- `agentkit skill info content_generator` 显示技能详情
- 无技能注册时 `skill list` 显示空列表
- 加载无效 YAML 文件报错
**Verification**: `agentkit skill list` 输出技能表格
---
### U4. `init` 命令 + `usage` 命令
**Goal**: 实现项目初始化和用量查询
**Dependencies**: U1
**Files**:
- `src/agentkit/cli/init.py` (新建) — init 命令
- `src/agentkit/cli/usage.py` (新建) — usage 命令
- `src/agentkit/cli/main.py` (修改) — 注册 init/usage 子命令
- `src/agentkit/cli/templates.py` (新建) — 模板文件内容agentkit.yaml、.env.example、docker-compose.yaml、示例 skill
**Approach**:
- `init` 命令:
- 交互式引导(使用 Typer `prompt`)或 `--non-interactive` 使用默认值
- 生成文件: `agentkit.yaml`, `.env.example`, `skills/example_skill.yaml`, `docker-compose.yaml`
- `agentkit.yaml` 包含 server/llm/memory/skills/logging 配置
- `.env.example` 包含 API key 占位符
- `docker-compose.yaml` 包含 agentkit + redis + postgres 服务
- 如果文件已存在,询问是否覆盖
- `usage` 命令:
- 本地模式: 从 LLMGateway.UsageTracker 获取统计
- 远程模式: 调用 `/api/v1/llm/usage` API
- `--agent` 过滤特定 Agent
- `--format table|json` 输出格式
**Test scenarios**:
- `agentkit init` 在空目录生成完整配置文件
- `agentkit init --non-interactive` 使用默认值生成
- `agentkit init` 文件已存在时提示覆盖
- 生成的 `agentkit.yaml` 包含所有必要配置段
- 生成的 `.env.example` 包含 API key 占位符
- 生成的 `docker-compose.yaml` 包含 3 个服务
- `agentkit usage` 显示用量统计表格
- `agentkit usage --agent content_generator` 过滤特定 Agent
- `agentkit usage --format json` 输出 JSON 格式
**Verification**: `mkdir /tmp/test-init && cd /tmp/test-init && agentkit init && ls -la` 看到生成的文件
---
### U5. Dockerfile 改造 + 生产级 docker-compose
**Goal**: 改造部署配置,支持 CLI 入口 + 生产部署
**Dependencies**: U1
**Files**:
- `Dockerfile` (修改) — ENTRYPOINT 改为 `agentkit`
- `docker-compose.yaml` (新建) — 生产部署配置
- `.dockerignore` (修改/新建) — 排除 tests/docs
**Approach**:
- Dockerfile:
- `ENTRYPOINT ["agentkit"]`
- `CMD ["serve", "--host", "0.0.0.0", "--port", "8001"]`
- 复制 `configs/` 目录到镜像
- 保持多阶段构建 + 非 root 用户
- docker-compose.yaml:
- `agentkit` 服务: build ., command: serve, ports: 8001, env_file: .env
- `redis` 服务: redis:7-alpine, healthcheck
- `postgres` 服务: pgvector/pgvector:pg15, healthcheck, volume
- `agentkit` depends_on redis + postgres (condition: service_healthy)
- `.dockerignore`: 排除 tests/, docs/, .git/, __pycache__/
**Test scenarios**:
- `docker build -t agentkit .` 构建成功
- `docker run agentkit version` 输出版本号
- `docker run agentkit serve` 启动 Server
- `docker-compose up` 启动完整环境
- `docker-compose exec agentkit agentkit health` 健康检查通过
**Verification**: `docker build -t agentkit . && docker run agentkit version`
---
### U6. README 更新 + 集成测试
**Goal**: 更新文档,添加 CLI 使用示例,编写集成测试
**Dependencies**: U1-U5
**Files**:
- `README.md` (修改) — 添加 CLI 使用章节
- `tests/unit/test_cli.py` (新建) — CLI 命令测试
**Approach**:
- README 添加:
- CLI 安装和快速开始
- 所有命令的使用示例
- Docker 部署说明
- `agentkit init` 生成的文件结构说明
- 测试:
- 使用 `typer.testing.CliRunner` 测试所有命令
- Mock 远程 API 调用
- 测试 init 生成的文件内容
**Test scenarios**:
- `agentkit --help` 显示所有子命令
- `agentkit task --help` 显示 task 子命令
- `agentkit init --non-interactive` 生成正确文件
- `agentkit skill list` 在无技能时显示空列表
- `agentkit version` 输出格式正确
- `agentkit usage` 在无用量时显示空表格
**Verification**: `pytest tests/unit/test_cli.py -v` 全部通过
---
## 范围边界
### 包含
- CLI 模块Typer 框架)
- `__main__.py` 入口
- `init` 脚手架生成
- Dockerfile 改造
- 生产级 docker-compose
- README 更新
### 不包含
- 交互式 REPL 模式(后续可加)
- Web UI 管理界面
- CI/CD pipeline 配置
- Kubernetes 部署配置
- 插件市场/注册中心
---
## 执行顺序
```
U1 (CLI 骨架) → U2 (task) + U3 (skill) + U4 (init/usage) 并行 → U5 (Docker) → U6 (README + 测试)
```
U2/U3/U4 互相独立可并行实现。U5 依赖 U1Dockerfile 需要 CLI 入口。U6 依赖所有前置单元。