Используйте службу агента Foundry вместе с LangGraph

langchain-azure-ai Используйте пакет для подключения приложений LangGraph и LangChain к службе агента Foundry. В этой статье рассматриваются практические сценарии, от использования существующих агентов и создания мультиагентных графов до рабочих процессов с поддержкой инструментов, утверждений с участием человека и отслеживания.

Необходимые условия

  • Подписка Azure. Создайте его бесплатно.
  • Проект Foundry.
  • Развернутая модель чата (например, gpt-4.1) в проекте.
  • Python 3.10 или более поздней версии.
  • Azure CLI вошел в систему (az login), чтобы DefaultAzureCredential могла пройти проверку подлинности.

Настройка среды

Установите пакет langchain-azure-ai, чтобы использовать возможности Microsoft Foundry в LangGraph и LangChain.

pip install langchain-azure-ai[tools,opentelemetry] azure-identity

Совет

Установите дополнительные компоненты [tools], чтобы использовать такие средства, как аналитика документов или соединители Azure Logic Apps. Установите [opentelemetry], чтобы включить поддержку OpenTelemetry с семантическими соглашениями для решений Генеративного ИИ.

Задайте переменные среды, которые мы используем в этом руководстве:

export AZURE_AI_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export MODEL_DEPLOYMENT_NAME="gpt-4.1"

Использование агентов службы Foundry

Класс AgentServiceFactory — это отправная точка создания агентов в LangGraph, взаимодействующих с службой агента в Foundry. Фабрика создает узлы, совместимые с LangGraph, которые выполняются через службу агента и которые можно использовать для создания более сложных решений с помощью LangGraph.

Создайте фабрику агентов, подключив AgentServiceFactory класс к проекту Foundry. Все агенты, которых вы создаете или на которых ссылаетесь с помощью этой фабрики, управляются в проекте и отображаются на обновленном портале Foundry.

Примечание

Переход с классической версии Foundry: Агенты, созданные с langchain_azure_ai.agents.v1.AgentServiceFactory помощью, отображаются только на портале Foundry (классический).

import os

from langchain_core.messages import HumanMessage

from azure.identity import DefaultAzureCredential
from langchain_azure_ai.agents import AgentServiceFactory
from langchain_azure_ai.utils.agents import pretty_print

factory = AgentServiceFactory(
	project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
	credential=DefaultAzureCredential(),
)	

Использование существующего агента

Рекомендуется создавать и настраивать агентов в портале Foundry или в SDK Foundry, а затем ссылаться на них по имени с помощью get_agent_node для составления графов. Этот подход рекомендуется, так как он сохраняет конфигурацию агента централизованно в Foundry и позволяет вашему коду сосредоточиться на оркестрации. Вы также можете программно создавать агентов с помощью create_prompt_agent, когда необходимо полностью определить их в коде.

echo_node = factory.get_agent_node(
	name="my-echo-agent",
	version="latest",
)

Что делает этот фрагмент кода: Извлекает ссылку на существующий агент Foundry в качестве узла, совместимого с LangGraph. Агент должен уже существовать в проекте Foundry. Используйте version="latest" для всегда обращения к последней версии или указания номера определённой версии для стабильности.

Проверьте, может ли ваш агент выполнить следующее:

response = echo_node.invoke(
	{"messages": [HumanMessage(content="Hello, world!")]}
)
pretty_print(response)
================================ Human Message =================================

Hello, world!
================================== Ai Message ==================================
Name: my-echo-agent

Goodbye, world!

Беседы и состояние

Узлы, подключенные к службе агента, автоматически отслеживают ответы в беседах. Свойство azure_ai_agents_conversation_id добавляется в состояние, чтобы вы могли ссылаться на беседы или продолжать их.

print(
	"azure_ai_agents_conversation_id:",
	response["azure_ai_agents_conversation_id"],
)
azure_ai_agents_conversation_id: <conversation-id>

Создание графов с существующими агентами

Для создания сложных графов можно использовать узлы службы агентов так же, как и любой другой узел в LangGraph. В следующем примере создается граф условной маршрутизации, где локальный router_node проверяет сообщение пользователя и решает, следует ли делегировать агенту Foundry.

