Files
GoClaw/docs/tool_binding_architecture.md
2026-03-20 16:39:29 -04:00

12 KiB
Raw Permalink Blame History

GoClaw Tool Binding Architecture

Система предоставления LLM доступа к реальным инструментам через структурированный интерфейс Function Calling.


Проблема

Текущая архитектура Chat позволяет LLM только генерировать текст, но не выполнять действия. LLM не может:

  • Открыть браузер и посетить сайт
  • Выполнить команду в терминале
  • Создать или отредактировать файл
  • Вызвать Docker API для управления контейнерами
  • Отправить HTTP-запрос

Это делает агента бесполезным для реальных задач.


Решение: Tool Binding (Function Calling)

Архитектура состоит из трёх слоёв:

┌─────────────────────────────────────────────────────────┐
│ Layer 1: LLM Chat Interface (React)                     │
│ - Пользователь пишет команду                            │
│ - LLM получает список доступных инструментов            │
│ - LLM генерирует JSON с вызовом инструмента             │
└──────────────────────┬──────────────────────────────────┘
                       │ (JSON with tool_call)
┌──────────────────────▼──────────────────────────────────┐
│ Layer 2: Tool Binding Engine (Node.js/tRPC)            │
│ - Парсит tool_call из LLM ответа                        │
│ - Валидирует параметры по JSON Schema                   │
│ - Маршрутизирует на Tool Executor                       │
│ - Возвращает результат LLM для следующего хода          │
└──────────────────────┬──────────────────────────────────┘
                       │ (execute tool)
┌──────────────────────▼──────────────────────────────────┐
│ Layer 3: Tool Executor (Go/Node.js/Docker)             │
│ - Browser Tool (Puppeteer/Playwright)                   │
│ - Shell Tool (exec, bash commands)                      │
│ - File Tool (read, write, delete)                       │
│ - Docker Tool (Docker SDK)                              │
│ - HTTP Tool (fetch, POST, etc)                          │
└─────────────────────────────────────────────────────────┘

Доступные инструменты (Tools Registry)

Инструмент Функции Параметры Пример
browser open, screenshot, click, type, wait url, selector, text, timeout {"tool": "browser", "action": "open", "url": "https://..."}
shell exec, bash command, timeout, cwd {"tool": "shell", "command": "ls -la /home"}
file read, write, delete, list path, content, mode {"tool": "file", "action": "read", "path": "/etc/hosts"}
docker list_containers, inspect, exec, logs container_id, command {"tool": "docker", "action": "list_containers"}
http GET, POST, PUT, DELETE url, method, headers, body {"tool": "http", "method": "POST", "url": "..."}

Формат Tool Call (Function Calling)

LLM генерирует JSON-ответ с вызовом инструмента:

{
  "type": "tool_call",
  "tool": "browser",
  "action": "open",
  "params": {
    "url": "https://github.com/UniqAI/GoClaw",
    "timeout": 10000
  },
  "id": "call_123"
}

Или несколько инструментов в цепи:

{
  "type": "tool_use",
  "tools": [
    {
      "tool": "shell",
      "command": "docker ps --format json",
      "id": "call_1"
    },
    {
      "tool": "http",
      "method": "POST",
      "url": "http://gateway:18789/api/agents",
      "body": {"name": "web-scraper", "model": "gpt-4o"},
      "id": "call_2"
    }
  ]
}

System Prompt для LLM с Tool Binding

You are GoClaw Agent — an autonomous AI agent with access to real tools.

Available tools:
1. browser — Open URLs, take screenshots, interact with web pages
2. shell — Execute bash commands
3. file — Read/write/delete files
4. docker — Manage Docker containers
5. http — Make HTTP requests

When you need to perform an action, respond with a JSON tool_call:
{
  "type": "tool_call",
  "tool": "browser|shell|file|docker|http",
  "action": "...",
  "params": {...},
  "id": "call_123"
}

After each tool execution, you'll receive the result and can make follow-up calls.
Always explain what you're doing and why.

Архитектура Tool Executor (Go)

// server/tools/executor.go
type ToolExecutor interface {
    Execute(ctx context.Context, call ToolCall) (ToolResult, error)
}

type ToolCall struct {
    Tool   string                 `json:"tool"`
    Action string                 `json:"action"`
    Params map[string]interface{} `json:"params"`
    ID     string                 `json:"id"`
}

type ToolResult struct {
    ID       string      `json:"id"`
    Success  bool        `json:"success"`
    Output   interface{} `json:"output"`
    Error    string      `json:"error,omitempty"`
    Duration int64       `json:"duration_ms"`
}

// Реализации:
// - BrowserExecutor (Puppeteer/Playwright)
// - ShellExecutor (os/exec)
// - FileExecutor (os, ioutil)
// - DockerExecutor (docker/docker-go SDK)
// - HTTPExecutor (net/http)

