Пользовательские инструменты OpenCode

Пользовательские инструменты позволяют вам расширять возможности OpenCode, давая LLM возможность вызывать функции, которые вы определяете во время разговоров, тем самым реализуя сложные операции, такие как запросы к базе данных, выполнение скриптов и вызовы API.

Эти инструменты работают со встроенными инструментами (такими какread、write、bash)


Пользовательские инструменты — это ключевая возможность расширения OpenCode, превращающая LLM из модели, только генерирующей код, в систему, способную выполнять задачи.

Правильно проектируя инструменты, вы можете создавать:

  • Автоматизированные конвейеры разработки
  • Интеллектуальные помощники по коду
  • Системы AI Ops
  • Внутренние корпоративные платформы AI-инструментов

1. Что такое пользовательские инструменты?

Пользовательский инструмент — это, по сути, функциональный интерфейс, который LLM может проактивно вызывать во время выполнения и получать результат.

Типичные сценарии использования:

  • Запросы к базам данных (SQL / NoSQL)
  • Вызов внутренних API
  • Выполнение скриптов (Python / Shell)
  • Чтение состояния системы или информации об окружении
  • Инкапсуляция сложной бизнес-логики

Это можно представить как:механизм плагинов, дающий ИИ возможности выполнения。


2. Место хранения инструментов

OpenCode автоматически загружает инструменты из следующих каталогов:

  • Уровень проекта:.opencode/tools/
  • Глобальный уровень:~/.config/opencode/tools/

Имя файла — это имя инструмента (это критически важно).


3. Базовое определение инструмента (рекомендуется)

Используйтеtool()Вспомогательные функции обеспечивают типобезопасность и проверку параметров.

import { tool } from "@opencode-ai/plugin"

export default tool({
  description: "Query the project database",
  args: {
    query: tool.schema.string().describe("SQL query to execute"),
  },
  async execute(args) {
    return `Executed query: ${args.query}`
  },
})

Пояснение:

  • description: Описание инструмента, используемое LLM для определения, вызывать ли его
  • args: Определение параметров (на основе Zod)
  • execute: Фактическая логика выполнения

4. Несколько инструментов в одном файле

Один файл может экспортировать несколько инструментов, и каждый инструмент автоматически получает имя:

<文件名>_<导出名>

import { tool } from "@opencode-ai/plugin"

export const add = tool({
  description: "Add two numbers",
  args: {
    a: tool.schema.number(),
    b: tool.schema.number(),
  },
  async execute(args) {
    return args.a + args.b
  },
})

export const multiply = tool({
  description: "Multiply two numbers",
  args: {
    a: tool.schema.number(),
    b: tool.schema.number(),
  },
  async execute(args) {
    return args.a * args.b
  },
})

Итоговые сгенерированные инструменты:

  • math_add
  • math_multiply

5. Конфликты со встроенными инструментами

Если имя вашего инструмента совпадает с именем встроенного инструмента, онпереопределит встроенный инструмент。

// 覆盖内置 bash 工具
export default tool({
  description: "Restricted bash wrapper",
  args: {
    command: tool.schema.string(),
  },
  async execute(args) {
    return `blocked: ${args.command}`
  },
})

Рекомендация:

  • Избегайте конфликтов имён
  • Если вам нужно только ограничить возможности, предпочтительно использоватьpermissionconfiguration

6. Определение параметров (Zod)

Параметры определяются с помощью Zod Schema, поддерживая валидацию типов и описания:

args: {
  query: tool.schema.string().describe("SQL query"),
  limit: tool.schema.number().optional(),
}

Вы также можете напрямую использовать Zod:

import { z } from "zod"

export default {
  description: "Example tool",
  args: {
    name: z.string(),
  },
  async execute(args) {
    return `Hello ${args.name}`
  },
}

7. Контекст

При выполнении инструмента информация о контексте внедряется автоматически:

export default tool({
  description: "Get project info",
  args: {},
  async execute(args, context) {
    const { agent, sessionID, directory, worktree } = context
    return `Agent: ${agent}, Dir: ${directory}`
  },
})<

Доступные поля:

  • agent: Текущий агент
  • sessionID: ID сессии
  • messageID: ID сообщения
  • directory: Текущий рабочий каталог
  • worktree: Корневой каталог Git

8. Вызов внешних языков (пример на Python)

Вы можете реализовать логику инструмента на любом языке, например Python.

1. Скрипт на Python

# .opencode/tools/add.py
import sys

a = int(sys.argv[1])
b = int(sys.argv[2])

print(a + b)

2. Инкапсуляция инструмента

import { tool } from "@opencode-ai/plugin"
import path from "path"

export default tool({
  description: "Add two numbers using Python",
  args: {
    a: tool.schema.number(),
    b: tool.schema.number(),
  },
  async execute(args, context) {
    const script = path.join(context.worktree, ".opencode/tools/add.py")
    const result = await Bun.$`python3 ${script} ${args.a} ${args.b}`.text()
    return result.trim()
  },
})

Этот подход подходит для:

  • Существующие цепочки инструментов Python
  • Вызов моделей анализа данных / ИИ
  • Выполнение сложных вычислительных задач

9. Лучшие практики

  • Описания инструментов должны быть понятными, чтобы помочь LLM сделать правильный выбор
  • Проектируйте параметры как можно проще и понятнее
  • Избегайте побочных эффектов (если только они явно не нужны)
  • Предпочитайте контролировать рискованные операции через разрешения
  • Инструменты должны быть сосредоточены на одной обязанности
Другие расширения