Доска
Если проблема всегда одна и та же, то предыдущие архитектуры могли бы сработать…
Но что, если лучший следующий шаг зависит от результатов предыдущего? Жесткая последовательность может быть невероятно неэффективной, заставляя систему выполнять ненужные шаги.
Вот тут-то и пригодится архитектура Blackboard . Это более продвинутый и гибкий способ координации работы команды специалистов. Идея основана на том, как эксперты решают проблемы.
Они собираются вокруг доски, общего рабочего пространства, где каждый может записать свои наблюдения.
Затем руководитель просматривает доску объявлений и решает, кто должен внести свой вклад следующим.
При разработке архитектуры Blackboard — это шаблон для решения сложных, плохо структурированных задач, где путь к решению заранее неизвестен. Он позволяет применять спонтанную, оппортунистическую стратегию, что делает его идеальным для динамического осмысления ситуации или сложной диагностики, где следующий шаг всегда является реакцией на последнее открытие.
Давайте разберемся в этом процессе...


Память Blackboard (создано пользователем)
Фарид Хан
)
Разделяемая память (как в «Доске объявлений»): центральное хранилище данных содержит текущее состояние проблемы и все полученные на данный момент результаты.
Специалисты-агенты: Группа независимых агентов, каждый из которых обладает определенными навыками, следит за доской объявлений.
Контроллер: Центральный агент-«контроллер» также следит за доской. Его задача — анализировать текущее состояние и решать, какой специалист лучше всего подготовлен к следующему шагу.
Оппортунистическая активация: Контроллер активирует выбранного агента. Агент считывает данные с доски, выполняет свою работу и записывает результаты обратно.
Итерация: Этот процесс повторяется, при этом контроллер динамически выбирает следующего агента, пока не решит, что проблема решена.
Давайте начнём его строить.
Наиболее важной частью этой системы является интеллектуальный контроллер . В отличие от нашего предыдущего мета-контроллера, который выполнял только однократную отправку команды, этот работает в цикле. После выполнения каждой команды специалистом контроллер повторно оценивает доску объявлений и решает, что делать дальше.
class BlackboardState ( TypedDict ):
user_request: str
blackboard: List [ str ] # Общее рабочее пространство
available_agents: List [ str ]
next_agent: Optional [ str ] # Решение контроллера
class ControllerDecision ( BaseModel ):
next_agent: str = Field(description= "Имя следующего вызываемого агента. Должно быть одним из ['News Analyst', 'Technical Analyst', 'Financial Analyst', 'Report Writer'] или 'FINISH'." )
reasoning: str = Field(description= "Краткое обоснование выбора следующего агента." )
def controller_node ( state: BlackboardState ):
"""Интеллектуальный контроллер, который анализирует доску и принимает решение о следующем шаге."""
console. print ( "--- КОНТРОЛЛЕР: Анализ доски... ---" )
controller_llm = llm.with_structured_output(ControllerDecision)
blackboard_content = "\n\n" .join(state[ 'blackboard' ])
prompt = f"""Вы являетесь центральным контроллером многоагентной системы. Ваша задача — проанализировать общую доску и исходный запрос пользователя, чтобы решить, какой специализированный агент должен запуститься следующим.
**Исходный запрос пользователя:**
{state[ 'user_request' ]}
**Текущее содержимое доски:**
---
{blackboard_content if blackboard_content else "Доска в данный момент пуста." }
---
**Доступные специализированные агенты:**
{ ', ' .join(state[ 'available_agents' ])}
**Ваша задача:**
1. Внимательно прочтите запрос пользователя и текущее содержимое доски.
2. Определите, какой *следующий логический шаг* необходимо предпринять, чтобы приблизиться к полный ответ.
3. Выберите единственного наиболее подходящего агента для выполнения этого шага.
4. Если запрос был полностью обработан, выберите «ЗАВЕРШИТЬ».
Предоставьте свое решение в требуемом формате.
"""
decision = controller_llm.invoke(prompt)
console. print ( f"--- КОНТРОЛЛЕР: Решение состоит в вызове ' {decision.next_agent} '. Причина:{decision.reasoning} ---" )
return {"next_agent" : decision.next_agent}
Теперь нам осталось только подключить это в LangGraph. Ключевым моментом является центральный цикл: любой специализированный агент после выполнения задания отправляет управление обратно для принятия Controllerследующего решения.
# ... (специализированные узлы определяются аналогично многоагентной системе) ...
bb_graph_builder = StateGraph(BlackboardState)
bb_graph_builder.add_node( "Controller" , controller_node)
bb_graph_builder.add_node( "News Analyst" , news_analyst_bb)
# ... добавить другие специализированные узлы ...
bb_graph_builder.set_entry_point( "Controller" )
def route_to_agent ( state: BlackboardState ):
return state[ "next_agent" ]
bb_graph_builder.add_conditional_edges( "Controller" , route_to_agent, {
"News Analyst" : "News Analyst" ,
# ... другие маршруты ...
"FINISH" : END
})
# После выполнения любого специализированного узла управление всегда возвращается к Controller
bb_graph_builder.add_edge( "News Аналитик" , "Контроллер" )
# ... другие ребра обратно к контроллеру ...
blackboard_app = bb_graph_builder.compile ( )

