Hyperlight CodeAct

Hyperlight — это задокументированная серверная часть для CodeAct в Agent Framework. Он предоставляет execute_code средство, поддерживаемое изолированной средой выполнения песочницы, и может вызывать средства call_tool(...) узла, принадлежащие поставщику.

Общие сведения о уровне шаблона см. в разделе CodeAct.

Почему Hyperlight CodeAct

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

Hyperlight поддерживаемый CodeAct оптимизирует этот цикл. Модель записывает одну короткую программу на Python, песочница выполняет её один раз, и инструменты, принадлежащие поставщику, доступны из песочницы с помощью call_tool(...). В репрезентативных нагрузках с преобладанием инструментов этот сдвиг может сократить задержку примерно вдвое и использование токенов более чем на 60%, сохраняя при этом изоляцию выполнения и возможность аудита.

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

dotnet add package Microsoft.Agents.AI.Hyperlight --prerelease

Microsoft.Agents.AI.Hyperlight поставляется отдельно от базовых абстракций, поэтому изолированная среда выполнения требуется только при необходимости.

Important

Пакет .NET находится в предварительной версии. Он зависит от Hyperlight.HyperlightSandbox.Api пакета NuGet из hyperlight-dev/hyperlight-sandbox; пока эта зависимость не будет опубликована на nuget.org, проекту не удастся выполнить восстановление зависимостей. Отслеживайте доступность исходного репозитория песочницы.

Note

Hyperlight требует аппаратной виртуализации на узле: KVM в Linux или на платформе гипервизора Windows (WHP) на Windows. Серверная часть Wasm дополнительно требует гостевого модуля Hyperlight Python — задайте для HYPERLIGHT_PYTHON_GUEST_PATH абсолютный путь перед выполнением.

Используйте HyperlightCodeActProvider

HyperlightCodeActProvider — это рекомендуемая точка входа, когда требуется автоматически добавить CodeAct для каждого запуска. Это AIContextProvider, который добавляет инструкции CodeAct, действующие в рамках запуска, а также инструмент execute_code, не включая инструменты провайдера в набор инструментов, напрямую доступных агенту. Провайдер применяет механизм снимка/восстановления для каждого запуска, чтобы гостевая система при каждом вызове запускалась из известного чистого состояния.

Используйте фабрику HyperlightCodeActProviderOptions.CreateForWasm(modulePath), чтобы выбрать гостевой компонент Python на базе Wasm, используемый в примерах; для бэкенда JavaScript также доступен CreateForJavaScript().

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hyperlight;
using OpenAI.Chat;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-5.4-mini";
var guestPath = Environment.GetEnvironmentVariable("HYPERLIGHT_PYTHON_GUEST_PATH")
    ?? throw new InvalidOperationException("HYPERLIGHT_PYTHON_GUEST_PATH is not set.");

using var codeAct = new HyperlightCodeActProvider(
    HyperlightCodeActProviderOptions.CreateForWasm(guestPath));

AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetChatClient(deploymentName)
    .AsAIAgent(new ChatClientAgentOptions()
    {
        ChatOptions = new()
        {
            Instructions = "You are a helpful assistant. When the user asks something quantitative, "
                + "write Python and call `execute_code` instead of guessing.",
        },
        AIContextProviders = [codeAct],
    });

Console.WriteLine(await agent.RunAsync("What is the 20th Fibonacci number?"));

Note

К данному агенту может быть присоединен только один HyperlightCodeActProvider . Поставщик использует фиксированный ключ состояния, поэтому проверка уникальности ключа состояния в ChatClientAgent отклоняет повторные регистрации. HyperlightCodeActProvider реализует IDisposable; используйте объявление using, чтобы базовая песочница освобождалась, когда агент больше не нужен.

Инструменты, монтирования файлов и записи в списке разрешённых исходящих подключений можно заранее задать через HyperlightCodeActProviderOptions (Tools, FileMounts, AllowedDomains, HostInputDirectory) или управлять ими во время выполнения с помощью методов доступа AddTools(...), предоставляемых поставщиком: RemoveTools(...), ClearTools(), AddFileMounts(...), AddAllowedDomains(...) и соответствующих AddTools(...) методов доступа.

Как работают утверждения и инструменты хоста

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

