- Update project branding from claude-cli to Kode - Reorganize documentation with new development guides - Add CONTRIBUTING.md and Chinese README - Remove worktree_merge command and relocate system-design.md - Update dependencies and package configuration - Improve custom commands service with better error handling - Clean up storage utilities and debug logging
11 KiB
11 KiB
工具系统文档
概述
工具系统是 Kode 功能的核心,为 AI 可以执行的所有操作提供标准化接口。每个功能 - 从读取文件到执行命令 - 都作为工具实现。
工具接口
核心工具类
export abstract class Tool {
abstract name: string
abstract description: string
abstract inputSchema: z.ZodTypeAny
// 权限检查
abstract needsPermissions(input: unknown): boolean
// 输入验证
validateInput(input: unknown): unknown
// 主执行方法
abstract call(
input: unknown,
context: ToolUseContext
): AsyncGenerator<ToolCallEvent>
// 为 AI 格式化结果
abstract renderResultForAssistant(
input: unknown,
result: unknown
): string
}
工具生命周期
1. 工具注册
↓
2. AI 请求工具使用
↓
3. 输入验证 (Zod Schema)
↓
4. 权限检查
↓
5. 用户批准(如需要)
↓
6. 工具执行
↓
7. 进度更新(通过生成器)
↓
8. 结果格式化
↓
9. 返回给 AI
工具类别
1. 文件操作工具
FileReadTool(文件读取工具)
- 用途:读取带编码检测的文件内容
- 主要功能:
- 自动编码检测(UTF-8、UTF-16 等)
- 二进制文件处理
- 支持带偏移/限制的大文件
- 新鲜度跟踪以检测外部更改
- 安全性:检查文件访问权限
FileEditTool(文件编辑工具)
- 用途:对现有文件进行精确编辑
- 主要功能:
- 精确匹配的字符串替换
- 文件新鲜度验证
- 防止在未读取前编辑
- 多重编辑支持(MultiEditTool)
- 安全性:需要文件写入权限
FileWriteTool(文件写入工具)
- 用途:创建或覆盖整个文件
- 主要功能:
- 完整文件替换
- 如需要创建目录
- 编码规范
- 安全性:需要明确的写入权限
NotebookEditTool(笔记本编辑工具)
- 用途:编辑 Jupyter 笔记本单元格
- 主要功能:
- 单元格级操作(替换、插入、删除)
- 代码和 markdown 单元格支持
- 保留笔记本元数据
2. 搜索和发现工具
GrepTool(搜索工具)
- 用途:使用正则表达式搜索文件内容
- 主要功能:
- Ripgrep 集成以提高速度
- 多种输出模式(内容、文件、计数)
- 上下文行支持(-A、-B、-C)
- 文件类型过滤
- 实现:使用 ripgrep 二进制文件以提高性能
GlobTool(文件匹配工具)
- 用途:按名称模式查找文件
- 主要功能:
- Glob 模式匹配
- 隐藏文件支持
- 按修改时间排序结果
- 符号链接跟随选项
LSTool(列表工具)
- 用途:列出目录内容
- 主要功能:
- 递归列表
- 隐藏文件显示
- 大小和权限信息
- 模式过滤
3. 系统执行工具
BashTool(Shell 工具)
- 用途:执行 shell 命令
- 主要功能:
- 持久 shell 会话
- 工作目录管理
- 环境变量处理
- 超时支持(默认 2 分钟)
- 输出流式传输
- 安全性:
- 安全模式下的命令批准
- 受限命令黑名单
- 环境清理
4. AI 增强工具
TaskTool(任务工具/架构师)
- 用途:为复杂任务启动子代理
- 主要功能:
- 自主多步骤执行
- 专门的代理类型
- 上下文保留
- 并行任务执行
- 用例:复杂重构、系统设计
ThinkTool(思考工具)
- 用途:允许 AI 推理问题
- 主要功能:
- 结构化思考块
- 问题分解
- 对用户输出隐藏
- 实现:特殊消息格式
TodoWriteTool(待办事项工具)
- 用途:任务管理和跟踪
- 主要功能:
- 持久待办事项列表
- 状态跟踪(待处理、进行中、已完成)
- 进度可视化
- 自动任务分解
5. 外部集成工具
MCPTool(MCP 工具)
- 用途:桥接到模型上下文协议服务器
- 主要功能:
- 动态工具发现
- 协议转换
- 服务器生命周期管理
- 错误传播
- 实现:通过 stdio/SSE 的 JSON-RPC
WebFetchTool(网页获取工具)
- 用途:获取和处理网页内容
- 主要功能:
- HTML 到 markdown 转换
- 内容提取
- 缓存支持
- 重定向处理
工具实现指南
创建新工具
export class MyCustomTool extends Tool {
name = 'my_custom_tool'
description = '执行自定义操作'
inputSchema = z.object({
param1: z.string(),
param2: z.number().optional()
})
needsPermissions(input: unknown): boolean {
// 如果此操作需要用户批准,返回 true
return true
}
async *call(
input: z.infer<typeof this.inputSchema>,
context: ToolUseContext
): AsyncGenerator<ToolCallEvent> {
// 产生进度更新
yield {
type: 'progress',
message: '开始操作...'
}
// 检查中止信号
if (context.abortSignal.aborted) {
throw new Error('操作已取消')
}
// 执行操作
const result = await this.performOperation(input)
// 产生最终结果
yield {
type: 'result',
result: result
}
}
renderResultForAssistant(input: unknown, result: unknown): string {
// 为 AI 消费格式化结果
return `操作完成:${JSON.stringify(result)}`
}
}
工具注册
// 在 tools.ts 中
export async function getTools(): Promise<Tool[]> {
const tools = [
new FileReadTool(),
new FileEditTool(),
new BashTool(),
new MyCustomTool(), // 在这里添加您的工具
// ... 其他工具
]
// 动态添加 MCP 工具
const mcpTools = await getMCPTools()
tools.push(...mcpTools)
return tools
}
权限系统集成
权限类型
- 无需权限:只读操作
- 会话权限:当前会话的临时批准
- 持久权限:保存以供将来使用的批准
- 始终询问:需要明确批准的关键操作
权限流程
async function checkPermissionsAndCallTool(
tool: Tool,
input: unknown,
context: ToolUseContext
): Promise<ToolResult> {
if (!tool.needsPermissions(input)) {
// 无需权限
return await tool.call(input, context)
}
const permission = await requestPermission({
tool: tool.name,
operation: describeOperation(input)
})
if (permission.approved) {
if (permission.saveForSession) {
saveSessionPermission(tool.name, input)
}
return await tool.call(input, context)
} else {
throw new PermissionDeniedError()
}
}
工具上下文
ToolUseContext 接口
interface ToolUseContext {
// 取消支持
abortSignal: AbortSignal
// 当前工作目录
cwd: string
// 权限助手
hasPermission: (operation: string) => boolean
requestPermission: (operation: string) => Promise<boolean>
// 日志和指标
logEvent: (event: string, data: any) => void
// UI 助手
showProgress: (message: string) => void
// 配置访问
config: Configuration
}
工具最佳实践
1. 输入验证
- 使用 Zod 模式进行类型安全验证
- 为无效输入提供清晰的错误消息
- 验证文件路径和命令参数
2. 错误处理
- 抛出带有可操作消息的描述性错误
- 优雅地处理常见故障情况
- 提供恢复建议
3. 进度报告
- 为长操作产生进度更新
- 包括百分比或步骤信息
- 以合理的间隔更新(不要太频繁)
4. 取消支持
- 定期检查中止信号
- 取消时清理资源
- 可能时保存部分进度
5. 结果格式化
- 为用户提供人类可读的输出
- 包括用于 AI 解析的结构化数据
- 适当地总结大型结果
6. 安全考虑
- 始终验证和清理输入
- 在操作前检查权限
- 限制资源消耗
- 防止路径遍历攻击
工具测试
单元测试
describe('MyCustomTool', () => {
it('应该正确验证输入', () => {
const tool = new MyCustomTool()
const validInput = { param1: 'test' }
expect(() => tool.validateInput(validInput)).not.toThrow()
})
it('应该处理取消', async () => {
const tool = new MyCustomTool()
const abortController = new AbortController()
abortController.abort()
const context = {
abortSignal: abortController.signal,
// ... 其他上下文
}
await expect(
tool.call(input, context)
).rejects.toThrow('操作已取消')
})
})
集成测试
it('应该与权限系统集成', async () => {
const tool = new MyCustomTool()
const context = createTestContext({
permissions: ['my_custom_tool']
})
const result = await tool.call(input, context)
expect(result).toBeDefined()
})
高级工具模式
复合工具
编排多个其他工具的工具:
class CompositeAnalysisTool extends Tool {
async *call(input, context) {
// 首先,搜索文件
const files = await this.globTool.call(
{ pattern: input.pattern },
context
)
// 然后 grep 每个文件
for (const file of files) {
const results = await this.grepTool.call(
{ file, pattern: input.search },
context
)
yield { type: 'progress', file, results }
}
}
}
流式工具
增量处理数据的工具:
class StreamingFileTool extends Tool {
async *call(input, context) {
const stream = createReadStream(input.file)
for await (const chunk of stream) {
const processed = processChunk(chunk)
yield { type: 'partial', data: processed }
if (context.abortSignal.aborted) break
}
yield { type: 'complete' }
}
}
有状态工具
跨调用维护状态的工具:
class SessionTool extends Tool {
private session: Session
async *call(input, context) {
if (!this.session) {
this.session = await createSession()
}
const result = await this.session.execute(input.command)
yield { type: 'result', result }
}
cleanup() {
this.session?.close()
}
}
工具指标和监控
性能跟踪
class InstrumentedTool extends Tool {
async *call(input, context) {
const startTime = Date.now()
try {
yield* super.call(input, context)
} finally {
const duration = Date.now() - startTime
context.logEvent('tool_execution', {
tool: this.name,
duration,
success: true
})
}
}
}
错误跟踪
class MonitoredTool extends Tool {
async *call(input, context) {
try {
yield* super.call(input, context)
} catch (error) {
context.logEvent('tool_error', {
tool: this.name,
error: error.message,
stack: error.stack
})
throw error
}
}
}
工具系统为 Kode 的所有功能提供了基础,在为 AI 和人类用户维护一致接口的同时,实现了安全、高效和可扩展的操作。