# Phase T.1:Manifest 驱动系统 日期:2026-04-04 状态:待开始 依赖:T.0(已完成) --- ## 1. 本阶段目的 建立 Jarvis 的 Manifest 驱动工具系统: - 定义工具 Manifest Schema - 实现 Schema 验证 - 创建核心工具的 Manifest 文件 - 实现配置分离 --- ## 2. Manifest Schema 设计 ### 2.1 目录结构 ``` backend/app/tools/ ├── manifests/ # 工具 manifest │ ├── file_operator.yaml │ ├── search.yaml │ └── web_fetch.yaml ├── schemas/ # Schema 定义 │ ├── __init__.py │ ├── manifest.py # Manifest Schema │ ├── tool_call.py # 工具调用 Schema │ └── config.py # 配置 Schema └── configs/ # 配置分离 └── .tool.example # 工具配置模板 ``` ### 2.2 ToolManifest Schema ```python # tools/schemas/manifest.py from pydantic import BaseModel, Field from typing import Optional, List, Dict, Any from enum import Enum class ToolType(str, Enum): """工具类型""" SYNC = "sync" # 同步执行 ASYNC = "async" # 异步执行 SERVICE = "service" # 持续服务 class RuntimeType(str, Enum): """运行时类型""" PYTHON = "python" JAVASCRIPT = "javascript" NATIVE = "native" class InvocationCommand(BaseModel): """调用命令定义""" name: str = Field(..., description="命令名称") description: str = Field(..., description="命令描述(给 AI 看)") parameters: Optional[Dict[str, Any]] = Field( default=None, description="参数 JSON Schema" ) required: Optional[List[str]] = Field( default=None, description="必需参数列表" ) example: Optional[str] = Field( default=None, description="调用示例" ) class ToolManifest(BaseModel): """工具 Manifest""" manifest_version: str = Field( default="1.0.0", description="Manifest 版本" ) name: str = Field(..., description="工具名称(英文,唯一)") display_name: str = Field(..., description="显示名称(中文)") description: str = Field(..., description="工具描述") author: Optional[str] = Field(default=None, description="作者") version: str = Field(default="1.0.0", description="版本号") # 执行配置 type: ToolType = Field(default=ToolType.SYNC, description="工具类型") runtime: RuntimeType = Field(default=RuntimeType.PYTHON, description="运行时") entry: str = Field(..., description="执行入口(文件路径或命令)") timeout: int = Field(default=30000, description="超时时间(毫秒)") # 配置 config_schema: Optional[Dict[str, Any]] = Field( default=None, description="配置项 Schema" ) # 能力 commands: List[InvocationCommand] = Field( default_factory=list, description="可用命令列表" ) # 元数据 tags: Optional[List[str]] = Field(default=None, description="标签") dependencies: Optional[List[str]] = Field(default=None, description="依赖工具") enabled: bool = Field(default=True, description="是否启用") class Config: use_enum_values = True ``` ### 2.3 ToolCall Schema ```python # tools/schemas/tool_call.py from pydantic import BaseModel, Field from typing import Optional, Dict, Any, List from datetime import datetime class ToolCallRequest(BaseModel): """工具调用请求""" tool_name: str = Field(..., description="工具名称") command: str = Field(..., description="命令名称") parameters: Dict[str, Any] = Field(default_factory=dict, description="参数") timeout: Optional[int] = Field(default=None, description="超时时间") context: Optional[Dict[str, Any]] = Field( default=None, description="上下文信息" ) class ToolCallResponse(BaseModel): """工具调用响应""" status: str = Field(..., description="状态: success/error") result: Optional[Any] = Field(default=None, description="执行结果") error: Optional[str] = Field(default=None, description="错误信息") message: Optional[str] = Field(default=None, description="AI 友好消息") base64: Optional[str] = Field(default=None, description="Base64 数据") duration_ms: Optional[int] = Field(default=None, description="执行耗时") timestamp: datetime = Field(default_factory=datetime.utcnow) class ToolExecutionLog(BaseModel): """工具执行日志""" id: str tool_name: str command: str parameters: Dict[str, Any] status: str duration_ms: int error: Optional[str] user_id: Optional[str] agent_id: Optional[str] created_at: datetime ``` --- ## 3. Manifest 示例 ### 3.1 file_operator.yaml ```yaml manifest_version: "1.0.0" name: file_operator display_name: 文件操作器 description: 强大的文件系统操作工具,支持读写、搜索、下载等功能 author: Jarvis version: "1.0.0" type: sync runtime: python entry: tools/implementations/file_operator.py timeout: 30000 config_schema: allowed_directories: type: string description: 允许操作的目录列表,逗号分隔 default: "" max_file_size: type: integer description: 最大文件大小(字节) default: 10485760 commands: - name: read_file description: | 读取指定路径文件的内容。支持 PDF、DOCX、XLSX 等格式自动解析。 参数: - filePath (必需): 文件绝对路径 - encoding (可选): 编码格式,默认 utf8 parameters: type: object properties: filePath: type: string description: 文件绝对路径 encoding: type: string default: utf8 required: [filePath] - name: write_file description: | 将内容写入文件。如果文件存在,自动创建新文件避免覆盖。 参数: - filePath (必需): 文件绝对路径 - content (必需): 文件内容 parameters: type: object properties: filePath: type: string content: type: string required: [filePath, content] - name: list_directory description: | 列出目录内容。 参数: - directoryPath (必需): 目录绝对路径 - showHidden (可选): 是否显示隐藏文件 parameters: type: object properties: directoryPath: type: string showHidden: type: boolean default: false required: [directoryPath] - name: search_files description: | 递归搜索匹配模式的文件。 参数: - searchPath (必需): 搜索起始目录 - pattern (必需): 文件模式,如 *.txt parameters: type: object properties: searchPath: type: string pattern: type: string required: [searchPath, pattern] tags: [file, system, essential] enabled: true ``` ### 3.2 search.yaml ```yaml manifest_version: "1.0.0" name: web_search display_name: 联网搜索 description: 语义级并发搜索引擎,支持多源搜索和结果聚合 author: Jarvis version: "1.0.0" type: sync runtime: python entry: tools/implementations/web_search.py timeout: 60000 config_schema: api_key: type: string description: 搜索引擎 API 密钥 required: true max_results: type: integer description: 最大返回结果数 default: 10 commands: - name: search description: | 执行语义级搜索。 参数: - query (必需): 搜索关键词 - max_results (可选): 最大结果数 - sources (可选): 搜索源列表 parameters: type: object properties: query: type: string max_results: type: integer default: 10 sources: type: array items: type: string required: [query] - name: deep_search description: | 深度搜索,带摘要生成。 参数: - query (必需): 研究主题 - keywords (必需): 关键词列表 parameters: type: object properties: query: type: string keywords: type: array items: type: string required: [query, keywords] tags: [search, web, research] enabled: true ``` --- ## 4. Schema 验证 ### 4.1 验证器 ```python # tools/schemas/validator.py from pydantic import ValidationError from tools.schemas.manifest import ToolManifest def validate_manifest(data: dict) -> ToolManifest: """验证 Manifest 数据""" try: return ToolManifest(**data) except ValidationError as e: raise ManifestValidationError(str(e)) def validate_tool_call(data: dict) -> ToolCallRequest: """验证工具调用请求""" from tools.schemas.tool_call import ToolCallRequest try: return ToolCallRequest(**data) except ValidationError as e: raise ToolCallValidationError(str(e)) class ManifestValidationError(Exception): """Manifest 验证错误""" pass class ToolCallValidationError(Exception): """工具调用验证错误""" pass ``` --- ## 5. 配置分离 ### 5.1 工具配置模板 ```yaml # tools/configs/.tool.example # 文件操作器 file_operator: allowed_directories: "" max_file_size: 10485760 # 联网搜索 web_search: api_key: "" max_results: 10 ``` ### 5.2 配置加载器 ```python # tools/configs/loader.py import yaml from pathlib import Path from typing import Dict, Any class ConfigLoader: """工具配置加载器""" def __init__(self, config_dir: Path): self.config_dir = config_dir self._cache: Dict[str, Any] = {} def load(self, tool_name: str) -> Dict[str, Any]: """加载指定工具的配置""" if tool_name in self._cache: return self._cache[tool_name] config_file = self.config_dir / f"{tool_name}.yaml" if not config_file.exists(): return {} with open(config_file) as f: config = yaml.safe_load(f) or {} self._cache[tool_name] = config return config def reload(self, tool_name: str) -> Dict[str, Any]: """重新加载配置""" if tool_name in self._cache: del self._cache[tool_name] return self.load(tool_name) def get(self, tool_name: str, key: str, default: Any = None) -> Any: """获取配置项""" config = self.load(tool_name) return config.get(key, default) ``` --- ## 6. 实现步骤 | 步骤 | 任务 | 优先级 | |------|------|--------| | 1 | 创建目录结构 | 🟢 高 | | 2 | 实现 ToolManifest Schema | 🟢 高 | | 3 | 实现 ToolCall Schema | 🟢 高 | | 4 | 实现 Schema 验证器 | 🟢 高 | | 5 | 创建配置加载器 | 🟢 高 | | 6 | 创建 file_operator.yaml | 🟢 高 | | 7 | 创建 search.yaml | 🟡 中 | | 8 | 创建其他工具 Manifest | 🟡 中 | | 9 | 单元测试 | 🟡 中 | --- ## 7. 核心文件变更 | 文件 | 变更 | |------|------| | `tools/__init__.py` | 模块初始化 | | `tools/schemas/__init__.py` | Schema 导出 | | `tools/schemas/manifest.py` | 新增 | | `tools/schemas/tool_call.py` | 新增 | | `tools/schemas/validator.py` | 新增 | | `tools/configs/loader.py` | 新增 | | `tools/manifests/file_operator.yaml` | 新增 | | `tools/manifests/search.yaml` | 新增 | --- ## 8. 工作量估算 | 任务 | 工作量 | |------|--------| | Schema 定义 | 1 天 | | 验证器 | 0.5 天 | | 配置加载器 | 0.5 天 | | Manifest 文件 | 0.5 天 | | 单元测试 | 0.5 天 | | **总计** | **3 天** | --- ## 9. 验收标准 - [ ] ToolManifest Schema 可正确验证 Manifest - [ ] ToolCall Schema 可正确验证调用请求 - [ ] 配置加载器可正确加载配置 - [ ] Manifest 文件格式正确 - [ ] Schema 验证器可捕获错误 - [ ] 单元测试覆盖核心逻辑