Интеграция в Chat (tRPC)

// server/routers.ts
ollama: router({
  chat: protectedProcedure
    .input(z.object({
      messages: z.array(MessageSchema),
      model: z.string(),
      tools: z.boolean().optional(),
    }))
    .mutation(async ({ input }) => {
      // 1. Отправляем сообщение в LLM с описанием инструментов
      const response = await chatCompletion(input.model, input.messages, {
        tools: input.tools ? AVAILABLE_TOOLS : undefined,
      });

      // 2. Проверяем, есть ли tool_call в ответе
      if (response.tool_call) {
        // 3. Выполняем инструмент
        const result = await toolExecutor.execute(response.tool_call);
        
        // 4. Добавляем результат в контекст и делаем второй запрос к LLM
        const finalResponse = await chatCompletion(input.model, [
          ...input.messages,
          { role: "assistant", content: JSON.stringify(response.tool_call) },
          { role: "tool", content: JSON.stringify(result) },
        ]);

        return finalResponse;
      }

      return response;
    }),
}),

UI: Tools Manager

Новая страница в Control Center для управления инструментами:

┌─────────────────────────────────────────────┐
│ Tools Manager                               │
├─────────────────────────────────────────────┤
│ Available Tools:                            │
│                                             │
│ ✅ Browser Tool                             │
│    - Timeout: 30s                           │
│    - Max screenshots: 10                    │
│    - Allowed domains: *.github.com, ...     │
│                                             │
│ ✅ Shell Tool                               │
│    - Timeout: 60s                           │
│    - Allowed commands: ls, cat, grep, ...   │
│    - Blocked commands: rm -rf, ...          │
│                                             │
│ ✅ File Tool                                │
│    - Allowed paths: /home/goclaw, /tmp      │
│    - Max file size: 10MB                    │
│                                             │
│ ✅ Docker Tool                              │
│    - Socket: /var/run/docker.sock           │
│    - Allowed operations: list, inspect      │
│                                             │
│ ✅ HTTP Tool                                │
│    - Timeout: 30s                           │
│    - Allowed hosts: *.api.example.com       │
│                                             │
├─────────────────────────────────────────────┤
│ [Test Tool] [Edit] [Disable]                │
└─────────────────────────────────────────────┘

Безопасность и Изоляция

Проблемы:

  • LLM может попытаться выполнить опасные команды (rm -rf /)
  • Может получить доступ к чувствительным файлам
  • Может перегрузить систему бесконечными запросами

Решение:

  1. Whitelist/Blacklist: Каждый инструмент имеет список разрешённых/запрещённых операций
  2. Sandbox: Shell команды выполняются в Docker контейнере с ограничениями ресурсов
  3. Timeout: Все операции имеют таймаут (30-60 секунд)
  4. Rate Limiting: Максимум 10 tool_call за одну сессию
  5. Logging: Все вызовы инструментов логируются для аудита

Дорожная карта реализации

  • Спецификация Tool Call JSON Schema
  • Реализация Tool Executor на Go
  • Интеграция в tRPC роутер
  • System Prompt с инструментами для LLM
  • UI: Tools Manager страница
  • Безопасность: Whitelist/Blacklist
  • Тестирование: vitest + e2e
  • Документация и примеры

Примеры использования

Пример 1: Открыть GitHub и скопировать README

User: "Открой https://github.com/UniqAI/GoClaw и скопируй содержимое README.md"

LLM:
1. tool_call: browser.open(url="https://github.com/UniqAI/GoClaw")
2. tool_call: browser.screenshot()
3. tool_call: browser.click(selector="a[href*=README]")
4. tool_call: file.write(path="/tmp/readme.md", content="...")

Пример 2: Создать Docker контейнер и выполнить команду

User: "Создай контейнер с nginx и проверь статус"

LLM:
1. tool_call: docker.exec(command="docker run -d -p 80:80 nginx")
2. tool_call: shell.exec(command="curl http://localhost")
3. tool_call: docker.logs(container_id="...")

Пример 3: Скачать файл и обработать его

User: "Скачай https://example.com/data.csv и посчитай количество строк"

LLM:
1. tool_call: http.GET(url="https://example.com/data.csv")
2. tool_call: file.write(path="/tmp/data.csv", content="...")
3. tool_call: shell.exec(command="wc -l /tmp/data.csv")

Заключение

Tool Binding превращает GoClaw из пассивного чат-бота в активного агента, способного:

  • 🌐 Браузить интернет
  • 💻 Выполнять системные команды
  • 📁 Управлять файлами
  • 🐳 Управлять Docker контейнерами
  • 🔗 Интегрироваться с внешними API

Это ключевой компонент для создания по-настоящему автономных AI-агентов.