Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Используйте .NET пакеты размещения A2A для предоставления агента Agent Framework через ASP.NET Core. Полный справочник по серверу с несколькими языками см. в разделе агентов узлов с помощью A2A .
Используйте пакет Go provider/a2aprovider с официальными обработчиками сервера A2A для Go. Полный пример сервера см. в разделе "Агенты узла" с помощью A2A .
Agent Framework предоставляет два пакета Python для размещения агентов и рабочих процессов через официальный пакет SDK A2A:
| Package | Модель интеграции | Используйте его, когда |
|---|---|---|
agent-framework-a2a |
Компонент с жёстко заданной архитектурой A2AExecutor, который преобразует запросы, запускает агента и публикует события и артефакты задач A2A. |
Вам требуется стандартное поведение взаимодействия Agent Framework с A2A, и нужно лишь собрать сервер A2A SDK. |
agent-framework-hosting-a2a |
Инкрементальные компоненты для исполнителя, принадлежащего приложению. Начните с базового конвертера агента или конвертера рабочего процесса, а при необходимости используйте AgentA2AAdapter или WorkflowA2AAdapter, которые основаны на этих конвертерах и добавляют генерацию нативных карточек и проверку режима. |
Приложение должно обеспечивать сопоставление сессий, переходы между задачами, доставку событий, определение границ артефактов, преобразование вывода или работу в качестве многопротокольного хоста. |
Оба пакета используют собственные типы пакетов SDK A2A и серверные компоненты. Приложение предоставляет обработчик запросов, хранилище задач, маршруты или построитель приложений SDK, проверку подлинности и развертывание. С помощью agent-framework-hosting-a2aприложения можно создать карточку агента напрямую или разрешить адаптеру создать его.
Использование исполнителя A2A с мнением
Установите agent-framework-a2a, если встроенный адаптер сервера подходит для вашего жизненного цикла:
pip install --pre agent-framework-a2a starlette uvicorn
A2AExecutor реализует пакет AgentExecutor из SDK A2A. Он считывает пользовательский ввод из контекста запроса A2A, создает сеанс Agent Framework на основе идентификатора контекста A2A, запускает агент в потоковом или непотоковом режиме, преобразует поддерживаемые выходные данные и публикует события состояния задачи и артефактов через TaskUpdater SDK.
Соберите его с помощью SDK A2A DefaultRequestHandler, хранилища задач, карточки агента и приложения Starlette или другой поддерживаемой серверной интеграции. Настройте потоковую передачу с помощью A2AExecutor(agent, stream=True), передайте параметры запуска стабильного агента через run_kwargs или создайте подкласс A2AExecutor и переопределите handle_events, если требуется другое сопоставление выходных данных.
A2AExecutor ограничен эндпоинтом A2A и напрямую управляет своим A2A-выполнением и сопоставлением сеансов. Используйте пакеты размещения, если один и тот же агент должен быть доступен через несколько протоколов в одном приложении.
Полную настройку сервера см. в разделе Публикация агента Agent Framework через A2A.
Используйте адаптер в исполнителе, принадлежащем приложению
Установите пакет хостинга, если приложение использует собственный исполнитель A2A, но вы хотите, чтобы Agent Framework создавал публичную карточку и проверял конвертации:
pip install --pre agent-framework-hosting-a2a starlette uvicorn
AgentA2AAdapter поддерживает агент или AgentState. Его асинхронный метод get_card определяет публичное имя и описание, по умолчанию использует консервативные текстовые режимы и может определять нативные навыки A2A из экземпляров Agent Framework SkillsProvider. Возможности сервера и поддерживаемые интерфейсы остаются явными, так как они описывают конечную точку приложения, а не метод агента run .
Адаптер предоставляет a2a_to_run и a2a_from_run методы, которые проверяют значения в настроенных режимах карточки по умолчанию. Приложение по-прежнему владеет исполнителем A2A, жизненным циклом задач, очередью событий, границами артефактов, политикой сеанса, проверкой подлинности, маршрутами и развертыванием.
Этот исполнитель использует один адаптер для входящего преобразования, состояния агента и исходящего преобразования:
class AppAgentExecutor(AgentExecutor):
"""Native A2A SDK executor composed with Agent Framework conversion helpers."""
def __init__(self, adapter: AgentA2AAdapter[Any]) -> None:
self.adapter = adapter
async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
if context.context_id is None:
raise ValueError("A2A context id is required")
updater = TaskUpdater(event_queue, context.task_id or "", context.context_id)
await updater.cancel()
async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
if context.message is None or context.context_id is None:
raise ValueError("A2A message and context id are required")
task = context.current_task
if task is None:
task = new_task_from_user_message(context.message)
await event_queue.enqueue_event(task)
updater = TaskUpdater(event_queue, task.id, context.context_id)
await updater.submit()
try:
await updater.start_work()
run = self.adapter.a2a_to_run(context.message, stream=True)
agent = await self.adapter.state.get_target()
# Demo-only key: the outer server must authenticate and authorize these protocol IDs for multi-user use.
session_id = f"a2a:{context.tenant}:{context.context_id}"
session = await self.adapter.state.get_or_create_session(session_id)
if not run["stream"]:
raise RuntimeError("This executor requires streaming run arguments.")
stream = agent.run( # pyright: ignore[reportCallIssue]
run["messages"],
session=session,
options=run["options"],
stream=run["stream"],
)
default_artifact_id = uuid.uuid4().hex
streamed_artifact_ids: set[str] = set()
async for update in stream:
parts = self.adapter.a2a_from_run(update)
if parts:
artifact_id = update.message_id or default_artifact_id
await updater.add_artifact(
parts=parts,
artifact_id=artifact_id,
append=True if artifact_id in streamed_artifact_ids else None,
)
streamed_artifact_ids.add(artifact_id)
final_response = await stream.get_final_response()
if not streamed_artifact_ids:
parts = self.adapter.a2a_from_run(final_response)
if parts:
await updater.update_status(
state=TaskState.TASK_STATE_WORKING,
message=updater.new_agent_message(parts),
)
await self.adapter.state.set_session(session_id, session)
await updater.complete()
except asyncio.CancelledError:
await updater.update_status(state=TaskState.TASK_STATE_CANCELED)
except Exception:
logger.exception("A2A agent execution failed.")
await updater.update_status(
state=TaskState.TASK_STATE_FAILED,
message=updater.new_agent_message([Part(text="Agent execution failed.")]),
)
Программа установки сервера создает адаптер, создает собственный AgentCardобъект и создает исполнителя, принадлежащий приложению, с обработчиком запроса пакета SDK A2A:
if __name__ == "__main__":
flight_skill = InlineSkill(
frontmatter=SkillFrontmatter(
name="flight-booking",
description="Search and book flights across Europe.",
),
instructions="Help users search and book flights across Europe.",
)
hotel_skill = InlineSkill(
frontmatter=SkillFrontmatter(
name="hotel-booking",
description="Search and book hotels across Europe.",
),
instructions="Help users search and book hotels across Europe.",
)
agent = Agent(
client=OpenAIChatClient(),
name="Europe Travel Agent",
description="Helps users search and book flights and hotels across Europe.",
instructions="You are a helpful Europe Travel Agent.",
context_providers=[SkillsProvider([flight_skill, hotel_skill])],
)
state = AgentState(agent)
adapter = AgentA2AAdapter(
state,
version="1.0.0",
capabilities=AgentCapabilities(streaming=True),
supported_interfaces=[AgentInterface(url="http://localhost:9999/", protocol_binding="JSONRPC")],
)
public_agent_card = asyncio.run(adapter.get_card())
request_handler = DefaultRequestHandler(
agent_executor=AppAgentExecutor(adapter),
task_store=InMemoryTaskStore(),
agent_card=public_agent_card,
)
Создайте принадлежащий приложению A2A-экзекьютор
Используйте автономные вспомогательные средства размещения, если приложению также требуется прямой контроль над созданием карт:
pip install --pre agent-framework-hosting-a2a starlette uvicorn
Вспомогательные функции не зависят от фреймворка:
-
a2a_to_runпреобразует A2AMessageв аргументы запуска Agent Framework. -
a2a_from_runпреобразует ответы Agent Framework и обновления в потоковом режиме в значения A2APart.
Исполнитель выбирает ключи сеанса и владеет переходами задач, очередями событий, идентификаторами артефактов, границами сообщений и исходящей доставкой.
a2a_from_run возвращает плоский список частей, чтобы приложение могло сгруппировать эти части в сообщения A2A или артефакты и применять метаданные на уровне сообщения.
Конфигурация хостинга также поддерживает многопротокольные приложения. Использовать один и тот же целевой агент и одну и ту же инфраструктуру AgentState в маршрутах A2A, OpenAI Responses, Telegram и MCP, при этом каждая конечная точка сохраняет собственную политику преобразования, авторизации и ключей сеанса. Это позволяет клиентам обращаться к одному агенту по разным протоколам одновременно, не создавая отдельное развертывание агента для каждой конечной точки.
Скомпонуйте вспомогательные компоненты в нативном исполнителе A2A SDK. Этот пример создает и обновляет задачи A2A, преобразует входящее сообщение в запуск Agent Framework, сохраняет обновленный AgentState сеанс после завершения потока и публикует возвращаемые части в виде артефактов.
class AppAgentExecutor(AgentExecutor, Generic[AgentT]):
"""Native A2A SDK executor composed with Agent Framework conversion helpers."""
def __init__(self, state: AgentState[AgentT]) -> None:
self.state = state
async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
if context.context_id is None:
raise ValueError("A2A context id is required")
updater = TaskUpdater(event_queue, context.task_id or "", context.context_id)
await updater.cancel()
async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
if context.message is None or context.context_id is None:
raise ValueError("A2A message and context id are required")
task = context.current_task
if task is None:
task = new_task_from_user_message(context.message)
await event_queue.enqueue_event(task)
updater = TaskUpdater(event_queue, task.id, context.context_id)
await updater.submit()
try:
await updater.start_work()
run = a2a_to_run(context.message, stream=True)
agent = await self.state.get_target()
# Demo-only key: the outer server must authenticate and authorize these protocol IDs for multi-user use.
session_id = f"a2a:{context.tenant}:{context.context_id}"
session = await self.state.get_or_create_session(session_id)
if not run["stream"]:
raise RuntimeError("This executor requires streaming run arguments.")
stream = agent.run( # pyright: ignore[reportCallIssue]
run["messages"],
session=session,
options=run["options"],
stream=run["stream"],
)
default_artifact_id = uuid.uuid4().hex
streamed_artifact_ids: set[str] = set()
async for update in stream:
parts = a2a_from_run(update)
if parts:
artifact_id = update.message_id or default_artifact_id
await updater.add_artifact(
parts=parts,
artifact_id=artifact_id,
append=True if artifact_id in streamed_artifact_ids else None,
)
streamed_artifact_ids.add(artifact_id)
final_response = await stream.get_final_response()
if not streamed_artifact_ids:
parts = a2a_from_run(final_response)
if parts:
await updater.update_status(
state=TaskState.TASK_STATE_WORKING,
message=updater.new_agent_message(parts),
)
await self.state.set_session(session_id, session)
await updater.complete()
except CancelledError:
await updater.update_status(state=TaskState.TASK_STATE_CANCELED)
except Exception:
logger.exception("A2A agent execution failed.")
await updater.update_status(
state=TaskState.TASK_STATE_FAILED,
message=updater.new_agent_message([Part(text="Agent execution failed.")]),
)
В примере используются Starlette и Uvicorn, но вспомогательные функции не привязаны ни к одному из них. Используйте платформу приложений или построитель приложений пакета SDK A2A для обслуживания карточки агента A2A и маршрутов JSON-RPC:
# Create the Agent Framework agent for the chosen type
agent_factory = AGENT_FACTORIES[args.agent_type]
agent = agent_factory(client)
state = AgentState(agent)
# Build the A2A server components
url = f"http://{args.host}:{args.port}/"
agent_card = AGENT_CARD_FACTORIES[args.agent_type](url)
executor = AppAgentExecutor(state)
task_store = InMemoryTaskStore()
request_handler = DefaultRequestHandler(
agent_executor=executor,
task_store=task_store,
agent_card=agent_card,
)
app = Starlette(
routes=[
*create_agent_card_routes(agent_card),
*create_jsonrpc_routes(request_handler, "/"),
]
)
Размещение рабочего процесса с адаптером
WorkflowA2AAdapter предоставляет одинаковые границы для создания карточек и преобразования в рамках рабочего процесса или WorkflowState. Он содержит консервативные режимы ввода и вывода из объявленных типов рабочего процесса или вы можете предоставить явные режимы для представления конкретного приложения.
Автономные вспомогательные функции a2a_to_workflow_run и a2a_from_workflow_run обеспечивают типизированное преобразование входных и выходных данных рабочего процесса. Адаптер представляет их в виде асинхронных a2a_to_run и синхронных a2a_from_run методов, которые проверяют соответствие фактически применяемым режимам карты. Преобразование входных данных принимает одну часть A2A типа text, raw или data для единственного входного типа start-executor в рабочем процессе, а преобразование выходных данных сопоставляет выходные данные завершённого публичного рабочего процесса с собственными частями A2A. Вызывайте get_card перед преобразованием проверенных выходных данных, когда адаптеру необходимо определить режимы вывода.
Приложение по-прежнему отвечает за собственный нативный исполнитель A2A, а также за потоковую передачу сведений о ходе выполнения, статусе задачи, артефактах, контрольных точках и продолжение с участием человека. Ожидающие запросы, требующие участия пользователя, не преобразуются автоматически, поэтому хост должен реализовать собственную политику продолжения.
Безопасные сеансы и состояние задачи
A2AExecutor использует идентификатор контекста A2A в качестве идентификатора сеанса Agent Framework. Примеры на основе адаптера и вспомогательных компонентов объединяют идентификатор арендатора A2A и идентификатор контекста, чтобы продемонстрировать сопоставление, выбранное приложением. В каждом случае промышленный хост должен аутентифицировать вызывающую сторону до того, как запрос попадёт в обработчик запросов A2A, определить тенанта и субъекта на основе этого доверенного удостоверения, а также авторизовать все идентификаторы задач, контекста, продолжения и отмены.
Important
Хранилище задач по умолчанию и хранилища push-конфигураций в SDK A2A находятся в памяти и используют имя пользователя для определения области владения. Для службы с несколькими клиентами используйте объект, производный от того же доверенного клиента и субъекта, и используйте owner_resolver устойчивые хранилища задач и сеансов, когда реплики могут перезапускать или масштабироваться.
Полноценные примеры сервера на основе вспомогательных компонентов и примеры с несколькими агентами см. в примерах хостинга A2A. Сведения о клиентах И протоколах A2A см. в службе агента A2A.
Дальнейшие действия
Вернитесь глубже: