true message
This commit is contained in:
322
docs/tool_binding_architecture.md
Normal file
322
docs/tool_binding_architecture.md
Normal file
@@ -0,0 +1,322 @@
|
||||
# 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-агентов.
|
||||
Reference in New Issue
Block a user