12 KiB
12 KiB
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
# 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
# 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
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
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 验证器
# 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 工具配置模板
# tools/configs/.tool.example
# 文件操作器
file_operator:
allowed_directories: ""
max_file_size: 10485760
# 联网搜索
web_search:
api_key: ""
max_results: 10
5.2 配置加载器
# 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 验证器可捕获错误
- 单元测试覆盖核心逻辑