from typing import Literal
from langchain_core.messages import AIMessage
from langgraph.graph import StateGraph, MessagesState, START, END


class RouterState(MessagesState):
	jump_to: str | None


def router_node(state: RouterState):
	last_message = state["messages"][-1].content.lower()

	# Simple logic simulating a model decision
	if "negate" in last_message:
		return RouterState(
			messages=state["messages"], jump_to="delegate"
		)
	else:
		return RouterState(
			messages=[AIMessage(content="I can handle this!")],
			jump_to=None,
		)


def route_decision(state: RouterState) -> Literal["expert_node", END]:
	if state.get("jump_to", None) == "delegate":
		return "expert_node"
	return END


workflow = StateGraph(RouterState)

workflow.add_node("router_node", router_node)
workflow.add_node("expert_node", echo_node)
workflow.add_edge(START, "router_node")
workflow.add_conditional_edges("router_node", route_decision)
workflow.add_edge("expert_node", END)

app = workflow.compile()

Что делает этот фрагмент кода: Создает LangGraph StateGraph с двумя узлами. Проверяет router_node последнее сообщение — если оно содержит "отрицать", он делегирует агенту Foundry expert_node, полученному с помощью get_agent_node. В противном случае маршрутизатор обрабатывает запрос локально и заканчивает граф. В этом шаблоне показано, как объединить локальную логику с агентами Foundry.

График выглядит следующим образом:

Диаграмма графа агента с узлом, работающим в сервисе агента.

Вызов графа:

print("--- Test 1 (Direct) ---")
pretty_print(
	app.invoke({"messages": [HumanMessage(content="Hello, world!")]})
)

print("\n--- Test 2 (Delegated) ---")
pretty_print(
	app.invoke(
		{"messages": [HumanMessage(content="Negate that I'm a genius!")]}
	)
)
------------------------------- Test 1 (Direct) --------------------------------
================================ Human Message =================================

Hello, world!
================================== Ai Message ==================================

I can handle this!

------------------------------ Test 2 (Delegated) ------------------------------
================================ Human Message =================================

Negate that I'm a genius!
================================== Ai Message ==================================
Name: my-echo-agent

You're not a genius!

В тесте 1 маршрутизатор обрабатывает запрос локально. В тесте 2 маршрутизатор делегирует агенту компании Foundry, который отвечает противоположным утверждением пользователя.

Создание базового агента запроса

Если необходимо полностью определить агенты в коде, например во время создания прототипов или когда конфигурация агента должна жить вместе с приложением— используйте create_prompt_agent. Начните с минимального агента запроса в стиле ReAct, чтобы проверить интеграцию.

agent = factory.create_prompt_agent(
	name="my-echo-agent",
	model=os.environ["MODEL_DEPLOYMENT_NAME"],
	instructions=(
		"You are a helpful AI assistant that always replies with the "
		"opposite of what the user says."
	),
)

print(f"Agent created with ID: {factory.get_agents_id_from_graph(agent)}")
Agent created with ID: {'my-echo-agent:1'}

Вызов агента:

messages = [HumanMessage(content="I'm a genius and I love programming!")]
response = agent.invoke({"messages": messages})
pretty_print(response)
================================ Human Message =================================

I'm a genius and I love programming!
================================== Ai Message ==================================
Name: my-echo-agent

You are not a genius and you hate programming!

Что делает этот фрагмент кода: Создает агент на основе запроса в службе агента Foundry и возвращает LangGraph CompiledStateGraph , использующий его. Агент сразу же отображается на портале Foundry в разделе "Агенты". Вызов get_agents_id_from_graph извлекает назначенный Foundry идентификатор Agent, чтобы вы могли отслеживать или ссылаться на этого агента позже.

Вы можете визуализировать, как агент был создан и использован в графе LangGraph, распечатав его представление схемы. Узел foundryAgent выполняется в службе агента Foundry. Обратите внимание, как имя и версия агента отображаются на графе.

from IPython import display

display.Image(agent.get_graph().draw_mermaid_png())

factory.delete_agent(agent)

Схема графа агента для агента без инструментов.

Добавьте инструменты в вашего агента

Вы можете добавить инструменты в ваш агент для выполнения действий. Метод create_prompt_agent реализует цикл агента для вас.

