Память и состояние агента на практике
От теории к коду: реализуем простую память агента с обрезкой истории и хранением фактов — то, что в настоящем агенте держит контекст между шагами.
Состояние агента — то, что он помнит прямо сейчас: усечённая история диалога (краткосрочная память) плюс набор сохранённых фактов (зачаток долгосрочной).
Что должна уметь память
- добавлять реплики (роль + текст) и хранить только последние — чтобы влезть в окно;
- сохранять отдельные факты «ключ → значение» надолго;
- выдавать текущий контекст для передачи модели.
Класс памяти
class AgentMemory:
def __init__(self, max_turns=3):
self.history = [] # краткосрочная: список (роль, текст)
self.max_turns = max_turns # сколько реплик держим
self.facts = {} # долгосрочная: ключ -> значение
def add(self, role, text):
self.history.append((role, text))
# обрезаем до последних max_turns реплик (эмуляция окна)
self.history = self.history[-self.max_turns:]
def remember(self, key, value):
self.facts[key] = value
def context(self):
return "\n".join(f"{r}: {t}" for r, t in self.history)
mem = AgentMemory(max_turns=3)
mem.add("user", "Меня зовут Аня")
mem.remember("имя", "Аня") # важный факт — в долгосрочную память
mem.add("agent", "Приятно познакомиться, Аня")
mem.add("user", "Столица Франции?")
mem.add("agent", "Париж")
print("Краткосрочный контекст (последние 3 реплики):")
print(mem.context())
print("---")
print("Долгосрочный факт 'имя':", mem.facts["имя"])
Вывод:
Краткосрочный контекст (последние 3 реплики): agent: Приятно познакомиться, Аня user: Столица Франции? agent: Париж --- Долгосрочный факт 'имя': Аня
Важная деталь: первая реплика «Меня зовут Аня» выпала из краткосрочной истории (окно — 3 реплики), но имя сохранилось в долгосрочных фактах. Так и работает разделение памяти: сырой диалог обрезается, а важное выносится в надёжное хранилище.
Почему обрезка важна
Если не ограничивать историю, в длинном диалоге она перерастёт контекстное окно — модель либо обрежет её непредсказуемо, либо вызов вообще не пройдёт. Управляемая обрезка (или суммаризация) держит размер под контролем и оставляет самое свежее.
Состояние сверх диалога
Память — частный случай состояния агента. Кроме истории, агент может хранить: счётчик шагов, промежуточные результаты, список выполненных подзадач, флаг «нужен человек». Аккуратная работа с состоянием — то, что отличает рабочего агента от хрупкого скрипта; именно поэтому фреймворки вроде LangGraph строятся вокруг явного состояния (раздел 6).
state = {"step": 0, "done_subtasks": [], "need_human": False}
def do_subtask(state, name):
state["step"] += 1
state["done_subtasks"].append(name)
return state
state = do_subtask(state, "собрать данные")
state = do_subtask(state, "посчитать")
print("Шагов сделано:", state["step"])
print("Выполнено:", state["done_subtasks"])
print("Нужен человек:", state["need_human"])
Вывод:
Шагов сделано: 2 Выполнено: ['собрать данные', 'посчитать'] Нужен человек: False
Итог
- Память агента = усечённая краткосрочная история + долгосрочные факты «ключ-значение».
- Обрезка истории удерживает контекст в пределах окна; важное выносится в долгосрочное хранилище.
- Память — часть состояния агента; явное состояние (шаги, подзадачи, флаги) делает агента надёжнее.