Используйте Foundry Toolbox с LangChain

Используйте пакет langchain-azure-ai, чтобы загружать инструменты и навыки из инструментария Foundry в ваши агенты LangChain и LangGraph. Foundry Toolbox — это управляемый мульти-MCP-сервер, который объединяет несколько настроенных инструментов за единой конечной точкой Model Context Protocol (MCP).

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

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

Установите необходимые пакеты:

pip install -U langchain-azure-ai langchain-mcp-adapters httpx azure-identity

Для интеграции с панелью инструментов требуется langchain-mcp-adapters и httpx. Чтобы загрузить навыки для агентов Deep, также установите deepagents.

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

Для панели элементов требуется конечная точка проекта и имя панели элементов. Задайте конечную точку в качестве переменной среды и передайте имя панели элементов конструктору.

Задайте конечную точку проекта:

import os

os.environ["FOUNDRY_PROJECT_ENDPOINT"] = (
    "https://<resource>.services.ai.azure.com/api/projects/<project>"
)

Интеграция считывает либо FOUNDRY_PROJECT_ENDPOINT, либо AZURE_AI_PROJECT_ENDPOINT для конечной точки проекта. Ни одна переменная среды не задаёт имя инструментария, поэтому в конструктор следует всегда передавать toolbox_name.

Импортируйте общие классы и инициализировать модель, используемую в этой статье:

from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage

model = init_chat_model("azure_ai:gpt-4.1")

Набор инструментов проходит аутентификацию через DefaultAzureCredential, который использует ваш сеанс az login. Вам не нужно создавать учетные данные самостоятельно.

Подключиться к набору инструментов

Используйте AzureAIProjectToolbox из пространства имен langchain_azure_ai.tools для подключения к набору инструментов. Интеграция обнаруживает подключение проекта при настройке переменной FOUNDRY_PROJECT_ENDPOINT среды. Microsoft Entra ID — это метод проверки подлинности по умолчанию.

from langchain_azure_ai.tools import AzureAIProjectToolbox

toolbox = AzureAIProjectToolbox(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    toolbox_name="my-toolbox",
)

При установке конечной точки в среде можно опустить project_endpoint. Вам всегда необходимо предоставить toolbox_name:

toolbox = AzureAIProjectToolbox(toolbox_name="my-toolbox")

Замечание

AzureAIProjectToolbox доступен в предварительной версии и вызывает ExperimentalWarning при создании. Его API подлежит изменению.

Справочник:AzureAIProjectToolbox

Загрузите инструменты из панели инструментов

Вызовите aget_tools(), чтобы открыть сеанс с набором инструментов и загрузить все инструменты, которые он предоставляет, в виде экземпляров LangChain BaseTool. Каждый вызов не сохраняет состояние: он открывает новый сеанс MCP, загружает инструменты и возвращает их.

async def main():
    toolbox = AzureAIProjectToolbox(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        toolbox_name="my-toolbox",
    )

    tools = await toolbox.aget_tools()

    agent = create_agent(model=model, tools=tools)

    result = await agent.ainvoke(
        {"messages": [HumanMessage("What can you do?")]}
    )
    print(result["messages"][-1].content)

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

AzureAIProjectToolbox также поддерживает протокол асинхронного диспетчера контекстов. Поведение идентично, так как каждый aget_tools() вызов управляет собственным сеансом:

async with AzureAIProjectToolbox(toolbox_name="my-toolbox") as toolbox:
    tools = await toolbox.aget_tools()

Справочник:create_agent

Определение средств, требующих утверждения

Некоторые средства панели инструментов настроены для утверждения перед их запуском. Вызовите get_tools_requiring_approval(), чтобы получить имена этих инструментов и добавить этап с участием человека перед их выполнением.

tools_needing_approval = await toolbox.get_tools_requiring_approval()

print("Tools that require approval before execution:")
for name in tools_needing_approval:
    print(f"- {name}")

Что делает этот фрагмент кода: Проверяет метаданные панели инструментов и возвращает имена инструментов, в конфигурации которых require_approval задано значение always. Используйте этот список для шлюза конфиденциальных операций за рабочим процессом утверждения.

Эта возможность не зависит от обработки согласия OAuth. Дополнительные сведения об утверждениях с участием человека см. в разделе Использование службы Foundry Agent Service с LangGraph.

