Библиотека для программного взаимодействия с AI-моделями через DuckDuckGo AI Chat
Эта библиотека предоставляет Python API для работы с DuckDuckGo AI Chat и включает встроенный сервис для запуска локального HTTP-сервера. Теперь вы можете использовать мощные AI-модели напрямую в своем коде или через REST API.
- Прямой доступ к AI-моделям DuckDuckGo через Python API
- Встроенный FastAPI-сервер для удобной интеграции с любыми приложениями
- Автоматическое управление заголовками запросов (через Playwright)
- Поддержка изображений в запросах
- Web-поиск в ответах моделей
- Совместимость с различными AI-моделями (GPT-4o, Claude, Llama и др.)
pip install git+https://github.com/paranoik1/duck-chat-apipip install "duck-chat-api[api-service]"git clone https://github.com/paranoik1/duck-local-chat-api
cd duck-local-chat-api
poetry install --with api-service,devВажно: Для работы с API-сервисом необходимы системные зависимости:
sudo apt install xvfb
import asyncio
from duck_chat_api import DuckChat, ModelType
from duck_chat_api.utils.headers import get_headers
async def main():
headers = await get_headers()
async with DuckChat(headers, model=ModelType.Gpt4OMini) as chat:
async for part in chat.ask_question("Привет! Кто ты?"):
if hasattr(part, 'text'):
print(part.text, end="", flush=True)
print()
asyncio.run(main())import asyncio
from duck_chat_api import DuckChat, PartText, PartImage
from duck_chat_api.utils.headers import get_headers
import base64
async def chat_with_image():
headers = await get_headers()
async with DuckChat(headers, model="gpt-4o-mini") as chat:
# Подготовка изображения
with open("image.jpg", "rb") as img_file:
image_data = base64.b64encode(img_file.read()).decode()
# Формирование запроса с изображением
query = [
PartText.create("Что изображено на картинке?"),
PartImage.create(image_data)
]
# Отправка запроса с включенным веб-поиском
async for part in chat.ask_question(query, web_search=True):
if hasattr(part, 'text'):
print(part.text, end="", flush=True)
print()
asyncio.run(chat_with_image())Важно: Библиотека рассчитана на самостоятельное управление заголовками запросов. Пользователи должны самостоятельно получать (
get_headers()или другими методами) и обновлять заголовки (chat.set_headers(headers)).
duck-api-service --host 0.0.0.0 --port 8000 --log-level infofrom duck_chat_api.service import app
import uvicorn
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)После запуска сервиса доступны эндпоинты:
POST /chat— отправка запроса к AI-моделиGET /docs— интерактивная документация Swagger UIGET /redoc— альтернативная документация ReDoc
curl -X POST http://localhost:8000/chat \
-F "content=Что на этой картинке?" \
-F "model=gpt-4o-mini" \
-F "web_search=true" \
-F "file=@/path/to/image.jpg"duck_chat_api/
├── __init__.py # Основные импорты
├── api.py # Класс DuckChat для взаимодействия с API
├── event.py # Обработка событий от DuckDuckGo
├── exceptions.py # Пользовательские исключения
├── model_type.py # Типы поддерживаемых моделей
├── parts.py # Структуры данных для частей сообщений
├── request_data.py # Формирование запросов к API
├── service/ # Модуль для запуска API-сервиса
│ ├── __main__.py # Точка входа для CLI
│ ├── headers_manager.py# Управление заголовками запросов
│ ├── service.py # FastAPI приложение
│ └── utils.py # Вспомогательные функции
└── utils/ # Утилиты для работы с заголовками и моделями
├── headers.py # Получение валидных заголовков через Playwright
└── models.py # Парсинг доступных моделей
Библиотека автоматически определяет доступные модели при запуске. Основные поддерживаемые модели:
gpt-4o-minigpt-5-miniclaude-3-5-haiku-latestmeta-llama/Llama-4-Scout-17B-16E-Instructmistralai/Mistral-Small-24B-Instruct-2501openai/gpt-oss-120b
Для получения актуального списка моделей используйте:
from duck_chat_api.utils.models import get_models_page_html, parse_models
from duck_chat_api.service.utils import generate_models
import asyncio
from pprint import pprint
async def print_models():
html = await get_models_page_html()
models = parse_models(html)
pprint(models)
# ИЛИ же
models = await generate_models()
pprint(models)
asyncio.run(print_models())Библиотека duck_chat_api использует концепцию "частей сообщений" (parts) для гибкого формирования запросов и обработки ответов. Все части сообщений наследуются от базового класса Part и имеют специфическую структуру.
- Абстрактный базовый класс для всех типов частей
- Содержит поле
typeдля идентификации типа части - Атрибут
IS_SAVEопределяет, нужно ли сохранять часть в истории диалога
- Представляет текстовую часть сообщения
- Создание:
PartText.create("Ваш текст здесь") - Поля:
text: содержимое текста
- Представляет изображение в запросе
- Создание:
PartImage.create(base64_encoded_image, mime_type="image/jpeg") - Поля:
mime_type: MIME-тип изображения (по умолчаниюimage/webp)image: изображение в формате data URL (data:{mime_type};base64,{base64})
- Используется моделью для вызова инструментов (автоматически)
- Не предназначен для ручного создания в запросах
- Представляет либо вызов инструмента, либо результат его выполнения
- Поля:
tool_call_id: идентификатор вызоваstate: состояние (callилиresult)tool_arguments,tool_name: параметры вызова (приstate=call)result: результат выполнения (приstate=result)
- Представляет источники информации в ответах модели
- Не сохраняется в истории диалога (
IS_SAVE = False) - Поля:
source: объект с информацией об источнике
| Тип части | Можно использовать в запросе | Может вернуться в ответе | Примечание |
|---|---|---|---|
PartText |
✅ | ✅ | Основной тип для текстовых запросов и ответов |
PartImage |
✅ | ❌ | Только для отправки изображений в запросах |
PartTool |
❌ | ✅ | Автоматически обрабатывается моделью |
PartSource |
❌ | ✅ | Источники информации в результатах поиска |
import asyncio
from duck_chat_api import DuckChat, PartText, PartImage, PartSource
from duck_chat_api.utils.headers import get_headers
import base64
async def chat_with_image():
# Получение валидных заголовков для запросов к API
headers = await get_headers()
async with DuckChat(headers, model="gpt-4o-mini") as chat:
# Подготовка изображения
with open("image.jpg", "rb") as img_file:
image_data = base64.b64encode(img_file.read()).decode()
# Формирование запроса с изображением
query = [
PartText.create("Что изображено на картинке?"),
PartImage.create(image_data)
]
# Отправка запроса с включенным веб-поиском
async for part in chat.ask_question(query, web_search=True):
if isinstance(part, PartText):
print(part.text, end="", flush=True)
elif isinstance(part, PartSource):
print("\n" + part.source.title + ": " + part.source.url)
elif isinstance(part, PartTool):
if part.state == "call" and part.tool_name == "WebSearch":
print("\n[Выполняется поиск в интернете...]")
print()
asyncio.run(chat_with_image())Важно: при создании запросов вы можете использовать только PartText и PartImage. Все остальные типы частей (PartTool, PartSource) генерируются автоматически моделью при формировании ответа и не должны создаваться вручную в запросах.
- Только Linux (если получение заголовков требуется в headless режиме) (из-за зависимости
xvfbwrapper) - Python 3.13+ (требуется для всех функций библиотеки)
- Chromium должен быть установлен в системе
- Срок действия заголовков ограничен (обычно 5-10 запросов)
- Не предназначен для массового использования (следуйте правилам duck.ai)
- Некоторые модели могут требовать аккаунта DuckDuckGo Pro (не поддерживается проектом)
- mrgick/duck_chat — за основу реализации
- patchright — за решение по обходу проверок на ботов
- FastAPI и Playwright — за отличные инструменты
🦆 Утки не возвращаются, но API — да.
Пользуйтесь с умом и соблюдайте правила использования DuckDuckGo AI.