Основное различие между регистрацией средства HyperlightCodeActProvider и его регистрацией непосредственно на агенте заключается в том, как вызывается средство, а не там, где в конечном счете выполняется функция:

  • Средства, зарегистрированные на HyperlightCodeActProviderOptions.Tools, скрыты от модели в качестве прямых средств. Модель достигает их путем написания кода, вызывающего call_tool("name", ...) внутри execute_code.
  • Инструменты, зарегистрированные непосредственно в агенте (например, через AsAIAgent(tools: [...])), предоставляются модели как полноправные инструменты, и каждый прямой вызов учитывает собственные метаданные согласования этого инструмента.

call_tool(...) — это мост обратно к обратным вызовам хоста; это не реимплементация инструмента в песочнице. Это означает, что средства, принадлежащие поставщику, по-прежнему выполняются в процессе узла, с любой файловой системой, сетью и учетными данными, к которым сам процесс узла может получить доступ.

Перечисление CodeActApprovalMode задаёт, каким образом утверждается сам инструмент execute_code:

  • CodeActApprovalMode.NeverRequire (по умолчанию): подтверждение наследуется от зарегистрированных инструментов. Если какой-либо инструмент в реестре заключён в тег ApprovalRequiredAIFunction, для execute_code также требуется одобрение; в противном случае одобрение не требуется.
  • CodeActApprovalMode.AlwaysRequire: execute_code всегда требуется утверждение пользователя перед вызовом.

Как правило:

  • Поместите дешевые, детерминированные, безопасные для цепочки инструменты на поставщика, так чтобы модель могла создавать множество вызовов внутри одного execute_code шага.
  • Оберните операции с побочными эффектами или чувствительные операции в ApprovalRequiredAIFunction (и подумайте, не лучше ли оставить их как прямые инструменты агента), чтобы каждый вызов оставался отдельно видимым и требовал отдельного одобрения.

В следующем примере регистрируются два безопасных инструмента (fetch_docs, query_data), а также чувствительный инструмент send_email, обёрнутый в ApprovalRequiredAIFunction. Поскольку по крайней мере один зарегистрированный инструмент требует утверждения, режим по умолчанию NeverRequire приводит к тому, что сам execute_code требует утверждения при каждом вызове.

AIFunction fetchDocs = AIFunctionFactory.Create(
    (string topic) => $"Docs for {topic}: (...)",
    name: "fetch_docs",
    description: "Fetch documentation for a given topic.");

AIFunction queryData = AIFunctionFactory.Create(
    (string query) => $"Rows for `{query}`: []",
    name: "query_data",
    description: "Run a read-only SQL-like query against the sample store.");

AIFunction sendEmail = new ApprovalRequiredAIFunction(
    AIFunctionFactory.Create(
        (string to, string subject) => $"Sent '{subject}' to {to}.",
        name: "send_email",
        description: "Send an email on behalf of the user."));

var options = HyperlightCodeActProviderOptions.CreateForWasm(guestPath);
options.Tools = [fetchDocs, queryData, sendEmail];

using var codeAct = new HyperlightCodeActProvider(options);

AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetChatClient(deploymentName)
    .AsAIAgent(new ChatClientAgentOptions()
    {
        ChatOptions = new()
        {
            Instructions = "You are a helpful assistant. Prefer orchestrating your work in a single "
                + "`execute_code` block using `call_tool(...)` over issuing many direct tool calls.",
        },
        AIContextProviders = [codeAct],
    });

Поскольку хост-инструменты выполняются за пределами песочницы, FileMounts и AllowedDomains ограничивают сам изолированный код, а не обратный вызов узла за call_tool(...). Когда вам нужен контролируемый доступ к конфиденциальному ресурсу, предпочитайте узкое средство узла вместо расширения разрешений песочницы.

Используйте HyperlightExecuteCodeFunction для прямого подключения

Если вам нужно использовать execute_code вместе с инструментами, доступными только напрямую, на одном и том же агенте, или если конфигурация песочницы фиксирована на всё время существования агента, используйте HyperlightExecuteCodeFunction вместо провайдера. Это автономный AIFunction, который создаёт один снимок переданных параметров при создании и повторно использует его при каждом вызове.

В отличие от HyperlightCodeActProvider, автономная функция не внедряет подсказки для промпта автоматически, поэтому вам нужно самостоятельно добавить вывод BuildInstructions(...) в инструкции агента. Передайте toolsVisibleToModel: false, когда зарегистрированные инструменты доступны только через call_tool(...), а true — когда те же инструменты также напрямую доступны модели.