Toolbox в Microsoft Foundry поддерживает рабочие процессы с выполнением от имени пользователя. При добавлении инструментов в набор инструментов можно настроить требования к авторизации.

Снимок экрана, показывающий, как настроить сервер MCP по схеме on-behalf-of.

Когда средство панели элементов подключается к службе, которая еще не авторизована, шлюз Foundry требует согласия OAuth. Вместо вызова исключения get_tools()/aget_tools() возвращает резервный инструмент, который отображает URL-адрес согласия, чтобы агент мог показать его пользователю.

Когда вы вызываете агента и модель вызывает резервный инструмент, ответ содержит сообщение примерно следующего вида:

OAuth consent is required before this toolbox can be used. Open the following
URL in a browser to authorize access, then restart the agent:

  https://consent.azure-apim.net/...

Откройте URL-адрес в браузере, чтобы авторизовать доступ, а затем перезапустите агент. После предоставления согласия панель инструментов обычно загружает свои инструменты.

Загрузить навыки с панели инструментов

Набор инструментов представляет навыки в виде ресурсов MCP с URI вида skill://{name}. Используется get_resources() для их загрузки в виде объектов LangChain Blob . Каждый Blob содержит имя ресурса в свойстве source, а его исходный URI — в metadata["uri"].

skill_blobs = toolbox.get_resources(scheme="skills")

for blob in skill_blobs:
    print(f"Skill: {blob.source}")
    print(blob.as_string())
Skill: jokes-teller/SKILL.md
{'content': '---\nname: jokes-teller\ndescription: A skill to tell jokes\n---\n\nUse...'}

Что делает этот фрагмент кода: Загружает каждый skill:// ресурс из панели элементов в виде Blob. Фильтр scheme="skills" ограничивает результаты ресурсами навыков. Совпадение не учитывает регистр и принимает форму единственного или множественного числа ("skill" или "skills").

Чтобы загрузить определенные ресурсы, передайте свои URI явным образом. Когда вы указываете uris, фильтр scheme игнорируется:

skill_blobs = toolbox.get_resources(uris="skill://my-skill/SKILL.md")

Используется aget_resources() для асинхронного эквивалента:

skill_blobs = await toolbox.aget_resources(scheme="skills")

Загрузите навыки для глубоких агентов

Если вы используете пакет deepagents, вызовите get_skills(), чтобы загрузить навыки Toolbox как готовое к использованию сопоставление файлов для create_deep_agent. Этот метод основан на get_resources() и устраняет рутинный шаблонный код, связанный с преобразованием каждого Blob в структуру файлов, которую ожидают deep agents.

Установите пакет:

pip install deepagents

В следующем примере инициализируется StateBackend (по умолчанию). Оставьте аргумент backend не заданным и передайте полученное сопоставление в качестве полезной нагрузки files в invoke:

from deepagents import create_deep_agent
from deepagents.backends import StateBackend

toolbox = AzureAIProjectToolbox(toolbox_name="my-toolbox")
skill_files = toolbox.get_skills()

agent = create_deep_agent(
    model="azure_ai:gpt-4.1",
    backend=StateBackend(),
    skills=["/skills/"],
)

agent.invoke({"messages": [HumanMessage("Use a skill")], "files": skill_files})

Что делает этот фрагмент кода: Загружает навыки набора инструментов в сопоставление виртуальных путей SKILL.md и помещает их в состояние агента через полезную нагрузку files. Затем агент может использовать навыки по базовому пути /skills/.

Чтобы инициализировать серверную часть с помощью автономного хранилища, например FilesystemBackend, передайте его как аргумент backend. Навыки записываются в серверную часть, и то же сопоставление также возвращается:

from deepagents.backends import FilesystemBackend

backend = FilesystemBackend(root_dir="./my-project")
toolbox = AzureAIProjectToolbox(toolbox_name="my-toolbox")
await toolbox.aget_skills(backend=backend)

agent = create_deep_agent(
    model="azure_ai:gpt-4.1",
    backend=backend,
    skills=["/skills/"],
)

По умолчанию файлы навыков помещаются в базовый /skills/ путь. Передайте другой base_path, чтобы изменить местоположение. Значение должно начинаться и заканчиваться косой чертой, и вы передаете то же значение аргументу skillscreate_deep_agent.

Следующий шаг