Следует различать два типа инструментов:

  • Локальные инструменты: это инструменты, которые выполняются в одной среде с кодом агента. Они могут быть вызываемыми функциями или любой функцией, доступной для экосистемы LangChain/LangGraph.
  • Встроенные инструменты: это инструменты, которые могут выполняться исключительно в службе Foundry Agent; на стороне сервера. Серверные средства можно применять только к агентам Foundry.

Добавление локальных инструментов в ваш агент системы добавляет узел инструментов в ваш граф для их выполнения. Встроенные инструменты не добавляют узел инструмента и выполняются в процессе выполнения запроса.

Диаграмма графа агента, использующего инструменты.

В следующем разделе объясняется, как использовать оба:

Добавить локальные инструменты

Вы можете определить локальные Python функции и присоединить их в качестве инструментов. Этот шаблон полезен для детерминированных бизнес-логики и служебных операций.

def add(a: int, b: int) -> int:
	"""Add two integers."""
	return a + b


def multiply(a: int, b: int) -> int:
	"""Multiply two integers."""
	return a * b


def divide(a: int, b: int) -> float:
	"""Divide one integer by another."""
	return a / b

Передайте инструменты create_prompt_agent в функцию и вызовите агент с многошаговой арифметической проблемой.

math_agent = factory.create_prompt_agent(
	name="math-agent",
	model=os.environ["MODEL_DEPLOYMENT_NAME"],
	instructions=(
		"You are a helpful assistant tasked with performing arithmetic "
		"on a set of inputs."
	),
	tools=[add, multiply, divide],
)

messages = [
	HumanMessage(
		content="Add 3 and 4. Multiply the output by 2. Divide the output by 5."
	)
]
response = math_agent.invoke({"messages": messages})
pretty_print(response)
================================ Human Message =================================

Add 3 and 4. Multiply the output by 2. Divide the output by 5
================================== Ai Message ==================================
Tool Calls:
  add (call_JSmltOCbsTRkbNEBMAVSgVe1)
 Call ID: call_JSmltOCbsTRkbNEBMAVSgVe1
  Args:
    a: 3
    b: 4
================================= Tool Message =================================
Name: add

7
================================== Ai Message ==================================
Tool Calls:
  multiply (call_ae6M6XyhOIBOkPy3ETd8nDI9)
...
================================== Ai Message ==================================
Name: math-agent

Here's the step-by-step calculation:
1. Add 3 and 4 to get 7.
2. Multiply the result (7) by 2 to get 14.
3. Divide the result (14) by 5 to get 2.8.

The final result is 2.8.

Что делает этот фрагмент кода: Создает агент с тремя арифметическими средствами. Когда агент определяет, что необходим вызов инструмента, служба агента Foundry организует вызов инструмента локально и передает результат агенту, чтобы он продолжил рассуждение.

Используйте другие средства из экосистемы LangGraph/LangChain, например Azure Интеллектуальный анализ документов в рамках инструментов Foundry из того же потока агента. Хотя эти средства подключены к ресурсу Foundry, они не являются эксклюзивными для службы агентов и, следовательно, действуют как локальное средство.

from langchain_azure_ai.tools import AzureAIDocumentIntelligenceTool

document_parser_agent = factory.create_prompt_agent(
	name="document-agent",
	model=os.environ["MODEL_DEPLOYMENT_NAME"],
	instructions="You are a helpful assistant tasked with analyzing documents.",
	tools=[AzureAIDocumentIntelligenceTool()],
)

Совет

AzureAIDocumentIntelligenceTool может использовать проект Foundry для подключения к службе и также поддерживает Microsoft Entra для проверки подлинности. По умолчанию средство использует AZURE_AI_PROJECT_ENDPOINT с DefaultAzureCredential, поэтому дополнительная настройка не требуется. При необходимости можно изменить это, чтобы использовать определенную конечную точку и ключ.

Попросите агента проанализировать счет по URL-адресу:

messages = [
	HumanMessage(
		content=(
			"What's the total amount in the invoice at "
			"https://raw.githubusercontent.com/Azure/azure-sdk-for-python/main/"
			"sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/"
			"forms/Form_1.jpg"
		)
	)
]
response = document_parser_agent.invoke({"messages": messages})
pretty_print(response)
================================ Human Message =================================