AIFunction calculate = AIFunctionFactory.Create(
    (double a, double b) => a * b,
    name: "multiply",
    description: "Multiply two numbers.");

var options = HyperlightCodeActProviderOptions.CreateForWasm(guestPath);
options.Tools = [calculate];

using var executeCode = new HyperlightExecuteCodeFunction(options);

var instructions =
    "You are a helpful assistant. When math is involved, solve it by writing Python "
    + "and calling `execute_code` instead of computing values yourself.\n\n"
    + executeCode.BuildInstructions(toolsVisibleToModel: false);

AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetChatClient(deploymentName)
    .AsAIAgent(instructions: instructions, tools: [executeCode]);

HyperlightExecuteCodeFunction также реализует IDisposable. Если для конфигурации требуется утверждение (согласно ApprovalMode или потому, что настроенный инструмент сам обёрнут в ApprovalRequiredAIFunction), экземпляр предоставляет прокси-объект ApprovalRequiredAIFunction через AITool.GetService(...) — именно через него остальная часть платформы определяет, что требуется утверждение.

Настройка файлов и исходящего доступа

Гиперлайт может предоставить дерево /input, доступное только для чтения, и область /output для записи, предназначенную для результатов генерации артефактов.

  • Используется HostInputDirectory для того, чтобы сделать каталог узла доступным в разделе /input/.
  • Используйте FileMounts, чтобы сопоставить определённые пути хоста с песочницей через new FileMount(hostPath, mountPath).
  • Используйте AllowedDomains для включения исходящего доступа только для определенных целевых объектов или методов с помощью new AllowedDomain(target, methods).
var options = HyperlightCodeActProviderOptions.CreateForWasm(guestPath);
options.Tools = [compute];
options.FileMounts =
[
    new FileMount("/host/data", "/input/data"),
    new FileMount("/host/models", "/sandbox/models"),
];
options.AllowedDomains =
[
    new AllowedDomain("https://api.github.com"),
    new AllowedDomain("https://internal.api.example.com", ["GET"]),
];

using var codeAct = new HyperlightCodeActProvider(options);

Те же коллекции FileMounts и AllowedDomains, а также инструменты, можно изменять во время выполнения через AddFileMounts(...), RemoveFileMounts(...), AddAllowedDomains(...) и RemoveAllowedDomains(...) в HyperlightCodeActProvider.

Руководство по результатам

Чтобы извлечь текст из execute_code, завершите гостевой код выражением print(...); Hyperlight не возвращает значение последнего выражения автоматически.

Если доступ к файловой системе включен, записывайте более крупные артефакты в /output/<filename> вместо этого. Возвращенные файлы присоединяются к результату средства, тогда как файлы под /input доступны для чтения в песочнице.

Текущие ограничения

Этот пакет всё ещё находится в предварительной версии, и при планировании стоит учитывать некоторые ограничения:

  1. Пакет зависит от Hyperlight.HyperlightSandbox.Api, который еще не опубликован на nuget.org. Пока он не будет выпущен, восстановить проект не удастся.
  2. Поддержка платформы следует опубликованным пакетам серверной части Hyperlight: поддерживаемым средам Linux (KVM) и Windows (WHP). Неподдерживаемые платформы или отсутствие модулей виртуализации не позволят создать песочницу.
  3. Текущая серверная часть Wasm выполняет гостевой модуль Python, указанный HYPERLIGHT_PYTHON_GUEST_PATH. Серверная часть JavaScript (CreateForJavaScript()) доступна для гостевого кода в JavaScript.
  4. Состояние интерпретатора в памяти не сохраняется в разных вызовах execute_code . Используйте подключенные файлы и /output артефакты, когда данные должны сохраняться между вызовами.
  5. Утверждение применяется к execute_code вызову в целом, а не к каждому call_tool(...) внутри одного блока кода.
  6. Описания инструментов, аннотации параметров и формы возвращаемых значений имеют большее значение здесь, так как модель пишет код в соответствии с этим контрактом, а не использует изолированные прямые вызовы инструментов.
  7. Пока ещё нет эквивалента образца бенчмарка на .NET для Python — см. вкладку Python, где приведена опубликованная инфраструктура сравнения.

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

pip install agent-framework-hyperlight --pre

agent-framework-hyperlight поставляется отдельно от agent-framework-core, поэтому вы используете только песочницу, когда это необходимо.

