Что делает эта «ботовская» библиотека?
Код представляет собой небольшую, но полностью готовую к использованию оболочку над различными LLM‑провайдерами. Она умеет:
- автоматически ставить pip install нужных пакетов, если их нет;
- подключаться к OpenAI API и совместимым сервисам (OpenRouter, Together, Ollama и др.);
- использовать асинхронный клиент
AsyncOpenAI; - поддерживать инструменты (tools) – калькулятор, запрос времени, сохраняемые факты и запуск Python‑кода;
- работать в полностью локальном режиме с MockProvider, не требуя API‑ключа и сети.
Структура проекта
Главные составляющие:
Provider– абстрактный базовый класс, задаёт интерфейсcomplete(messages, tools);OpenAICompatibleProvider– реализация для всех сервисов, поддерживающих OpenAI‑совместимый API;MockProvider– детерминированный «заглушечный» LLM, позволяющий отладить логику без реального вызова модели;- Вспомогательные
dataclass(ToolCall,Usage,LLMResponse) стандартизируют формат ответа.
Как подключить реальную модель
Для работы с OpenAI (или аналогом) достаточно создать объект провайдера:
from your_module import OpenAICompatibleProvider
provider = OpenAICompatibleProvider(
api_key="YOUR_API_KEY",
model="gpt-4o-mini",
base_url=None # можно указать endpoint другого сервисa
)
Далее в асинхронном коде вызываем await provider.complete(messages, tools). В messages передаём список словарей формата OpenAI ({"role": "user", "content": "..."}), а в tools – описание функций, которые модель может вызвать.
Что делает MockProvider и зачем он нужен
MockProvider имитирует поведение LLM, но никогда не отправляет запросы в сеть. Это удобно когда:
- нужна быстрая проверка цепочки tool‑calls;
- нет доступа к API‑ключу;
- тестируете логику обработки результатов (memory, recall, повторные вызовы).
Он распознаёт простые запросы («сколько будет 2+2», «какое сейчас время», «запомни, что мой любимый язык — Python») и генерирует соответствующие ToolCall.
Работа с инструментами
Каждый инструмент описывается JSON‑схемой, передаваемой в массив tools. Пример для калькулятора:
tools = [
{
"type": "function",
"function": {
"name": "calculator",
"description": "Вычисляет математическое выражение.",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "Математическое выражение"}
},
"required": ["expression"]
}
}
}
]
После того как модель решит вызвать этот инструмент, вы получаете объект ToolCall с полями id, name и arguments. Выполняете нужную логику и отправляете результат обратно в модель как отдельное сообщение с ролью tool:
tool_result = {
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
}
messages.append(tool_result)
Как добавить собственный инструмент
1. Описываем функцию в массиве tools (см. пример выше).
2. В классе MockProvider.complete (или в вашем кастомном провайдере) добавляем проверку if "my_tool" in tool_names и формируем ToolCall.
3. После получения результата вызываем await provider.complete(updated_messages, tools) – модель получит контекст и сформулирует ответ.
Полезные ссылки
- Документация OpenAI API – https://platform.openai.com/docs/api-reference/introduction
- Библиотека
openaiна GitHub – https://github.com/openai/openai-python - Проект
nest_asyncio– https://github.com/erdewit/nest_asyncio - Исходный код рассматриваемого примера – https://github.com/your-repo/nanobot




















