Что такое reflection loops для агентов и как они работают?
Краткий тезис
Reflection loops (циклы рефлексии) — это механизм, при котором агент после генерации ответа или действия получает обратную связь от второго агента-критика (или от самого себя) и на основе этой обратной связи улучшает свой результат. Работает итеративно: генерация → проверка → обратная связь → повторная генерация. Ограничивается числом итераций (обычно 3–5) для контроля затрат и времени. В контексте Agentic RAG reflection loops повышают качество и надёжность ответов, проверяя фактологическую точность, полноту и безопасность.
1. Термин: Reflection loop (цикл рефлексии)
Reflection loop — это архитектурный паттерн, в котором агент (исполнитель) не завершает работу после первого ответа, а подвергает его критике и дорабатывает. Ключевые компоненты:
- Actor (исполнитель) — агент, генерирующий ответ или выполняющий действие.
- Critic (критик) — агент (или тот же агент в другом режиме), который оценивает результат по заданным критериям.
- Feedback loop — канал передачи замечаний от критика к исполнителю.
- Iteration limit — максимальное число циклов (обычно 3–5), чтобы избежать бесконечного повторения и роста затрат.
Цикл рефлексии имитирует человеческий процесс: написал → перечитал → исправил → снова проверил.
2. Зачем нужны reflection loops в Agentic RAG
В Agentic RAG агент не просто ищет документы и генерирует ответ, а может планировать, использовать инструменты, обращаться к памяти. Это увеличивает вероятность ошибок:
- Галлюцинации — агент может добавить факты, не подтверждённые документами.
- Неполнота — ответ может не покрывать все аспекты запроса.
- Нарушение инструкций — агент может игнорировать системный промпт (например, отвечать на запрещённые темы).
- Ошибки инструментов — если агент вызывает API, результат может быть неверно интерпретирован.
Reflection loops позволяют выявить и исправить такие проблемы до выдачи ответа пользователю.
3. Архитектура reflection loop
Базовая схема:
[Запрос пользователя] → Actor (генерация ответа) → Critic (оценка)
↓
[Ответ OK?] → да → [Вывод пользователю]
нет
↓
Feedback (замечания) → Actor (доработка)
На практике часто используется два отдельных LLM-вызова (actor и critic), но возможна и саморефлексия (один и тот же LLM в двух ролях с разными промптами).
Пример реализации на псевдокоде:
def reflection_loop(query, max_iterations=3):
answer = actor.generate(query)
for i in range(max_iterations):
critique = critic.evaluate(query, answer)
if critique.is_ok():
return answer
answer = actor.revise(query, answer, critique.feedback)
return answer # возвращаем последнюю версию, даже если не идеальна
4. Типы проверок в reflection loop
Черновик упоминает три основных типа. Расширим их.
| Тип проверки | Описание | Пример промпта критика |
|---|---|---|
| Self-check (самопроверка) | Проверка, что ответ основан на фактах из контекста, нет галлюцинаций. | «Проверь, что каждое утверждение в ответе подтверждается предоставленными документами. Если нет — укажи, какие утверждения не подтверждены.» |
| Tool verification (верификация инструментов) | Если ответ содержит результат вызова API (например, погода, курс валют), проверяется, что результат корректен и не искажён. | «Сравни вывод агента с реальным ответом инструмента. Если есть расхождения, опиши их.» |
| Constitutional check (конституционная проверка) | Проверка на безопасность, соответствие политикам, отсутствие вредного контента. | «Убедись, что ответ не содержит оскорблений, не призывает к насилию, не раскрывает личные данные.» |
Дополнительные типы:
- Completeness check — проверка полноты: все ли подвопросы пользователя освещены.
- Consistency check — проверка непротиворечивости: нет ли взаимоисключающих утверждений в одном ответе.
- Instruction following — проверка соблюдения системных инструкций (формат, стиль, ограничения).
5. Процесс итерации и ограничения
Каждая итерация включает:
- Actor получает исходный запрос + предыдущий ответ + feedback от критика.
- Actor генерирует исправленную версию.
- Critic снова оценивает новую версию.
Ограничения
- Cost — каждый вызов LLM стоит денег и времени. 3–5 итераций — разумный компромисс.
- Latency — последовательные вызовы увеличивают время ответа. Для real-time систем может быть неприемлемо.
- Overcorrection — чрезмерная рефлексия может ухудшить ответ (например, удалить правильные детали).
- Feedback quality — если критик плохо обучен или промпт слабый, цикл может не улучшить ответ.
Максимум итераций — гиперпараметр. Обычно 3, реже 5. Если после лимита ответ неудовлетворительный, можно вернуть последнюю версию или сообщить об ошибке.
6. Преимущества и недостатки
| Преимущества | Недостатки |
|---|---|
| Повышение точности и фактологичности | Рост затрат (токены, время) |
| Снижение галлюцинаций | Увеличение latency |
| Возможность исправить ошибки инструментов | Риск переобучения критика (ложные срабатывания) |
| Гибкость: можно комбинировать разные типы проверок | Сложность отладки (нужно логировать каждую итерацию) |
| Улучшение соблюдения инструкций | Зависимость от качества промпта критика |
7. Сравнение с альтернативными подходами
| Подход | Описание | Когда использовать |
|---|---|---|
| Без рефлексии (single-shot) | Агент генерирует ответ один раз. | Когда скорость важнее точности, или задача простая. |
| Human-in-the-loop | Человек проверяет ответ и даёт обратную связь. | Когда ошибка критична (медицина, финансы), но человек медленный. |
| Multi-agent debate | Несколько агентов генерируют ответы и спорят, затем консенсус. | Когда нужна высокая надёжность, но затраты ещё выше. |
| Self-RAG | Агент сам рефлексирует на уровне токенов (специальные токены рефлексии). | Когда нужна тонкая настройка на уровне генерации (см. вопрос 10). |
Reflection loops — золотая середина между скоростью и качеством.
8. Реализация на Python (пример с LangGraph)
LangGraph — фреймворк для построения графов агентов. Пример узла рефлексии:
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
class AgentState(TypedDict):
query: str
answer: str
feedback: str
iteration: int
def actor_node(state: AgentState):
# генерация или доработка ответа
if state["iteration"] == 0:
answer = llm.invoke(f"Ответь на вопрос: {state['query']}")
else:
answer = llm.invoke(
f"Улучши ответ с учётом замечаний: {state['feedback']}\n"
f"Исходный ответ: {state['answer']}"
)
return {"answer": answer}
def critic_node(state: AgentState):
critique = llm.invoke(
f"Проверь ответ на фактологичность и полноту.\n"
f"Вопрос: {state['query']}\nОтвет: {state['answer']}\n"
f"Если есть проблемы, напиши 'ISSUES: ...', иначе 'OK'."
)
if "OK" in critique:
return {"feedback": "", "iteration": state["iteration"] + 1}
else:
return {"feedback": critique, "iteration": state["iteration"] + 1}
def should_continue(state: AgentState):
if state["feedback"] == "" or state["iteration"] >= 3:
return "end"
else:
return "continue"
graph = StateGraph(AgentState)
graph.add_node("actor", actor_node)
graph.add_node("critic", critic_node)
graph.set_entry_point("actor")
graph.add_conditional_edges("critic", should_continue, {
"continue": "actor",
"end": END
})
graph.add_edge("actor", "critic")
app = graph.compile()
Этот граф выполняет до 3 итераций, пока критик не скажет "OK".
9. Метрики оценки эффективности reflection loops
Чтобы понять, стоит ли внедрять рефлексию, нужно измерять:
- Improvement rate — доля ответов, которые улучшились после рефлексии (сравнение оценки до и после).
- Average iterations — среднее число циклов до принятия.
- Cost per query — среднее количество токенов на запрос (с рефлексией и без).
- Latency p95 — время ответа с учётом циклов.
- Faithfulness score (например, по RAGAS) — сравнение до и после.
Хорошая практика — A/B тестирование: половина запросов с рефлексией, половина без.
10. Связь с Agentic RAG
В Agentic RAG агент может:
- Искать документы → генерировать ответ → reflection loop проверяет, что ответ основан на найденных документах.
- Использовать инструменты (калькулятор, API) → reflection loop верифицирует результаты.
- Планировать многошаговые действия → reflection loop проверяет, что план выполнен корректно.
Reflection loops делают Agentic RAG более надёжным, особенно в сценариях, где цена ошибки высока (юридические консультации, медицинские рекомендации).
Пет-проект для закрепления
Задача Реализовать агента для ответа на вопросы по документации Python, который использует reflection loop для проверки фактов.
Инструменты Python, LangChain (или LangGraph), FAISS (векторная БД), OpenAI API (или локальная LLM).
Шаги:
- Загрузите документацию Python (например, несколько страниц про
asyncio) и разбейте на чанки. - Создайте векторное хранилище и retriever.
- Реализуйте агента-исполнителя, который получает запрос, ищет чанки и генерирует ответ.
- Реализуйте агента-критика, который проверяет ответ на фактологичность (каждое утверждение должно быть в найденных чанках).
- Соедините их в цикл с максимум 3 итерациями.
- Сравните качество ответов с рефлексией и без (например, вручную оцените 20 запросов).
Ожидаемый результат Вы увидите, что после рефлексии ответы становятся точнее, но растёт время и затраты токенов. Вы сможете подобрать оптимальное число итераций.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 565 | Что такое AI-агент и его компоненты |
| 566 | Планирование в агентах (Plan-and-Execute) |
| 567 | Использование инструментов (tool use) |
| 568 | Память агентов (memory) |
| 570 | Multi-agent системы |
| 571 | Human-in-the-loop |
Навигация
- Предыдущий: 568
- Следующий: 570
- Индекс: 00. Индекс разборов