1.4 Продвинутое машинное рассуждение: стратегии
Продвинутое машинное рассуждение объединяет набор практик, которые помогают языковым моделям решать сложные задачи надёжнее и прозрачнее. Цепочка рассуждений (Chain of Thought, CoT) предлагает вести решение поэтапно, раскладывая проблему на логичные шаги. Такой подход повышает точность и делает ход мысли проверяемым: пользователь видит, как модель пришла к ответу, что особенно полезно в задачах с несколькими условиями, сравнительном анализе и вычислениях. В образовательных сценариях CoT имитирует работу наставника, который ведёт по шагам, а не выдаёт готовый ответ, а в клиентской поддержке позволяет разбирать сложные запросы последовательно — уточнять детали, проверять предположения, исправлять недопонимания и давать корректный итог. Параллельно с CoT нередко применяют технику «внутренний монолог» (Inner Monologue), когда промежуточные рассуждения скрываются от пользователя и показывается только результат или минимально необходимая часть логики. Это уместно, когда раскрытие внутренних шагов может навредить обучению (нежелание давать «спойлеры»), когда речь идёт о конфиденциальной информации, либо когда лишние детали ухудшают пользовательский опыт.
Для воспроизводимых примеров начнём с подготовки окружения и клиента API.
# Импорт библиотек и загрузка ключей
import os
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
client = OpenAI()
def get_response_for_queries(query_prompts,
model_name="gpt-4o-mini",
response_temperature=0,
max_response_tokens=500):
"""
Возвращает ответ модели на основе списка сообщений (system/user...).
"""
model_response = client.chat.completions.create(
model=model_name,
messages=query_prompts,
temperature=response_temperature,
max_tokens=max_response_tokens,
)
return model_response.choices[0].message["content"]
Далее зафиксируем функцию-обёртку для запросов и перейдём к CoT‑промптингу, где рассуждения структурируются шагами под специальный разделитель. Системное сообщение описывает этапы анализа, а пользовательский ввод заключён в разделители, что упрощает разбор и последующую постобработку.
step_delimiter = "####"
system_prompt = f"""
Следуй шагам, разделяя их маркером '{step_delimiter}'.
Шаг 1:{step_delimiter} Проверь, идёт ли речь о конкретном продукте (а не о категории).
Шаг 2:{step_delimiter} Если да, сопоставь его с перечнем товаров (бренд, характеристики, цена).
[Здесь разместите список товаров]
Шаг 3:{step_delimiter} Выяви предположения пользователя (сравнения/спецификации).
Шаг 4:{step_delimiter} Проверь эти предположения по данным о товарах.
Шаг 5:{step_delimiter} Исправь неточности, опираясь только на список, и ответь вежливо.
"""
example_query_1 = "How does the BlueWave Chromebook compare to the TechPro Desktop in terms of cost?"
example_query_2 = "Are televisions available for sale?"
query_prompts_1 = [
{'role': 'system', 'content': system_prompt},
{'role': 'user', 'content': f"{step_delimiter}{example_query_1}{step_delimiter}"},
]
query_prompts_2 = [
{'role': 'system', 'content': system_prompt},
{'role': 'user', 'content': f"{step_delimiter}{example_query_2}{step_delimiter}"},
]
response_to_query_1 = get_response_for_queries(query_prompts_1)
print(response_to_query_1)
response_to_query_2 = get_response_for_queries(query_prompts_2)
print(response_to_query_2)
Чтобы сопоставить подходы, сначала выведем полный ответ с промежуточными шагами CoT, а затем применим вариант Inner Monologue, в котором пользователю показывается только конечная часть. Если модель возвращает текст, где шаги отделены step_delimiter
, можно оставить лишь заключительный фрагмент — так сохраняется лаконичность интерфейса там, где «внутренняя кухня» не нужна.
try:
final_response = response_to_query_2.split(step_delimiter)[-1].strip()
except Exception:
final_response = "Извините, возникла проблема. Попробуйте другой вопрос."
print(final_response)
В результате мы получаем два режима одного решения: подробный, с видимой цепочкой шагов, и краткий, где показывается только итог. В обоих случаях помогает ясная формулировка промптов; их стоит регулярно уточнять с учётом наблюдаемого поведения модели. Когда важна чистота интерфейса и отсутствие лишних деталей, целесообразно использовать Inner Monologue и показывать лишь результат, сохраняя при этом возможность внутреннего пошагового анализа для контроля качества.
Теоретические вопросы
- Что такое Цепочка рассуждений (Chain of Thought, CoT) и чем она полезна для задач, требующих нескольких шагов?
- Как прозрачность CoT повышает доверие пользователей к ответам модели?
- Каким образом CoT помогает в образовательных задачах?
- Как цепочка рассуждений улучшает качество ответов чат-ботов поддержки?
- Что такое «Внутренний монолог» (Inner Monologue) и чем он отличается от CoT по способу подачи информации пользователю?
- Почему Inner Monologue важен при работе с конфиденциальной информацией?
- Как Inner Monologue помогает в обучающих сценариях, не раскрывая промежуточные «спойлеры»?
- Какие шаги необходимы для подготовки окружения под примеры, использующие OpenAI API?
- Как устроена функция
get_response_for_queries
? - Как CoT-промптинг облегчает обработку сложных запросов?
- Как структура system/user-промптов помогает отвечать по вопросам о товарах?
- Чем полезно извлекать только финальную часть ответа при использовании Inner Monologue?
Практические задания
- Реализуйте функцию
chain_of_thought_prompting(query)
, которая генерирует системный промпт со структурой шагов и оборачивает запрос пользователя разделителем. - Напишите функцию
get_final_response(output, delimiter)
, извлекающую последнюю часть ответа и обрабатывающую возможные ошибки. - Создайте скрипт: отправьте два запроса — один с CoT, второй с Inner Monologue; распечатайте полученные ответы.
- Реализуйте функцию
validate_response_structure(resp, delimiter)
, которая проверяет, что в ответе присутствует необходимое число шагов. - Создайте класс
QueryProcessor
, который инкапсулирует логику CoT и Inner Monologue (загрузка ключей, сборка промптов, отправка запросов, постобработка и обработка ошибок).