--- 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 `: 调用 `AgentKitClient.get_task_status()` - `task list`: 调用 `AgentKitClient.list_tasks()`,Rich 表格输出 - `task cancel `: 调用 `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 ` 显示任务状态 - `agentkit task list` 列出所有任务 - `agentkit task list --status completed` 过滤已完成任务 - `agentkit task cancel ` 取消运行中任务 - `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 `: 从 YAML 文件加载技能到 Registry - `skill info `: 显示技能详情(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 依赖 U1(Dockerfile 需要 CLI 入口)。U6 依赖所有前置单元。