What's the total amount in ...
================================== Ai Message ==================================
Tool Calls:
  azure_ai_document_intelligence (call_32V6bqeCcJhhsOXDrYFXggnc)
 Call ID: call_32V6bqeCcJhhsOXDrYFXggnc
  Args:
    source_type: url
    source: https://raw.githubusercontent.com/Azure/ ...
================================= Tool Message =================================
Name: azure_ai_document_intelligence

Content: Purchase Order Hero ...
================================== Ai Message ==================================
Name: document-agent

The total amount in the invoice is **$144.00**.

Что делает этот фрагмент кода: Запрашивает агент извлечь данные из примера образа счета. Агент вызывает AzureAIDocumentIntelligenceTool для анализа документа и возвращает результат. Ожидаемый результат: "Общая сумма в счете составляет $ 144,00".

Добавление встроенных средств

Встроенные средства в Службе агентов Foundry выполняются на стороне сервера, а не в узле инструментов, как местные инструменты. Все инструменты в пространстве langchain_azure_ai.agents.prebuilt.tools.* имен — встроенные и работают только с create_prompt_agent.

Пример. Использование средства интерпретатора кода

Создайте агент интерпретатора кода для анализа данных и вызовите его с помощью вымышленного data.csv файла данных.

Перед выполнением этого примера создайте локальный data.csv файл в текущем рабочем каталоге.

import base64
from langchain_azure_ai.agents.prebuilt.tools import CodeInterpreterTool

code_interpreter_agent = factory.create_prompt_agent(
	name="code-interpreter-agent",
	model=os.environ["MODEL_DEPLOYMENT_NAME"],
	instructions=(
		"You are a data analyst agent. Analyze CSV data and create "
		"visualizations when helpful."
	),
	tools=[CodeInterpreterTool()],
)

with open("data.csv", "rb") as file_handle:
	csv_data = base64.b64encode(file_handle.read()).decode()

response = code_interpreter_agent.invoke(
	{
		"messages": [
			HumanMessage(
				content=[
					{
						"type": "file",
						"mime_type": "text/csv",
						"base64": csv_data,
					},
					{
						"type": "text",
						"text": (
							"Create a pie chart showing sales by region and "
							"return it as a PNG image."
						),
					},
				]
			)
		]
	}
)
pretty_print(response)
================================ Human Message =================================

[
	{'type': 'file', 'mime_type': 'text/csv', 'base64': '77u/bW9udG...xTb3V0aAo='}, 
	{'type': 'text', 'text': 'create a pie chart with the data showing sales by region and show it to me as a png image.'}
]
================================== Ai Message ==================================
Name: code-interpreter-agent

[
	{'type': 'text', 'text': 'Here is the pie chart showing sales by region as a PNG image:\n\n[Download the Pie Chart](sandbox:/mnt/data/sales_by_region_pie.png)'}, 
	{'type': 'image', 'mime_type': 'image/png', 'base64': 'iVBORw0...ErkJggg=='}
]

Изображение, созданное с помощью CodeInterpreterTool.

Пример: использование средства создания образов

В следующем примере показано, как использовать ImageGenTool для создания изображений:

from langchain_azure_ai.agents.prebuilt.tools import ImageGenTool

image_agent = factory.create_prompt_agent(
	name="image-generator-agent",
	model=os.environ["MODEL_DEPLOYMENT_NAME"],
	instructions=(
		"You are an image generation assistant. You receive a text prompt and "
		"must generate an image by using the configured tool."
	),
	tools=[ImageGenTool(model_deployment="gpt-image-1.5", quality="medium")],
)

response = image_agent.invoke(
	{"messages": [HumanMessage("Generate an image of a sunset over mountains.")]}
)
pretty_print(response)
================================ Human Message =================================

Generate an image of a sunset over the mountains.
================================== Ai Message ==================================
Name: image-generator-agent

Изображение, созданное с помощью ImageGenTool.

Использование других встроенных средств

Любой инструмент службы агента Foundry можно использовать с create_prompt_agent. Используйте AgentServiceBaseTool для упаковки средств из пакета SDK Azure AI Projects и подключите их к агенту запроса.

