Добавление нового tool
Как создать и подключить свой инструмент к Friedrich
Добавление нового tool
Архитектура Friedrich позволяет легко добавлять новые инструменты. Каждый tool — это отдельный Python-модуль.
Шаг 1: Создайте модуль
Создайте файл agent/tools/my_tool.py:
"""
Tool: My Tool — описание.
"""
import json
import logging
logger = logging.getLogger("tool.my_tool")
# ── Описание для LLM ────────────────────────────────────────────────
TOOL_DESCRIPTION = """
Tool: my_tool
Описание: Что делает этот инструмент.
Методы:
1. my_tool.do_something — описание метода
Параметры: param1 (строка), param2 (число)
""".strip()
# ── Обязательные поля ────────────────────────────────────────────────
METHOD_FIELDS = {
"my_tool.do_something": ["param1", "param2"],
}
FIELD_PROMPTS = {
"param1": {"prompt": "Укажи param1:", "error": "Не понял param1"},
"param2": {"prompt": "Укажи param2:", "error": "Не понял param2"},
}
# ── Реализация ───────────────────────────────────────────────────────
async def do_something(param1: str, param2: int,
user_id: str = "", channel_id: str = "") -> str:
return f"✅ Готово: {param1}, {param2}"
# ── Диспетчер ────────────────────────────────────────────────────────
METHODS = {
"my_tool.do_something": do_something,
}
async def execute(method: str, params: dict, user_id: str, channel_id: str) -> str:
fn = METHODS.get(method)
if not fn:
return f"❌ Неизвестный метод: {method}"
params["user_id"] = user_id
params["channel_id"] = channel_id
return await fn(**params)Шаг 2: Зарегистрируйте в agent
В agent/main.py добавьте импорт и регистрацию:
from .tools import keitaro, my_tool
TOOLS = {
"keitaro": keitaro,
"my_tool": my_tool,
}Шаг 3: Добавьте в brain.py
В agent/brain.py добавьте импорт и описание в system prompt:
from .tools import keitaro, my_tool
SYSTEM_PROMPT = f"""
...
{keitaro.TOOL_DESCRIPTION}
{my_tool.TOOL_DESCRIPTION}
...
"""Шаг 4: Добавьте парсеры полей (если нужно)
Если у вашего tool'а есть поля с нестандартным парсингом, добавьте их в _parse_field() в agent/main.py:
def _parse_field(field_name: str, text: str):
...
if field_name == "my_custom_field":
# кастомная логика
return parsed_value
...Шаг 5: Пересоберите
docker compose up --build -dLLM автоматически увидит новый tool в system prompt и начнёт маршрутизировать запросы.