Note

Пакет зависит от компонентов песочницы Hyperlight. Если серверная часть еще не опубликована для вашей текущей платформы, execute_code попытается создать песочницу, но это завершится ошибкой.

Используйте HyperlightCodeActProvider

HyperlightCodeActProvider — это рекомендуемая точка входа, когда требуется автоматически добавить CodeAct для каждого запуска. Он внедряет инструкции CodeAct, выполняемые в ограниченной области, а также инструмент execute_code, удерживая инструменты, принадлежащие поставщику, в стороне от непосредственного использования агентом.

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework.hyperlight import HyperlightCodeActProvider
from azure.identity import AzureCliCredential

# 1. Create the Hyperlight-backed provider and register sandbox tools on it.
codeact = HyperlightCodeActProvider(
    tools=[compute, fetch_data],
    approval_mode="never_require",
)

# 2. Create the client and the agent.
agent = Agent(
    client=FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["FOUNDRY_MODEL"],
        credential=AzureCliCredential(),
    ),
    name="HyperlightCodeActProviderAgent",
    instructions="You are a helpful assistant.",
    context_providers=[codeact],
)

# 3. Run a request that should use execute_code plus provider-owned tools.
query = (
    "Fetch all users, find admins, multiply 7*(3*2), and print the users, "
    "admins, and multiplication result. Use execute_code and call_tool(...) "
    "inside the sandbox."
)
result = await agent.run(query)
print(result.text)

Инструменты, зарегистрированные у поставщика, доступны внутри песочницы через call_tool(...), но они не предоставляются как прямые инструменты агента. Поставщик также предоставляет управление в стиле CRUD для инструментов, подключений файлов и исходящих записей списка разрешений с помощью таких методов, как add_tools(...), remove_tool(...), add_file_mounts(...) и add_allowed_domains(...).

Как работают утверждения и инструменты хоста

Средства Agent Framework содержат approval_mode, который управляет тем, могут ли они вызываться автоматически или должны быть приостановлены для утверждения пользователя.

Основное различие между регистрацией инструмента на HyperlightCodeActProvider и регистрацией его непосредственно на Agent(tools=...) заключается в том, как вызывается инструмент, а не где в конечном счете выполняется функция Python:

  • Средства, зарегистрированные на HyperlightCodeActProvider(tools=...), скрыты от модели в качестве прямых средств. Модель достигает их путем написания кода, вызывающего call_tool("name", ...) внутри execute_code.
  • Средства, зарегистрированные на Agent(tools=...) ней, отображаются в модели как средства первого класса, и каждый прямой вызов учитывает собственный approval_modeинструмент.

call_tool(...) — это мост обратно к обратным вызовам хоста; это не реимплементация инструмента в песочнице. Это означает, что средства, принадлежащие поставщику, по-прежнему выполняются в процессе узла, с любой файловой системой, сетью и учетными данными, к которым сам процесс узла может получить доступ.

Как правило:

  • Поместите дешевые, детерминированные, безопасные для цепочки инструменты на поставщика, так чтобы модель могла создавать множество вызовов внутри одного execute_code шага.
  • Сохраняйте побочные эффекты или операции, требующие одобрения, как прямые средства агента, часто с approval_mode="always_require", чтобы каждое вызов оставался по отдельности видимым и подлежащим одобрению.

Поскольку хост-инструменты выполняются за пределами песочницы, file_mounts и allowed_domains ограничивают сам изолированный код, а не обратный вызов узла за call_tool(...). Когда вам нужен контролируемый доступ к конфиденциальному ресурсу, предпочитайте узкое средство узла вместо расширения разрешений песочницы.

Note

Средства, вызываемые через call_tool(...), возвращают значение Python (dict, list, примитив или пользовательский объект) непосредственно в гостевую систему. Любой result_parser, настроенный на FunctionTool, предназначен для потребителей, использующих интерфейс LLM, и не выполняется по пути песочницы — применяйте форматирование внутри функции инструмента, если оно нужно для пользователей песочницы.

Используйте HyperlightExecuteCodeTool для прямого подключения

Если вам нужно интегрировать execute_code с инструментами, работающими только напрямую, на одном агенте, используйте HyperlightExecuteCodeTool вместо провайдера. Для фиксированных конфигураций можно создать инструкции CodeAct один раз и подключить средство напрямую:

