Настройка запросов к моделям через Ollama
Структура JSON модели для передачи на сервер OLLAMA
{
"model": "qwen3:4b",
"prompt": "Ваш запрос",
"stream": false,
"format": "json",
"options": {
"temperature": 0.8,
"top_p": 0.9,
"top_k": 40,
"num_predict": 512,
"stop": ["\n", "###"],
"repeat_penalty": 1.1,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"seed": 42,
"mirostat": 0,
"num_ctx": 2048,
"num_thread": 8
},
"template": "{{ .Prompt }}",
"context": [1, 2, 3]
}
Описание и назначение основных параметров для управления моделями в Ollama:
1. "model": "qwen3:4b"
- Что делает: Указывает, какую модель использовать
- Применение: Замените на нужную модель:
"llama3:8b"
,"mistral:7b"
, etc - Пример:
"model": "llama3:8b"
2. "prompt": "Ваш запрос"
- Что делает: Текст запроса к модели
- Применение: Можно использовать многострочные промпты
- Пример:
"prompt": "Напиши рецепт пасты карбонара:\n"
3. "stream": false
- Что делает: Возвращать ответ потоком или целиком
- Применение:
false
- весь ответ сразу (для скриптов)true
- потоковая передача (для UI)
- Пример:
"stream": true
4. "format": "json"
- Что делает: Заставляет модель возвращать ответ в JSON формате
- Применение: Полезно для структурированных данных
- Пример:
"format": "json"
+"prompt": "Верни JSON с именем и возрастом"
В Ollama параметр format
поддерживает несколько значений:
Толкование
Поддерживаемые форматы
1. "format": "json"
- Описание: Заставляет модель возвращать ответ в валидном JSON формате
- Пример промпта:
"Верни JSON: {\\\"name\\\": \\\"John\\\", \\\"age\\\": 30}"
- Пример вывода:
{"name": "John", "age": 30}
2. "format": "text"
(по умолчанию)
- Описание: Обычный текстовый ответ без специального форматирования
- Пример промпта:
"Расскажи о космосе"
- Пример вывода:
"Космос - это бескрайнее пространство..."
3. "format": "markdown"
- Описание: Ответ в формате Markdown
- Пример промпта:
"Напиши документацию в markdown"
- Пример вывода:
# Заголовок - Список **Жирный текст**
4. "format": "html"
- Описание: Ответ в HTML формате
- Пример промпта:
"Создай HTML страницу"
- Пример вывода:
<html><body><h1>Заголовок</h1></body></html>
5. "format": "xml"
- Описание: Ответ в XML формате
- Пример промпта:
"Верни данные в XML"
- Пример вывода:
<data><name>John</name><age>30</age></data>
6. "format": "yaml"
- Описание: Ответ в YAML формате
- Пример промпта:
"Верни конфигурацию в YAML"
- Пример вывода:
name: John age: 30
7. "format": "csv"
- Описание: Ответ в CSV формате
- Пример промпта:
"Верни данные в CSV"
- Пример вывода:
name,age\nJohn,30\nJane,25
8. "format": "code"
- Описание: Для генерации кода (поддерживает подсветку синтаксиса)
- Пример промпта:
"Напиши функцию на Python"
- Пример вывода:
def hello(): return "Hello World"
Практические примеры:
JSON запрос:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Верни JSON с информацией о пользователе: имя, возраст, город",
"format": "json",
"stream": false
}'
Markdown запрос:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши руководство по Git в markdown",
"format": "markdown",
"stream": false
}'
HTML запрос:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Создай простую HTML страницу с заголовком и параграфом",
"format": "html",
"stream": false
}'
Важные замечания:
- Не все модели одинаково хорошо поддерживают все форматы
- Формат - это указание модели, а не гарантия
- Лучше всего работают JSON и text
- Для сложных форматов лучше явно указывать в промпте
Комбинирование с промптом:
# Более надежный способ
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Верни ответ в формате JSON: {\"name\": \"string\", \"age\": number}",
"format": "json",
"stream": false
}'
Большинство моделей лучше всего работают с json
и text
форматами.
Параметры в options
:
5. "temperature": 0.8
- Что делает: Контролирует случайность ответов (0.0-1.0)
- Применение:
0.1
- детерминированные, повторяемые ответы0.8
- креативные, разнообразные ответы1.0
- максимальная случайность
- Пример:
"temperature": 0.3
для фактологических ответов
6. "top_p": 0.9
- Что делает: nucleus sampling - учитывает только топ-N% вероятных слов
- Применение:
0.1
- только самые вероятные слова0.9
- более разнообразный выбор
- Пример:
"top_p": 0.7
7. "top_k": 40
- Что делает: Ограничивает выбор только топ-K слов
- Применение:
10
- только 10 самых вероятных слов40
- хороший баланс
- Пример:
"top_k": 20
Толкование
Подробное объяснение top_p и top_k
top_p
(также known as nucleus sampling) - это алгоритм выборки, который ограничивает генерацию только теми словами, кумулятивная вероятность которых попадает в верхние P% распределения.
Как это работает:
- Сортировка вероятностей: Модель ранжирует все возможные следующие слова по вероятности
- Кумулятивная сумма: Складывает вероятности от самой высокой к самой низкой
- Выбор ядра: Берет только те слова, чья кумулятивная сумма ≤
top_p
- Перераспределение вероятностей: Нормализует вероятности выбранных слов
Математическая формула:
Выбрать множество V таких что: ∑(p(x) для x в V) ≥ p
где p = значение top_p (0.0-1.0)
Практические примеры:
Пример 1: top_p = 0.3
(очень строгий)
Возможные слова:
- "кот" (p=0.25)
- "собака" (p=0.20)
- "птица" (p=0.15)
- "рыба" (p=0.10)
- ... остальные (сумма p=0.30)
Выбор: только "кот" (0.25 ≤ 0.3)
Пример 2: top_p = 0.6
(умеренный)
Выбор: "кот" + "собака" + "птица" (0.25+0.20+0.15=0.6)
Пример 3: top_p = 0.9
(либеральный)
Выбор: почти все вероятные слова кроме самых маловероятных
Сравнение с top_k
:
Параметр | Что делает | Преимущества | Недостатки |
---|---|---|---|
top_p |
Динамический выбор вероятностей | Автоматически адаптируется к распределению | Может быть непредсказуемым |
top_k |
Фиксированное количество слов | Предсказуемость | Не учитывает распределение вероятностей |
Рекомендации по использованию:
Для точных ответов:
{
"top_p": 0.3,
"temperature": 0.1,
"top_k": 20
}
- Фактологические ответы
- Техническая документация
- Код генерация
Для творческих текстов:
{
"top_p": 0.9,
"temperature": 0.8,
"top_k": 60
}
- Поэзия
- Художественные тексты
- Креативные идеи
Для баланса:
{
"top_p": 0.7,
"temperature": 0.5,
"top_k": 40
}
- Диалоги
- Общие вопросы
- Аналитические тексты
Практические примеры запросов:
1. Строгий режим (top_p = 0.3)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Столица Франции это",
"top_p": 0.3,
"temperature": 0.1,
"stream": false
}'
Результат: “Париж” (максимально точный ответ)
2. Творческий режим (top_p = 0.9)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Опиши закат на море",
"top_p": 0.9,
"temperature": 0.8,
"stream": false
}'
Результат: Развернутое художественное описание
3. Комбинирование с другими параметрами
{
"top_p": 0.7,
"top_k": 50,
"temperature": 0.6,
"repeat_penalty": 1.1
}
Частые ошибки:
Слишком низкий top_p:
{"top_p": 0.1} # Может приводить к зацикливанию
Слишком высокий top_p:
{"top_p": 0.99} # Почти не фильтрует, может включать nonsense
Конфликт с temperature:
{"top_p": 0.3, "temperature": 0.9} # Противоречивые настройки
Золотые правила:
top_p
иtemperature
должны быть согласованы- Низкий top_p + низкая temperature = точность
- Высокий top_p + высокая temperature = креативность
- Тестируйте разные значения для вашей задачи
Оптимальные значения для большинства задач: top_p: 0.7-0.9
8. "num_predict": 512
- Что делает: Максимальное количество генерируемых токенов
- Применение:
64
- короткие ответы512
- средние ответы2048
- длинные тексты
- Пример:
"num_predict": 256
9. "stop": ["\n", "###"]
- Что делает: Символы/слова, при которых генерация останавливается
- Применение:
["\n"]
- остановиться в конце строки["###", "Конец"]
- кастомные стоп-слова
- Пример:
"stop": ["\n\n", "Ответ:"]
10. "repeat_penalty": 1.1
- Что делает: Штраф за повторения (>1.0 уменьшает повторения)
- Применение:
1.0
- без штрафа1.2
- сильный штраф за повторения
- Пример:
"repeat_penalty": 1.15
11. "presence_penalty": 0.0
- Что делает: Штраф за новые темы (положительные значения поощряют новизну)
- Применение:
-2.0
до2.0
12. "frequency_penalty": 0.0
- Что делает: Штраф за частые слова
- Применение:
-2.0
до2.0
13. "seed": 42
- Что делает: Seed для детерминированной генерации
- Применение: Одинаковый seed = одинаковые ответы
- Пример:
"seed": 12345
Толкование
Подробное объяснение SEED
Seed (сид) - это начальное значение для генератора псевдослучайных чисел. В контексте LLM это означает, что при одинаковых:
- Модели
- Промпте
- Параметрах
- И одинаковом seed
Вы получите идентичный результат каждый раз.
Как это работает технически:
- Инициализация:
seed = 42
- Детерминированность: Генератор случайных чисел начинает с одинаковой точки
- Воспроизводимость: Все “случайные” выборы становятся предсказуемыми
- Идентичный результат: Токен за токеном одинаковый вывод
Практические примеры:
Пример 1: Детерминированная генерация
# Первый запуск
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши короткое стихотворение о весне",
"seed": 42,
"stream": false
}'
# Второй запуск (ТОЧНО такой же результат)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши короткое стихотворение о весне",
"seed": 42,
"stream": false
}'
Пример 2: Разные seed = разные результаты
# Seed 42
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Придумай название для кофе",
"seed": 42,
"stream": false
}'
# Результат: "Утренняя свежесть"
# Seed 43 (немного другой)
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Придумай название для кофе",
"seed": 43,
"stream": false
}'
# Результат: "Золотой эспрессо"
Ключевые особенности:
1. Полная детерминированность
{
"seed": 123,
"temperature": 0.1, // Должен быть низким!
"top_p": 0.3 // Должен быть низким!
}
- ✅ Работает с низкой temperature
- ✅ Работает с низким top_p
- ❌ Не работает с высокой temperature
2. Зависимость от всех параметров
# Изменится ЛЮБОЙ параметр → изменится результат
seed=42 + prompt="A" ≠ seed=42 + prompt="A "
3. Постоянство между запусками
# Сегодня
seed=42 → "Ответ А"
# Завтра
seed=42 → "Ответ А" (тот же самый)
# После перезагрузки
seed=42 → "Ответ А" (все равно тот же)
Практическое применение:
1. Тестирование и отладка
# Тестирование изменений промпта
seed=42 + prompt="Версия 1" → Результат А
seed=42 + prompt="Версия 2" → Результат Б
# Можно точно сравнить улучшения
2. Воспроизведение результатов
# Найден хороший результат → сохраняем seed
curl ... -d '{
"prompt": "Креативное название",
"seed": 78901, # ← ЗАПОМНИТЬ ЭТОТ SEED
"temperature": 0.3
}'
# Результат: "Небесный аромат" (сохраняем для производства)
3. A/B тестирование моделей
# Сравнение моделей на одинаковых данных
seed=42 + model="qwen3:4b" → Результат А
seed=42 + model="llama3:8b" → Результат Б
# Честное сравнение без случайности
4. Обучение и демонстрации
# Демо для клиента - всегда одинаковый результат
seed=12345 → "Ваш идеальный бизнес-план..."
Важные ограничения:
1. Temperature должен быть низким
{
"seed": 42,
"temperature": 0.9, // ❌ Высокая randomness
"top_p": 0.9 // ❌ Высокая randomness
}
// Результат НЕ будет детерминированным!
2. Оптимальные настройки для детерминированности
{
"seed": 42,
"temperature": 0.1, // ✅ Низкая случайность
"top_p": 0.3, // ✅ Строгая выборка
"top_k": 20, // ✅ Ограниченный выбор
"repeat_penalty": 1.1 // ✅ Предсказуемость
}
3. Зависит от версии модели
# Модель обновилась → результаты могут измениться
seed=42 + model=v1.0 → Результат А
seed=42 + model=v1.1 → Результат Б (может отличаться)
Практические примеры настроек:
Для детерминированного кода:
{
"seed": 12345,
"temperature": 0.1,
"top_p": 0.2,
"top_k": 10,
"prompt": "Напиши функцию на Python для сложения чисел"
}
Для воспроизводимых аналитических ответов:
{
"seed": 67890,
"temperature": 0.2,
"top_p": 0.4,
"prompt": "Проанализируй преимущества технологии блокчейн"
}
Для тестирования промптов:
{
"seed": 11111,
"temperature": 0.1,
"prompt": "Версия 1 промпта..."
}
// Меняем только промпт, сохраняем seed
Как выбрать хороший seed?
# Любое целое число
"seed": 42
"seed": 1234567890
"seed": 999888777
# Но лучше избегать:
"seed": 0 # Иногда особый случай
"seed": 1 # Слишком простой
"seed": 123456 # Нормально
Пример полного workflow:
- Экспериментируем без seed, находим хорошие параметры
- Фиксируем параметры и промпт
- Добавляем
"seed": 12345
для воспроизводимости - Сохраняем конфигурацию для production
{
"model": "qwen3:4b",
"prompt": "Генерируй креативные названия для кофе",
"seed": 424242,
"temperature": 0.3,
"top_p": 0.6,
"top_k": 30,
"num_predict": 50
}
Seed - это мощный инструмент для обеспечения воспроизводимости и отладки LLM приложений!
14. "mirostat": 0
- Что делает: Алгоритм контроля перплексии (0, 1, 2)
- Применение:
0
- выключено1
или2
- для контроля качества
Толкование
Подробное объяснение MIROSTAT
Mirostat - это алгоритм контроля качества текста, который динамически регулирует параметры генерации чтобы поддерживать заданный уровень перплексии (сложности/предсказуемости текста).
Как это работает:
Mirostat постоянно измеряет перплексию генерируемого текста и подстраивает параметры в реальном времени чтобы достичь целевого значения.
Аналогия:
Представьте круиз-контроль в автомобиле:
- Без mirostat: Вы сами управляете газом/тормозом
- С mirostat: Автоматически поддерживает заданную скорость
Режимы работы:
"mirostat": 0
- Выключено
{"mirostat": 0}
- Обычная генерация
- Без контроля качества
- По умолчанию
"mirostat": 1
- Mirostat 1.0
{
"mirostat": 1,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1
}
- Более простой алгоритм
- Меньше вычислительных затрат
"mirostat": 2
- Mirostat 2.0
{
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1
}
- Улучшенная версия
- Более точный контроль
- Лучшее качество текста
Дополнительные параметры:
mirostat_tau
- Целевая перплексия
{"mirostat_tau": 5.0}
- Низкие значения (2.0-4.0): Более предсказуемый, простой текст
- Средние значения (4.0-6.0): Баланс сложности и читаемости
- Высокие значения (6.0-8.0): Более сложный, креативный текст
mirostat_eta
- Скорость обучения
{"mirostat_eta": 0.1}
- Низкие значения (0.01-0.1): Медленная адаптация, стабильность
- Высокие значения (0.1-0.3): Быстрая адаптация, агрессивные изменения
Практические примеры:
Пример 1: Техническая документация
{
"mirostat": 2,
"mirostat_tau": 3.0, // Низкая перплексия = простота
"mirostat_eta": 0.05,
"prompt": "Объясни концепцию API REST"
}
Результат: Четкий, структурированный текст без излишней сложности
Пример 2: Художественный текст
{
"mirostat": 2,
"mirostat_tau": 7.0, // Высокая перплексия = сложность
"mirostat_eta": 0.2,
"prompt": "Напиши поэтическое описание заката"
}
Результат: Богатый, образный язык с сложными конструкциями
Пример 3: Сбалансированный режим
{
"mirostat": 1,
"mirostat_tau": 5.0, // Баланс
"mirostat_eta": 0.1,
"prompt": "Напиши статью о искусственном интеллекте"
}
Сравнение с традиционными параметрами:
Без Mirostat:
{
"temperature": 0.7,
"top_p": 0.9,
"top_k": 40
}
// Качество может "плавать" в течение генерации
С Mirostat:
{
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1
}
// Постоянное качество throughout текста
Преимущества Mirostat:
- Стабильное качество: Избегает деградации в длинных текстах
- Автоматическая адаптация: Не нужно manually настраивать temperature
- Контроль сложности: Точная настройка уровня сложности текста
- Воспроизводимость: Предсказуемые результаты
Недостатки:
- Вычислительная стоимость: Дополнительные расчеты
- Сложность настройки: Нужно понимать перплексию
- Не для всех задач: Иногда проще использовать temperature
Рекомендации по настройке:
Для разных задач:
Задача | mirostat_tau | mirostat_eta |
---|---|---|
Техническая документация | 2.0-4.0 | 0.05-0.1 |
Новостные статьи | 4.0-6.0 | 0.1-0.2 |
Художественная литература | 6.0-8.0 | 0.2-0.3 |
Научные тексты | 5.0-7.0 | 0.1-0.15 |
Примеры полных конфигураций:
Высокое качество, стабильность:
{
"mirostat": 2,
"mirostat_tau": 5.0,
"mirostat_eta": 0.1,
"temperature": 0.3,
"top_p": 0.8
}
Креативность с контролем:
{
"mirostat": 2,
"mirostat_tau": 7.0,
"mirostat_eta": 0.25,
"temperature": 0.7
}
Практический пример запроса:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Напиши подробное руководство по использованию Docker",
"mirostat": 2,
"mirostat_tau": 4.0,
"mirostat_eta": 0.08,
"temperature": 0.2,
"stream": false
}' | jq -r '.response'
Когда использовать Mirostat:
✅ Длинные тексты (избегает деградации качества)
✅ Консистентность (техдокументация, руководства)
✅ Точный контроль сложности текста
✅ Автоматизация генерации контента
Когда НЕ использовать:
❌ Короткие ответы (излишне сложно)
❌ Максимальная скорость (дополнительные вычисления)
❌ Эксперименты (проще использовать temperature)
❌ Очень креативные задачи (может ограничивать)
Отладка Mirostat:
Если текст слишком простой:
{"mirostat_tau": 6.0} // Увеличить перплексию
Если текст слишком сложный:
{"mirostat_tau": 3.0} // Уменьшить перплексию
Если качество нестабильное:
{"mirostat_eta": 0.05} // Уменьшить скорость обучения
15. "num_ctx": 2048
- Что делает: Размер контекстного окна
- Применение: Зависит от модели
16. "num_thread": 8
- Что делает: Количество потоков для вычислений
- Применение: Обычно равно количеству ядер CPU
Дополнительные параметры:
17. "template": "{{ .Prompt }}"
- Что делает: Шаблон для форматирования промпта
- Применение:
"template": "Ответь как эксперт: {{ .Prompt }}\nОтвет:"
18. "context": [1, 2, 3]
- Что делает: Контекст предыдущего взаимодействия
- Применение: Для продолжения диалога
Толкование
Подробное объяснение CONTEXT
Context - это массив чисел, который представляет собой “память” предыдущего взаимодействия с моделью. Это позволяет продолжить диалог или текст точно с того места, где остановились.
Как это работает технически:
Контекст содержит эмбеддинги (векторные представления) предыдущего взаимодействия:
- Кодирование: Текст → числовой вектор
- Сохранение: Вектор сохраняется в
context
- Восстановление: При следующем запросе вектор передается обратно
- Продолжение: Модель “помнит” предыдущий разговор
Практический пример workflow:
Шаг 1: Первый запрос
response=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Расскажи о преимуществах Python",
"stream": false
}')
# Извлекаем ответ И контекст
answer=$(echo $response | jq -r '.response')
context=$(echo $response | jq '.context')
Шаг 2: Продолжение с контекстом
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "А какие недостатки?",
"context": '"$context"',
"stream": false
}'
Полный пример скрипта:
#!/bin/bash
# Первый запрос
echo "Шаг 1: Первый запрос"
response1=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Расскажи о Python для начинающих",
"stream": false
}')
answer1=$(echo $response1 | jq -r '.response')
context=$(echo $response1 | jq '.context')
echo "Ответ: $answer1"
echo "Контекст сохранен"
# Второй запрос с контекстом
echo -e "\nШаг 2: Продолжение диалога"
response2=$(curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3:4b",
"prompt": "Какие книги посоветуешь для изучения?",
"context": '"$context"',
"stream": false
}')
answer2=$(echo $response2 | jq -r '.response')
echo "Ответ: $answer2"
Формат контекста:
Контекст возвращается и принимается как массив чисел:
{
"context": [123, 456, 789, 12, 34, 56, 78, 90, ...]
}
Практические применения:
1. Многошаговые диалоги
# Пользователь: Привет
# Модель: Привет! Как дела?
# Пользователь: Хорошо, расскажи о погоде
# Модель: Помнит предыдущие реплики
2. Продолжение длинных текстов
# Начало: "В далекой галактике..."
# Продолжение: "где мы остановились..."
3. Технические консультации
# Шаг 1: Обсуждение проблемы
# Шаг 2: Уточняющие вопросы
# Шаг 3: Решение с учетом всей истории
4. Написание кода по частям
# Сначала: архитектура проекта
# Затем: реализация конкретных функций
# В конце: тестирование
Преимущества использования context:
По сравнению с передачей всей истории в prompt:
# Без context (громоздко):
"prompt": "Предыдущий разговор: Привет - Привет! Как дела? - Хорошо. Текущий вопрос: Что нового?"
# С context (эффективно):
"prompt": "Что нового?",
"context": [123, 456, 789]
Экономия токенов:
- ❌ Без context: Каждый раз передается вся история
- ✅ С context: Передаются только компактные эмбеддинги
Сохраняется состояние:
- Переменные
- Контекст разговора
- Стиль и тон
- Технические детали
Ограничения и важные моменты:
1. Совместимость моделей
# Контекст от одной модели может не работать с другой
context от "qwen3:4b" ≠ context для "llama3:8b"
2. Временные ограничения
# Контекст может "устаревать" после долгого времени
# Или после обновления модели
3. Размер контекста
# Слишком длинный контекст может быть обрезан
# Зависит от ограничений модели
4. Не для всех задач
# Для совершенно новых тем лучше не использовать context
# Чтобы избежать влияния предыдущего разговора
Пример с обработкой ошибок:
#!/bin/bash
ask_question() {
local prompt="$1"
local context="$2"
local data='{
"model": "qwen3:4b",
"prompt": "'"$prompt"'",
"stream": false'
if [ -n "$context" ] && [ "$context" != "null" ]; then
data+=', "context": '"$context"
fi
data+='}'
curl -s http://localhost:11434/api/generate -d "$data"
}
# Диалог
response1=$(ask_question "Привет! Как тебя зовут?")
answer1=$(echo $response1 | jq -r '.response')
context1=$(echo $response1 | jq '.context')
echo "Модель: $answer1"
response2=$(ask_question "А чем ты занимаешься?" "$context1")
answer2=$(echo $response2 | jq -r '.response')
echo "Модель: $answer2"
Использование в API чата:
Для чат-интерфейсов лучше использовать /api/chat
:
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:4b",
"messages": [
{"role": "user", "content": "Привет"},
{"role": "assistant", "content": "Привет! Как дела?"},
{"role": "user", "content": "Хорошо, а у тебя?"}
],
"stream": false
}'
Лучшие практики:
1. Сохраняйте контекст между запросами
# В приложении сохраняйте context в:
# - Базе данных
# - Файле
# - Памятии сессии
2. Очищайте контекст для новых тем
# Если тема полностью меняется:
context=null
3. Проверяйте валидность контекста
if [ "$context" != "null" ] && [ -n "$context" ]; then
# Используем контекст
else
# Новый разговор
fi
4. Ограничивайте длину диалога
# После N реплик начинайте новый контекст
# Чтобы избежать накопления ошибок
Продвинутое использование:
Сохранение контекста в файл:
# Сохраняем
echo $context > context.json
# Загружаем
context=$(cat context.json)
Многоуровневые диалоги:
# Разные контексты для разных тем
context_python=$(cat python_context.json)
context_js=$(cat js_context.json)
Воспроизведение диалогов:
# Для тестирования можно сохранить и воспроизвести
# exact диалог с одинаковым context
Пример для продакшена:
# Псевдокод для веб-приложения
sessions = {}
def handle_message(user_id, message):
if user_id not in sessions:
# Новый диалог
response = ollama.generate(prompt=message)
sessions[user_id] = {
'context': response['context'],
'history': [message, response['response']]
}
else:
# Продолжение диалога
response = ollama.generate(
prompt=message,
context=sessions[user_id]['context']
)
sessions[user_id]['context'] = response['context']
sessions[user_id]['history'].extend([message, response['response']])
return response['response']
Практические примеры настроек:
Для точных фактологических ответов:
{
"temperature": 0.1,
"top_p": 0.3,
"top_k": 20,
"repeat_penalty": 1.2
}
Для креативных текстов:
{
"temperature": 0.9,
"top_p": 0.95,
"top_k": 60,
"num_predict": 1024
}
Для детерминированных результатов:
{
"temperature": 0.1,
"seed": 42,
"top_p": 0.1
}