Сколько раз вы хотели быстро спросить что-то у ИИ, не открывая браузер и не платя за API? Запустить модель локально, чтобы она помнила контекст разговора и была вашим личным ассистентом в терминале.
Проблема в том, что даже с такими инструментами, как Ollama, написание стабильного, удобного клиента - это отдельная история. Нужно управлять промптами, обрабатывать обрывы соединения, настраивать параметры генерации. И каждый раз писать это с нуля - безумие.
Решение - связка из трех компонентов: Ollama (движок для локальных моделей), LiteLLM (универсальная библиотека для работы с разными API) и ваш собственный Python-скрипт, который все это скрепляет. Сегодня мы соберем этого Франкенштейна, и он будет работать как швейцарские часы.
Актуальность на 20 марта 2026: В этом гайде используются последние стабильные версии инструментов. Для Ollama это версия 0.6.0+, LiteLLM - 1.35.0+. В качестве модели возьмем одну из самых сбалансированных на момент написания - Qwen2.5:7b. Она быстрая, достаточно умная и отлично работает на обычном CPU.
Что нужно сделать перед началом
Представьте, что вы пытаетесь приготовить ужин, но у вас нет ни плиты, ни продуктов. Примерно так же выглядит попытка запустить LLM без подготовки. Вот что должно быть на вашей кухне:
- Python 3.10+. Старее - не работает, новее - обычно ок.
- Ollama. Установите его с официального сайта. На Linux/macOS это одна команда в терминале, на Windows - скачиваете exe-файл.
- Минимальные знания терминала. Умение запускать скрипты и не пугаться черного экрана.
Если вы никогда не запускали локальные модели, сначала прочитайте мой полный гид по запуску LLM офлайн. Там разжеваны базовые шаги.
1 Ставим движок и качаем модель
Ollama - это не модель, а контейнер для моделей. Как Docker, но для нейросетей. Установка элементарная:
# На macOS или Linux (в большинстве случаев)
curl -fsSL https://ollama.ai/install.sh | sh
# После установки проверяем
ollama --version
Теперь нужна модель. Не гонитесь за самыми большими. Для консольного чата, где важна скорость отклика, идеально подходят модели на 7-8 миллиардов параметров.
# Скачиваем и запускаем модель (займет время и гигабайты места)
ollama pull qwen2.5:7b
# Проверяем, что модель загрузилась и работает
ollama run qwen2.5:7b "Привет!"
llama3.2:1b. Она менее способная, но ответит мгновенно. Для более серьезных задач, где нужен код или анализ, лучше все-таки 7b. Подробнее о выборе железа я писал в статье про запуск LLM на ноутбуке.2 Пишем скрипт-прослойку на Python
Ollama дает API, но он сырой. Писать запросы через curl каждый раз - мазохизм. Тут на помощь приходит LiteLLM. Эта библиотека знает, как разговаривать с десятком разных провайдеров моделей (OpenAI, Anthropic, Ollama и другие) через единый интерфейс. Устанавливаем:
pip install litellmА теперь самое интересное - код. Не делайте так, как многие: открывают файл и пишут 20 строк без обработки ошибок. Через полчаса скрипт падает, и вы не понимаете почему.
Как НЕ надо делать:
import litellm
response = litellm.completion(model="ollama/qwen2.5:7b", messages=[{"role": "user", "content": "Привет"}])
print(response.choices[0].message.content)
Что не так? Нет system prompt, нет потокового вывода (будете ждать полный ответ минуту), нет обработки ошибок сети. Это учебный пример, который в реальности бесполезен.
Правильный вариант:
import litellm
import sys
from typing import List, Dict
# Конфигурация - выносим все настройки в одно место
MODEL_NAME = "ollama/qwen2.5:7b"
SYSTEM_PROMPT = "Ты - полезный ассистент, который отвечает кратко и по делу. Ты работаешь в терминале, поэтому длинные ответы не приветствуются."
BASE_URL = "http://localhost:11434" # Адрес, на котором работает Ollama
class ConsoleChat:
def __init__(self):
self.conversation_history: List[Dict[str, str]] = [
{"role": "system", "content": SYSTEM_PROMPT}
]
# Настраиваем LiteLLM
litellm.api_base = BASE_URL
litellm.drop_params = True # Игнорируем параметры, которые не поддерживает Ollama
def stream_response(self, user_input: str):
"""Отправляет запрос и выводит ответ по кусочкам, как в ChatGPT."""
self.conversation_history.append({"role": "user", "content": user_input})
try:
response = litellm.completion(
model=MODEL_NAME,
messages=self.conversation_history,
stream=True,
max_tokens=1000,
temperature=0.7,
)
collected_chunks = []
print("\nАссистент: ", end="", flush=True)
for chunk in response:
if hasattr(chunk.choices[0].delta, 'content'):
content = chunk.choices[0].delta.content or ""
print(content, end="", flush=True)
collected_chunks.append(content)
full_response = "".join(collected_chunks)
self.conversation_history.append({"role": "assistant", "content": full_response})
print("\n")
except Exception as e:
print(f"\nОшибка: {e}")
# Простая политика повторения - удаляем последний вопрос и пробуем снова
self.conversation_history.pop()
def run(self):
print(f"Запущен чат с моделью {MODEL_NAME}. Для выхода введите 'exit' или 'quit'.")
print(f"System prompt: {SYSTEM_PROMPT[:50]}...\n")
while True:
try:
user_input = input("\nВы: ").strip()
except KeyboardInterrupt:
print("\n\nВыход.")
break
if user_input.lower() in ["exit", "quit", "выход"]:
break
if not user_input:
continue
self.stream_response(user_input)
if __name__ == "__main__":
chat = ConsoleChat()
chat.run()
Сохраните это в файл chat.py и запустите. У вас заработает полноценный чат с историей, потоковым выводом и базовой обработкой ошибок.
3 Зачем нужен system prompt и как его правильно писать
System prompt - это инструкция, которую модель получает «внутренним голосом» перед началом диалога. Без него модель будет отвечать как попало. Хороший промпт решает три задачи:
- Задает роль («Ты - опытный разработчик Python»).
- Определяет формат ответов («Отвечай кратко, используй маркеры списков»).
- Устанавливает ограничения («Не упоминай, что ты ИИ, не генерируй вредоносный код»).
Вот пример плохого промпта: "Ты - умный ассистент." Слишком абстрактно, модель не поймет, что от нее хотят.
Вот рабочий вариант для консольного помощника:
SYSTEM_PROMPT = """Ты - ассистент, встроенный в терминал разработчика.
Твои ответы должны быть краткими, информативными и готовыми к копированию.
Если тебя просят сгенерировать код, предоставляй только код с минимальными пояснениями.
Избегай маркдаун-разметки, кроме случаев, когда это явно требуется.
Ты общаешься через консоль, поэтому не используй эмодзи и излишние приветствия."""Если вам нужно нечто более сложное, например, агент с вызовом функций, смотрите руководство по tool calling для Qwen.
Что еще можно улучшить: нюансы и грабли
Скрипт выше - основа. В реальном использовании вы наткнетесь на подводные камни. Вот самые частые:
| Проблема | Причина | Решение |
|---|---|---|
| Модель «забывает» контекст после 10 сообщений | Ollama по умолчанию ограничивает контекст. История переполняет буфер. | Реализовать «скользящее окно»: хранить только последние N сообщений. Или явно указать num_ctx при запуске модели в Ollama. |
| Скрипт зависает на минуту, потом выдает ошибку | Ollama не запущен или слушает на другом порту. | Добавить проверку подключения к BASE_URL перед началом чата. Использовать timeout в запросах. |
| Ответы получаются слишком общими | Температура (temperature) равна 0.7, что дает много случайности. | Для задач, требующих точности (код, факты), снижайте temperature до 0.1. Для креативных - поднимайте до 0.9. |
Если ваш чат должен не просто болтать, а выполнять конкретные задачи (например, писать код), вам нужна более продвинутая архитектура. Я разбирал ее в статье про создание кодинг-агента с нуля.
Вопросы, которые вы зададите первыми
Можно ли использовать эту связку для автоматизации, а не только для чата?
Конечно. LiteLLM отлично работает в скриптах. Вы можете, например, автоматически проверять код на уязвимости, генерировать документацию или классифицировать тексты. Главное - вынести логику общения с моделью в отдельный класс, как мы сделали с ConsoleChat.
Ollama жрет всю память. Как ограничить?
Запускайте модель с флагом --num-gpu (для указания слоев на GPU) и --num-threads (для ограничения CPU). Например: ollama run qwen2.5:7b --num-gpu 10 --num-threads 4. Это загрузит часть модели в VRAM и ограничит потоки CPU.
Как добавить поддержку других моделей, кроме Ollama?
В этом главная прелесть LiteLLM. Чтобы переключиться на OpenAI, измените MODEL_NAME на "gpt-4o-mini" и задайте litellm.api_key. Все остальное - обработка ошибок, стриминг - останется без изменений. Подробнее о других терминальных инструментах я писал в обзоре терминальных инструментов.
И последнее. Не пытайтесь сделать идеальный чат с первого раза. Сначала добейтесь, чтобы он просто работал. Потом добавьте обработку ошибок. Потом - логирование. Потом - конфигурационный файл. Иначе вы утонете в деталях и бросите проект. Как не утонуть в хаосе при работе с LLM, я рассказывал в статье про организацию чатов и контекста.
Теперь у вас в арсенале есть рабочий инструмент. Не просто «Hello, World!», а полноценный клиент, который можно развивать. Меняйте промпты, экспериментируйте с моделями, подключайте к внешним API. Главное - начать.