Практические заметки: Обучение LangGraph: путешествие среди агентов и досок
Пошаговое руководство по Practical notes: Learning LangGraph : A Journey Through Agents, Blackboards: contracts, checks, and drop-in code slots для команд, использующих эту архитектуру.
Источники: Learning LangGraph : A Journey Through Agents, Blackboards, and Bottlenecks
В следующих заметках описывается практический подход к изучению материала «Learning LangGraph : A Journey Through Agents, Blackboards, and Bottlenecks». Основное внимание уделяется контрактам, проверкам и местам для вставки кода, а не мотивирующей подаче материала. При изучении обзора сначала запишите контракт: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Рядом с функциональными результатами записывайте время выполнения и стоимость токенов или запросов. Отображение затрат с самого начала предотвращает неожиданные расходы при переходе от демо-версии к общим средам.
Шаг 1: Минимальный агент
Шаг 1: Минимальный агент наилучшим образом функционирует, когда его рассматривают как измеримую поверхность. Соберите один пример успешной работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работы. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь граф. Сохраняйте состояние графа простым и типизированным. Вложенные структуры данных скрывают информацию о том, какой узел заполнил тот или иной поле, и приводят к нарушению возобновления работы после перерывов.
from langchain.agents import create_agent # langchain 1.x (NOT langgraph.prebuilt)
from langchain.tools import tool
from langchain_anthropic import ChatAnthropic
# 1. Model
llm = ChatAnthropic(model="claude-haiku-4-5", max_tokens=1024)
# 2. Tool — a plain function + @tool.
# - type hints (drug_name: str) become the input schema
# - the docstring is what the LLM reads to decide WHEN to call it
# The model only "sees" the signature + docstring, so write the docstring
# like an API description.
@tool
def get_drug_targets(drug_name: str) -> str:
"""Return the protein targets for a given drug name."""
return "EGFR, BRAF" # real data-source call goes here
# 3. System prompt — a plain string
SYSTEM_PROMPT = "You are a research assistant. Use the tools to gather evidence."
# 4. Build the agent
agent = create_agent(model=llm, tools=[get_drug_targets], system_prompt=SYSTEM_PROMPT)
# 5. Run it — pass in {"messages": [...]}, get the full message list back
result = agent.invoke({"messages": [{"role": "user", "content": "What does metformin target?"}]})
print(result["messages"][-1].content) # last message = final answer
@tool
def calculator(expression: str) -> str:
"""Evaluate a basic arithmetic expression like '2 + 2 * 3'."""
return str(eval(expression)) # fine for learning; never eval untrusted input in prod
Шаг 2: Обеспечение взаимодействия двух агентов
Шаг 2: Наилучший способ заставить двух агентов взаимодействовать — рассматривать это как измеримую процедуру. Соберите один идеальный пример взаимодействия, один пример сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Документируйте одновременно успешный и восстановительный пути работы. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не этапом последующей доработки. Сохраняйте структуру графа простой и типизированной; вложенные структуры скрывают информацию о том, какой узел заполнил тот или иной поле, и мешают возобновлению работы после прерываний.
Вариант 1: Сообщения
Вариант 1: Система Messages работает наилучшим образом, когда рассматривается как измеримая структура. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работы. Предпочитайте небольшие, тестируемые единицы вместо обширных скриптов. При сбое какого-либо шага причина должна быть связана с конкретной ответственностью, а не с запутанной цепочкой операций. Сохраняйте простую и типизированную структуру графа. Вложенные элементы мешают понять, какой узел заполнил тот или иной поле, и приводят к нарушению продолжения работы после перерывов. Вариант 1: Система Messages работает наилучшим образом, когда рассматривается как измеримая структура. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работы. Записывайте временные показатели, а также стоимость токенов или запросов вместе с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные расходы при переходе от демо-среды к общедоступным средам.
Вариант 2: Blackboard
Для варианта 2: Blackboard — определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь граф. Вводите ручное утверждение для ребер, связанных с тратой денег или изменением производственных данных. Подключение на этапе компиляции не гарантирует полноты бизнес-логики.
Шаг 3: Получение введенных данных из одного агента
Для шага 3: получения введенных данных из одного агента необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Необходимо задокументировать как успешный, так и восстановительный пути выполнения. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не элементами последующей доработки. Внедрять утверждение человеком для операций, связанных с тратой денег или изменением производственных данных. Подключение на этапе компиляции не гарантирует полноты функционала продукта.
from pydantic import BaseModel, Field
class ResearchOutput(BaseModel):
attraction: str = Field(description="2 sentences about the attraction")
city: str = Field(description="1 sentence about the city it is in")
agent = create_agent(
model=llm,
tools=[attraction_info, city_info],
system_prompt=SYSTEM_PROMPT,
response_format=ResearchOutput, # <- agent emits this typed object
)
result = agent.invoke({"messages": [...]})
out = result["structured_response"] # a ResearchOutput instance
out.attraction # str
out.city # str
def research_node(state):
out = research(state["topic"]) # ResearchOutput
return {"research": out.attraction, "city": out.city}
Связь, которая создается
Для обеспечения необходимой связности определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага причина должна быть связана с конкретной функцией, а не с запутанной структурой обработки. Внедряйте человеческое утверждение для операций, связанных с тратой денег или изменением производственных данных. Настройка на этапе компиляции не гарантирует полноты решения бизнес-задач. Для обеспечения необходимой связности определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Записывайте время выполнения, а также стоимость токенов или запросов рядом с функциональными результатами. Отображение стоимости на ранних этапах предотвращает неожиданные счета при переходе от демо-среды к общедоступным средам.
SYSTEM_PROMPT = "...\n" + "\n".join(f"- {t.name}: {t.description}" for t in TOOLS)
Четыре варианта, по одному дисплею каждый
При работе над вариантом «Четыре варианта, по одному дисплею каждый» сначала запишите условия работы: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой список поможет избежать ошибок при последующих изменениях кода. Храните конфигурацию вне кода приложения. Файлы с настройками окружения, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код. Создавайте контрольные точки после дорогостоящих операций. Функция возобновления работы не должна снова взимать плату за один и тот же вызов большой языковой модели, если оператор попытается выполнить следующий шаг заново.
Шаг 4: Почему это так медленно — и что на самом деле помогает решить проблему
При работе над шагом 4: «Почему это так медленно — и что на самом деле решает проблему», сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Документируйте одновременно успешный и восстановительный сценарии работы. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не элементами последующей доработки. Выполняйте контрольные точки после дорогостоящих операций. Механизм возобновления работы не должен повторно взимать плату за один и тот же вызов LLM, когда оператор пытается выполнить следующий этап.
def _crowd_score_sync(attraction: str) -> str: # plain blocking function
total = 0
for i in range(60_000_000):
total += i
return f"... {total % 100} ..."
@tool
async def crowd_score(attraction: str) -> str:
return await asyncio.to_thread(_crowd_score_sync, attraction)
Почему агент ReAct всё равно остается медленным
При анализе причин медленной работы агента ReAct в любых условиях сначала запишите контракт: необходимые входные данные, сигнал о успехе и последствия частичной неудачи. Такой чек-лист помогает сохранять честность при последующих изменениях кода. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. Если какой-то шаг не сработает, причина неудачи должна указывать на конкретную ответственность, а не на запутанную цепочку операций. Выполняйте контрольные точки после дорогостоящих шагов. Механизм возобновления работы не должен повторно взимать плату за один и тот же вызов большой языковой модели при повторной попытке обработки последующего элемента. При анализе причин медленной работы агента ReAct в любых условиях сначала запишите контракт: необходимые входные данные, сигнал о успехе и последствия частичной неудачи. Такой чек-лист помогает сохранять честность при последующих изменениях кода. Записывайте время выполнения и стоимость токенов или запросов рядом с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные счета при переходе от демо-среды к общедоступным средам.
Шаг 5: Одновременная работа с целыми пайплайнами
Шаг 5: Одновременная работа с целыми пайплайнами наилучшим образом функционирует, когда рассматривается как измеримая структура. Соберите один эталонный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь граф. Сохраняйте структуру графа простой и типизированной. Вложенные структуры данных маскируют информацию о том, какой узел записал какое поле, и мешают возобновлению работы после прерываний.
Шаг 6: Обеспечение эффективной работы кэширования
Шаг 6: Для эффективной работы кэширования лучше всего рассматривать его как измеримую систему. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работы. Задокументируйте одновременно успешный и восстановительный сценарии. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не этапом последующей доработки. Сохраняйте структуру графа простой и типизированной. Вложенные структуры данных скрывают информацию о том, какой узел заполнил тот или иной поле, и мешают возобновлению работы после прерываний.
system_prompt = "You are a travel research agent..." # string: no keys
content = [{ # dict: has keys
"type": "text",
"text": "You are a travel research agent...",
"cache_control": {"type": "ephemeral"}, # <- attaches here
}]
from langchain_anthropic.middleware import AnthropicPromptCachingMiddleware
agent = create_agent(
model=llm, tools=[...], system_prompt=SYSTEM_PROMPT, # plain string
middleware=[AnthropicPromptCachingMiddleware()],
)
Шаг 7: Обеспечение долговечности «доски»
Шаг 7: Для обеспечения долговечности «доски» наилучшим образом работает подход, при котором она рассматривается как измеримая поверхность. Сохраните один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Предпочитайте небольшие, тестируемые единицы вместо обширных скриптов. Когда какой-то шаг терпит неудачу, причина сбоя должна указывать на конкретного ответственного, а не на запутанную цепочку операций. Сохраняйте структуру графа простой и типизированной. Вложенные структуры скрывают информацию о том, какой узел заполнил тот или иной поле, что приводит к нарушению работоспособности после перерывов. Шаг 7: Для обеспечения долговечности «доски» наилучшим образом работает подход, при котором она рассматривается как измеримая поверхность. Сохраните один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Записывайте временные показатели, а также стоимость токенов или запросов рядом с функциональными результатами. Отображение стоимости на раннем этапе предотвращает неожиданные расходы при переходе с демо-среды в общедоступные среды.
Чек-лист операций
Для операционного чек-листа необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии.
Рассматривайте этот этап как контракт между входными данными и проверенными результатами. Укажите названия элементов, определите критерии успеха и не допускайте молчаливого частичного завершения работы.
Внедряйте человеческое утверждение для операций, связанных с тратой денег или изменением производственных данных. Компиляционная настройка не заменяет полноты обработки в бизнес-процессах.
Напишите краткий руководство: как обновлять ключи, как опустошать очередь, как откатить последнюю загрузку данных.
Записывайте время выполнения операций, стоимость токенов или запросов вместе с функциональными результатами. Ясность стоимости на ранних этапах предотвращает неожиданные счета при переходе с демо-среды в общедоступные среды.
Внедряйте человеческое утверждение для операций, связанных с расходованием средств или изменением производственных данных. Конфигурация во время компиляции не гарантирует полноты функционала бизнес-приложения.
Перед внедрением всей стек-технологии заморозьте версии, сохраните эталонные записи для критически важных этапов и уточните шаги отката. В совместных средах необходимы ограничения на частоту запросов, проверки принадлежности пользователя и четко определенный ответственный за обновление секретов. Лучше выбирать надежность, чем креативные одноразовые демонстрации.
Примечание для 7a480fca3eb9: не храните ключи поставщика в репозитории, установите лимит токенов на сессию и сохраняйте записи рядом с фикстурами для оценки, чтобы последующие замены моделей оставались сопоставимыми.
При работе над заметкой по усилению безопасности номер 0 сначала запишите условия соглашения: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Документируйте одновременно успешный сценарий работы и сценарий восстановления. Повторные попытки, проверки со стороны человека и обработка неработоспособных сообщений являются частью продукта, а не последующими доработками.
Деталь усиления безопасности 0/913: измерьте время выполнения, класс ошибки и расход токенов для этой заметки, затем решите, следует ли сохранять изменение на основе фиксированного набора критериев, а не на основе единичных примеров.
Заметка по усилению безопасности номер 1 будет работать наилучшим образом, если рассматривать её как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Рассматривайте этот этап как соглашение между входными данными и проверенными выходными результатами. Дайте названия соответствующим элементам, определите критерии успеха и не допускайте молчаливого частичного завершения работы.
Подробности усиления безопасности 1/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменение на основе фиксированного набора критериев, а не на основе единичных примеров.
Для записи о втором этапе усиления безопасности определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Храните конфигурацию вне кода приложения: файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, которое операторы могут проверять, не читая весь код.
Подробности усиления безопасности 2/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменение на основе фиксированного набора критериев, а не на основе единичных примеров.
При работе над пунктом усиления безопасности №3 сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Лучше использовать небольшие, тестируемые модули вместо обширных скриптов. Если какой-то шаг не сработает, причина неудачи должна указывать на конкретную ответственность, а не на запутанную цепочку операций.
Подробность усиления безопасности 3/913: измерьте время выполнения, класс ошибки и расход токенов для данного пункта, затем решите, следует ли сохранять изменение, опираясь на заранее определенный набор критериев, а не на устные оценки.
Пункт усиления безопасности №4 будет работать наилучшим образом, если рассматривать его как объект с измеримыми показателями. Соберите один эталонный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Записывайте время выполнения, а также стоимость в токенах или запросах рядом с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные расходы при переходе с демо-среды в общедоступные среды.
Подробности усиления безопасности 4/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора вопросов, а не на основе единичных случаев.
Для записи об усилении безопасности 5 определите входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Документируйте как успешный путь, так и путь восстановления одновременно. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не последующими улучшениями.
Подробности усиления безопасности 5/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора вопросов, а не на основе единичных случаев.
При работе над пунктом усиления безопасности №6 сначала запишите контракт: необходимые входные данные, сигнал о успехе и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Рассматривайте этот этап как контракт между входными данными и проверенными выходными данными. Дайте названия результатам работы, определите критерии успеха и не допускайте молчаливого частичного выполнения задач.
Подробности усиления безопасности 6/913: измерьте время выполнения, класс ошибки и расход токенов для данного пункта, затем решите, следует ли сохранять изменение на основе фиксированного набора критериев, а не на основе единичных примеров.
Пункт усиления безопасности №7 будет работать наилучшим образом, если рассматривать его как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, которое операторы могут проверять, не читая весь код.
Подробности усиления безопасности 7/913: измерьте время выполнения операции, класс ошибки и количество потраченных токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора критериев, а не на основе единичных примеров.
Для записи об усилении безопасности 8 определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Предпочтительнее использовать небольшие, проверяемые единицы кода вместо обширных скриптов. При сбое шага он должен указывать на конкретную причину, а не на сложную взаимосвязь между компонентами.
Подробности усиления безопасности 8/913: измерьте время выполнения операции, класс ошибки и количество потраченных токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора критериев, а не на основе единичных примеров.
При работе над пунктом усиления безопасности №9 сначала запишите условия работы: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Рядом с функциональными результатами записывайте время выполнения, стоимость токенов или запросов. Очевидность затрат с самого начала предотвращает неожиданные расходы при переходе с демо-среды в общедоступные среды.
Подробности усиления безопасности 9/913: измерьте время выполнения, класс ошибки и расход токенов для данного пункта, затем решите, следует ли сохранять изменение на основе фиксированного набора критериев, а не на основе устных оценок.
Пункт усиления безопасности №10 лучше всего реализовывать как измеримую составляющую. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Документируйте одновременно успешный и восстановительный сценарии работы. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.
Подробности усиления безопасности 10/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора критериев, а не на основе единичных примеров.
Для записи об усилении безопасности 11 определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Рассматривайте этот этап как контракт между входными данными и проверенными результатами. Дайте названия результатам работы, определите критерии успеха и не соглашайтесь на молчаливое частичное выполнение задачи.
Подробности усиления безопасности 11/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора критериев, а не на основе единичных примеров.
При работе над пунктом усиления безопасности 12 сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Храните конфигурацию отдельно от кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код.
Подробности усиления безопасности 12/913: измерьте время выполнения, класс ошибки и количество использованных токенов для данного пункта, затем решите, следует ли сохранять изменение, опираясь на установленный набор критериев, а не на случайные наблюдения.
Пункт усиления безопасности 13 будет работать наилучшим образом, если рассматривать его как измеримую поверхность. Соберите один эталонный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Предпочитайте небольшие, проверяемые на примерах блоки кода вместо обширных скриптов. Когда какой-то шаг не срабатывает, причина должна указывать на конкретную ответственность, а не на запутанную цепочку операций.
Подробность усиления безопасности 13/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора вопросов, а не на основе единичных примеров.
Для записи о усилении безопасности 14 определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Записывайте время выполнения и стоимость токенов или запросов рядом с функциональными результатами. Отображение стоимости заранее предотвращает неожиданные счета при переходе с демо-среды в общедоступные среды.
Подробность усиления безопасности 14/913: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменения на основе фиксированного набора вопросов, а не на основе единичных примеров.
При работе над пунктом усиления безопасности 15 сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Документируйте одновременно успешный сценарий работы и сценарий восстановления. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не последующими доработками.
Подробности усиления безопасности 15/913: измерьте время выполнения, класс ошибки и количество использованных токенов для этого пункта, затем решите, следует ли сохранять изменение, опираясь на фиксированный набор критериев, а не на устные описания.