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

323 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-ответ с вызовом инструмента:
```json
{
"type": "tool_call",
"tool": "browser",
"action": "open",
"params": {
"url": "https://github.com/UniqAI/GoClaw",
"timeout": 10000
},
"id": "call_123"
}
```
Или несколько инструментов в цепи:
```json
{
"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)
```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)
```typescript
// 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-агентов.