Перед выполнением этого примера убедитесь, что идентификатор хранилища векторов существует в проекте.

В следующем примере показано, как использовать :FileSearchTool

from azure.ai.projects.models import FileSearchTool
from langchain_azure_ai.agents.prebuilt.tools import AgentServiceBaseTool

file_search_agent = factory.create_prompt_agent(
	name="file-search-agent",
	model=os.environ["MODEL_DEPLOYMENT_NAME"],
	instructions=(
		"You are a helpful agent with access to a file search tool over a "
		"vector store."
	),
	tools=[
		AgentServiceBaseTool(
			tool=FileSearchTool(vector_store_ids=["vector-store-1"]),
		)
	],
)

Человек в процессе

Некоторые инструменты в Foundry имеют встроенные рабочие процессы утверждения, например MCPTool. Вы можете требовать утверждение перед выполнением вызовов средств для конкретного средства на сервере.

Метод create_prompt_agent реализует тот же шаблон, что и LangGraph, введя узел утверждения в графе:

Схема графа агента с реализованными процессами утверждения.

В следующем примере показано, как использовать MCPTool с одобрением.

from langchain_azure_ai.agents.prebuilt.tools import MCPTool
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import Command

mcp_agent = factory.create_prompt_agent(
	name="mcp-github-specs-agent",
	model=os.environ["MODEL_DEPLOYMENT_NAME"],
	instructions=(
		"You are a helpful agent that can use MCP tools to assist users."
	),
	tools=[
		MCPTool(
			server_label="api-specs",
			server_url="https://gitmcp.io/Azure/azure-rest-api-specs",
			require_approval="always",
		)
	],
	checkpointer=MemorySaver(),
)

config = {"configurable": {"thread_id": "mcp-session-1"}}

response = mcp_agent.invoke(
	input={"messages": [HumanMessage("What APIs are available for Azure Cosmos DB?")]},
	config=config,
)
pretty_print(response)
================================ Human Message =================================

What APIs are available for Azure Cosmos DB?
================================== Ai Message ==================================
Tool Calls:
  mcp_approval_request (mcpr_74e314080483acce0069a11d2d9f008190a971212ac61d76d8)
 Call ID: mcpr_74e314080483acce0069a11d2d9f008190a971212ac61d76d8
  Args:
    server_label: api-specs
    name: search_azure_rest_api_docs
    arguments: {"query":"Cosmos DB APIs"}

================================== Interrupt ==================================
Interrupt ID: c3cb23363f91d097298fb3c6f8fbf70a
Interrupt Value:
  Tool Call ID: mcpr_74e314080483acce0069a11d2d9f008190a971212ac61d76d8
  Server Label: api-specs
  Tool Name: search_azure_rest_api_docs
  Arguments: {"query":"Cosmos DB APIs"}

Отправьте утверждение в LangGraph, используя Command.

response = mcp_agent.invoke(Command(resume={"approve": True}), config)

pretty_print(response)
================================ Human Message =================================

What APIs are available for Azure Cosmos DB?
================================== Ai Message ==================================
Tool Calls:
  mcp_approval_request (mcpr_74e314080483acce0069a11d2d9f008190a971212ac61d76d8)
 Call ID: mcpr_74e314080483acce0069a11d2d9f008190a971212ac61d76d8
  Args:
    server_label: api-specs
    name: search_azure_rest_api_docs
    arguments: {"query":"Cosmos DB APIs"}
================================= Tool Message =================================

{"approve": true}
================================== Ai Message ==================================
Name: mcp-github-specs-agent

Azure Cosmos DB supports multiple APIs, ...

Наблюдаемость

При создании решений с помощью службы агента Foundry и LangGraph некоторые части выполняются в службе агента, а другие выполняются там, где выполняется код.

Этот класс AzureAIOpenTelemetryTracer позволяет отслеживать сквозные решения, построенные с использованием LangGraph, используя стандарт OpenTelemetry, который поддерживается Сервисом Агентов.

Для трассировки кода используйте следующее:

from langchain_azure_ai.callbacks.tracers import AzureAIOpenTelemetryTracer

tracer = AzureAIOpenTelemetryTracer(
    agent_id="mcp-github-specs-agent-langgraph"
)

