Friedrich the Great!

Добавление нового 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 -d

LLM автоматически увидит новый tool в system prompt и начнёт маршрутизировать запросы.

On this page