from agent_framework.hyperlight import HyperlightExecuteCodeTool

execute_code = HyperlightExecuteCodeTool(
    tools=[compute],
    approval_mode="never_require",
)

codeact_instructions = execute_code.build_instructions(tools_visible_to_model=False)

Этот шаблон полезен, когда поверхность CodeAct является фиксированной, и жизненный цикл поставщика не требуется для каждого запуска. В отличие от самостоятельного средства, инструмент не внедряет руководство по запросу автоматически, поэтому вы несете HyperlightCodeActProviderответственность за добавление build_instructions(...) выходных данных в инструкции для агента самостоятельно.

Настройка файлов и исходящего доступа

Гиперлайт может предоставить дерево /input, доступное только для чтения, и область /output для записи, предназначенную для результатов генерации артефактов.

  • Используйте workspace_root, чтобы сделать рабочую область доступной в /input/.
  • Используйте file_mounts для сопоставления определенных путей хоста в песочницу.
  • Используйте allowed_domains для включения исходящего доступа только для определенных целевых объектов или методов.

file_mounts принимает строку в сокращенном формате, явную пару значений или именованный кортеж (host_path, mount_path). allowed_domains принимает строковый целевой объект, явную (target, method-or-methods) пару или именованный AllowedDomain кортеж.

from agent_framework.hyperlight import HyperlightCodeActProvider

codeact = HyperlightCodeActProvider(
    tools=[compute],
    file_mounts=[
        "/host/data",
        ("/host/models", "/sandbox/models"),
    ],
    allowed_domains=[
        "api.github.com",
        ("internal.api.example.com", "GET"),
    ],
)

Руководство по результатам

Чтобы получить текст из execute_code, завершите код с помощью print(...); Hyperlight не возвращает значение последнего выражения автоматически.

Если доступ к файловой системе включен, записывайте более крупные артефакты в /output/<filename> вместо этого. Возвращенные файлы присоединяются к результату средства, тогда как файлы под /input доступны для чтения в песочнице.

Сравнение CodeAct и прямой вызов инструментов

Концептуальное сравнение здесь такое же, как и для любого бэкенда CodeAct: один и тот же клиент, модель, инструменты, запрос и схему структурированного вывода можно подключить как через традиционный вызов инструментов, так и через CodeAct на базе Hyperlight. Единственное различие — в интерфейсе инструментов: прямые инструменты в сравнении с единым инструментом execute_code, работающим на базе HyperlightCodeActProvider:

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework.hyperlight import HyperlightCodeActProvider

# Direct tool calling: the model picks one tool at a time per turn.
direct = Agent(
    client=FoundryChatClient(...),
    instructions="...",
    tools=[fetch_data, compute],
)

# Hyperlight-backed CodeAct: the model writes one program per turn that
# orchestrates the same tools through call_tool(...).
codeact = Agent(
    client=FoundryChatClient(...),
    instructions="...",
    context_providers=[
        HyperlightCodeActProvider(
            tools=[fetch_data, compute],
            approval_mode="never_require",
        ),
    ],
)

Для рабочих нагрузок, которые вычисляют итоговые значения по всему набору данных за счёт многократного поиска данных и выполнения несложных вычислений — множества небольших, последовательно связанных шагов, — CodeAct может устранить накладные расходы на оркестрацию. Измерьте оба прогона с помощью секундомера и проверьте возвращённый ChatResponse.usage, чтобы сравнить затраченное время и использование токенов в вашей среде.

Текущие ограничения

Этот пакет по-прежнему находится на стадии альфа-версии, и стоит учитывать некоторые ограничения:

  1. Поддержка платформы согласуется с опубликованными пакетами бэкенда Hyperlight. Сегодня это означает поддерживаемые среды Linux и Windows, а создание песочницы на неподдерживаемых платформах не удастся.
  2. Текущая интеграция выполняет гостевой код Python.
  3. Состояние интерпретатора в памяти не сохраняется в разных вызовах execute_code . Используйте подключенные файлы и /output артефакты, когда данные должны сохраняться между вызовами.
  4. Утверждение применяется к execute_code вызову в целом, а не к каждому call_tool(...) внутри одного блока кода.
  5. Описания инструментов, аннотации параметров и формы возвращаемых значений имеют большее значение здесь, так как модель пишет код в соответствии с этим контрактом, а не использует изолированные прямые вызовы инструментов.

Дальнейшие действия