mcp_agent = mcp_agent.with_config({ "callbacks": [tracer] })

Что делает этот фрагмент кода: Создает экземпляр AzureAIOpenTelemetryTracer для отправки трейсов в приложение Azure Insights с помощью стандарта OpenTelemetry. Он задает параметр agent_id для идентификации трассировок, задав свойство gen_ai.agent.id в диапазонах типа agent_invoke. AzureAIOpenTelemetryTracer требуется строка подключения для приложение Azure Insights. В этом случае это не отображается, так как вы задаете переменную среды AZURE_AI_PROJECT_ENDPOINT, которую класс может использовать для обнаружения строка подключения в приложение Azure Insights, связанной с проектом. Вы можете передать любую необходимую строку подключения.

Чтобы просмотреть трассировки, важно понимать, что здесь есть два агента :

  1. Агент Foundry, являющийся серверной частью одного из узлов графа.
  2. Весь граф LangGraph, состоящий из множества узлов.

Трассировки агента Foundry можно просмотреть с помощью портала Foundry но для просмотра трассировки агента LangGraph во время разработки необходимо использовать Azure Monitor на портале Azure.

Совет

Приложения LangChain и LangGraph можно зарегистрировать в Системе управления Foundry для управления. Затем можно использовать портал Foundry для просмотра трассировок. Просмотр трассировок в плоскости управления Foundry.

Чтобы просмотреть трассировки с помощью Azure Monitor, выполните следующие действия.

  1. Перейдите на портал Azure.

  2. Перейдите к настроенной приложение Azure Insights.

  3. На панели навигации слева выберите Исследовать>Агенты (Предварительная версия).

  4. Отображается панель мониторинга, показывающая выполнение агентов, моделей и инструментов. Используйте это представление, чтобы понять общую картину агентов.

  5. Выберите [Просмотреть трассировки с запусками агента]. На боковой панели отображаются все трассировки, созданные запуском агента.

    Скриншот, показывающий раздел

  6. Выберите одну из трассировок. Вам следует посмотреть подробности.

    Снимок экрана, показывающий сведения о трассировке выбранного запуска.

  7. Обратите внимание, что два агента участвуют в беседе: агент foundryAgent и один с именем mcp-github-specs-agent-langgraph.

Очистка агентов

Удалите агентов, созданных в примерах, чтобы избежать оставления неиспользуемых ресурсов.

Удаляйте только тех агентов, которых вы создали в вашем сеансе.

factory.delete_agent(math_agent)	
factory.delete_agent(document_parser_agent)
factory.delete_agent(image_agent)
factory.delete_agent(code_interpreter_agent)
factory.delete_agent(mcp_agent)
factory.delete_agent(file_search_agent)

Важно

После удаления объект LangGraph больше не может использоваться.

Устранение неполадок

Используйте этот контрольный список для диагностики распространенных проблем при использовании langchain-azure-ai службы агента.

Включение ведения журнала диагностики

Сначала включите журналы отладки, чтобы проверить проверку подлинности, поток запросов и сведения о выполнении средства.

import logging

logging.getLogger("langchain_azure_ai").setLevel(logging.DEBUG)

Если вам нужны дополнительные сведения, увеличьте ведение журнала, чтобы включить другие библиотеки:

import logging

logging.basicConfig(level=logging.DEBUG)

Проверка конфигурации на ранней стадии

  • Убедитесь, что AZURE_AI_PROJECT_ENDPOINT указывает на правильную конечную точку проекта, и вы используете проект Foundry с новым интерфейсом.
  • Подтвердите, что MODEL_DEPLOYMENT_NAME соответствует существующей развернутой модели.
  • Проверьте контекст аутентификации с помощью az account show.
  • Сначала используйте минимальный create_prompt_agent пример.

Проверка доступа к ресурсам и разрешениям

  • Убедитесь, что у вашей учетной записи есть доступ к проекту Foundry и развертыванию модели.
  • Убедитесь, что зависимости нижестоящих уровней (например, хранилища векторов или ресурсы инструментов) существуют и доступны.
  • Если для средства требуется определенный тип ресурса, убедитесь, что ресурс предоставлен в правильной подписке и правильном регионе.