Архитектура Blackboard (создано компанией...)
Фарид Хан
)
Чтобы понять, почему это намного лучше, чем жесткая последовательность, давайте дадим ему задачу с условной логикой, в которой последовательный агент потерпит неудачу.
dynamic_query = "Найти последние важные новости о Nvidia. В зависимости от настроения новости провести либо технический анализ (если новость нейтральная или позитивная), либо финансовый анализ (если новость негативная)."
initial_bb_input = { "user_request" : dynamic_query, "blackboard" : [], "available_agents" : [ "News Analyst" , "Technical Analyst" , "Financial Analyst" , " Report Writer " ] }
final_bb_output = blackboard_app.invoke(initial_bb_input, { "recursion_limit" : 10 })
console. print ( "\n--- [bold green]Итоговый отчет из системы Blackboard[/bold green] ---" )
console. print (Markdown(final_bb_output[ 'blackboard' ][- 1 ]))
--- КОНТРОЛЛЕР: Анализ доски... ---
Решение: вызвать «Аналитика новостей»...
--- Состояние доски ---
АГЕНТ «Аналитик новостей» работает...
--- КОНТРОЛЛЕР: Анализ доски... ---
Решение: вызвать «Технического аналитика» (новости позитивные)...
--- Состояние доски ---
Отчет 1: Позитивные новости о Nvidia, новый чип с ИИ «Rubin», бычий настрой рынка...
--- (Доска) АГЕНТ «Технический аналитик» работает... ---
--- КОНТРОЛЛЕР: Анализ доски... ---
Решение: вызвать «Автора отчета» (анализ завершен, подготовить отчет)...
...
Трассировка выполнения показывает гораздо более интеллектуальный процесс. Последовательный агент запустил бы одновременно технический и финансовый анализ, что привело бы к нерациональному расходованию ресурсов. Наша система Blackboard умнее:
Запуск контроллера: Он видит пустую плату и вызывает News Analyst.
Программа News Analyst Runs: находит позитивные новости о Nvidia и публикует их на форуме.
Контролер пересматривает ситуацию: он читает позитивные новости и правильно решает, что следующим шагом будет звонок в службу поддержки Technical Analyst, полностью пропуская финансовый вопрос.
Выполнение задачи специалистом: технический аналитик выполняет свою работу и публикует отчет.
Контроллер завершает работу: он видит, что весь необходимый анализ выполнен, и вызывает функцию Report Writerдля синтеза окончательного ответа перед завершением.
Этот динамичный, основанный на оперативности рабочий процесс — именно то, что определяет систему Blackboard . Для большей формальности наш магистр права, выступающий в роли судьи, оценивает каждый вклад, выставляя баллы за логическую согласованность и эффективность , гарантируя, что предлагаемые решения являются одновременно обоснованными и применимыми на практике.
class ProcessLogicEvaluation ( BaseModel ):
instruction_following_score: int = Field(description= "Оценка от 1 до 10 того, насколько хорошо агент следовал условным инструкциям." )
process_efficiency_score: int = Field(description= "Оценка от 1 до 10 того, избегал ли агент ненужной работы." )
justification: str = Field(description= "Краткое обоснование оценок." )
Последовательный агент получил бы здесь ужасные результаты. Однако наша система Blackboard справляется с тестом на отлично.
--- Оценка процесса работы системы Blackboard ---
{
'instruction_following_score': 7,
'process_efficiency_score': 8,
'justification': "Агент идеально следовал условным инструкциям пользователя. После того, как аналитик новостей сообщил о позитивном настроении, система правильно выбрала запуск технического аналитика и полностью пропустила финансового аналитика. Это демонстрирует как безупречное следование инструкциям, так и оптимальную эффективность процесса."
}
В сложных задачах, где дальнейший путь зависит от промежуточных результатов, гибкость…
Архитектура Blackboard может быть лучше, чем многоагентная система.