Hyperlight CodeAct

Hyperlight é o back-end documentado atualmente para CodeAct no Agent Framework. Ele expõe uma execute_code ferramenta apoiada por um runtime de área restrita isolada e pode chamar ferramentas de host de propriedade do provedor por meio de call_tool(...).

Para obter a visão geral do nível do padrão, consulte CodeAct.

Por que o CodeAct do Hyperlight

Os agentes modernos geralmente são limitados mais pela sobrecarga de chamada de ferramentas do que pelo próprio modelo. Uma tarefa que lê dados, executa uma computação leve e monta um resultado pode facilmente se transformar em uma cadeia de interações de modelo -> ferramenta -> modelo -> ferramenta, mesmo quando cada etapa individual é simples.

CodeAct apoiado por Hyperlight colapsa esse loop. O modelo grava um programa curto em Python, a sandbox o executa uma vez, e ferramentas do provedor são acessadas de dentro da sandbox com call_tool(...). Em cargas de trabalho de ferramentas pesadas representativas, essa mudança pode reduzir a latência aproximadamente pela metade e o uso de token em mais de 60%, mantendo a execução isolada e auditável.

Introdução

Em breve.

Instalar o pacote

pip install agent-framework-hyperlight --pre

agent-framework-hyperlight é enviado separadamente de agent-framework-core, então você só assume o runtime da área restrita quando precisar.

Note

O pacote depende dos componentes sandbox do Hyperlight. Se o back-end ainda não tiver sido publicado para sua plataforma atual, execute_code falha ao tentar criar o sandbox.

Utilize HyperlightCodeActProvider

HyperlightCodeActProvider é o ponto de entrada recomendado quando você deseja que CodeAct seja adicionado automaticamente para cada execução. Ele injeta instruções CodeAct com escopo de execução, além da ferramenta execute_code, enquanto mantém as ferramentas de propriedade do provedor fora da superfície direta da ferramenta do agente.

async def main() -> None:
    """Run the provider-owned Hyperlight CodeAct sample."""
    # 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],
        middleware=[log_function_calls],
    )

    # 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."
    )
    print(f"{_CYAN}{'=' * 60}")
    print("Hyperlight CodeAct provider sample")
    print(f"{'=' * 60}{_RESET}")
    print(f"{_CYAN}User: {query}{_RESET}")
    result = await agent.run(query)
    print(f"{_CYAN}Agent: {result.text}{_RESET}")

As ferramentas registradas no provedor estão disponíveis dentro da área restrita através de call_tool(...), mas não são expostas como ferramentas de agentes diretos. O provedor também expõe o gerenciamento de estilo CRUD para ferramentas, montagens de arquivo e entradas de lista de permissões de saída por meio de métodos como add_tools(...), remove_tool(...), add_file_mounts(...) e add_allowed_domains(...).

Como as aprovações e as ferramentas de host funcionam

As ferramentas do Agent Framework têm um approval_mode controle que controla se elas podem ser invocadas automaticamente ou devem pausar para aprovação do usuário.

A principal diferença entre registrar uma ferramenta HyperlightCodeActProvider e registrá-la diretamente Agent(tools=...) é como a ferramenta é invocada, não onde a função Python é executada:

  • As ferramentas registradas em HyperlightCodeActProvider(tools=...) estão ocultas para o modelo como ferramentas diretas. O modelo os alcança escrevendo código que chama call_tool("name", ...) dentro execute_code.
  • Ferramentas registradas no Agent(tools=...) são exibidas como ferramentas de primeira classe, e cada chamada direta respeita o approval_mode da própria ferramenta.

call_tool(...) é uma ponte de volta para os retornos de chamada para o host; não é uma reimplementação da ferramenta no ambiente isolado. Isso significa que as ferramentas de propriedade do provedor ainda são executadas no processo de host, com qualquer sistema de arquivos, rede e credenciais que o próprio processo de host possa acessar.

Como regra geral:

  • Coloque ferramentas baratas, determinísticas e seguras em cadeia no provedor para que o modelo possa compor muitas chamadas em uma única execute_code vez.
  • Mantenha operações que provocam efeitos colaterais ou que necessitam de aprovação como ferramentas diretas do agente, geralmente com approval_mode="always_require", para que cada invocação permaneça individualmente visível e aprovável.

Como as ferramentas de host são executadas fora da área restrita, file_mounts e allowed_domains restringem o código dentro da área restrita, não o callback do host por trás de call_tool(...). Quando você precisar de acesso controlado a um recurso confidencial, prefira uma ferramenta de host estreita em vez de ampliar as permissões de área restrita.

Utilize HyperlightExecuteCodeTool para conexão direta

Quando você precisar integrar execute_code a ferramentas de acesso direto no mesmo agente, use HyperlightExecuteCodeTool em vez do provedor. Para configurações fixas, você pode criar as instruções codeact uma vez e conectar a ferramenta diretamente:

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)

Esse padrão é útil quando a superfície CodeAct é fixa e você não precisa do ciclo de vida do provedor a cada execução. Ao contrário de HyperlightCodeActProvider, a ferramenta autônoma não injeta diretrizes de prompt automaticamente, portanto, você é responsável por adicionar a build_instructions(...) saída às instruções do agente você mesmo.

Configurar arquivos e acesso de saída

O Hyperlight pode expor uma árvore somente para leitura /input além de uma área gravável /output para artefatos gerados.

  • Use workspace_root para disponibilizar um espaço de trabalho em /input/.
  • Use file_mounts para mapear caminhos de host específicos para o sandbox.
  • Use allowed_domains para habilitar o acesso de saída apenas para destinos ou métodos específicos.

file_mounts aceita uma cadeia de caracteres abreviada, um par explícito (host_path, mount_path) ou uma FileMount tupla nomeada. allowed_domains aceita uma string de destino, um par explícito (target, method-or-methods) ou uma tupla nomeada 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"),
    ],
)

Diretrizes de saída

Para exibir o texto de execute_code, encerre o código com print(...); O Hyperlight não retorna automaticamente o valor da última expressão.

Quando o acesso ao sistema de arquivos estiver habilitado, escreva artefatos maiores em /output/<filename> em vez disso. Os arquivos retornados são anexados ao resultado da ferramenta, enquanto os arquivos /input embaixo estão disponíveis para leitura dentro da área restrita.

Comparar CodeAct e chamada de ferramenta direta

A amostra de referência executa a tarefa idêntica com o mesmo cliente, modelo, ferramentas, prompt e esquema de saída estruturado uma vez através da chamada tradicional de ferramenta e outra vez através do CodeAct suportado pelo Hyperlight. A única diferença é a fiação: ferramentas diretas versus uma única execute_code ferramenta suportada por HyperlightCodeActProvider.

async def _run_traditional() -> tuple[float, AgentResponse]:
    agent = Agent(
        client=get_client(),
        name="TraditionalAgent",
        instructions=INSTRUCTIONS,
        tools=TOOLS,
        default_options={"response_format": UserGrandTotals},
    )
    start = time.perf_counter()
    result = await agent.run(BENCHMARK_PROMPT)
    elapsed = time.perf_counter() - start
    return elapsed, result


async def _run_codeact() -> tuple[float, AgentResponse]:
    codeact = HyperlightCodeActProvider(
        tools=TOOLS,
        approval_mode="never_require",
    )
    agent = Agent(
        client=get_client(),
        name="CodeActAgent",
        instructions=INSTRUCTIONS,
        context_providers=[codeact],
        default_options={"response_format": UserGrandTotals},
    )
    start = time.perf_counter()
    result = await agent.run(BENCHMARK_PROMPT)
    elapsed = time.perf_counter() - start
    return elapsed, result

Nesse exemplo, o agente calcula totais gerais em um conjunto de dados de usuários e pedidos pesquisando dados repetidamente e executando computação leve. Esse é exatamente o tipo de fluxo de trabalho de muitas etapas pequenas em que o CodeAct pode remover a sobrecarga de orquestração. O exemplo completo imprime o tempo decorrido e o uso do token para ambas as execuções para que você possa comparar a forma de execução em seu próprio ambiente.

Limitações atuais

Este pacote ainda está na fase alfa, e algumas restrições valem a pena ser consideradas no planejamento.

  1. O suporte à plataforma segue os pacotes de back-end do Hyperlight publicados. Hoje isso significa ambientes Linux e Windows com suporte; As plataformas sem suporte falharão ao criar a área restrita.
  2. A integração atual executa o código convidado do Python. A documentação do .NET ainda estará disponível em breve.
  3. O estado do interpretador na memória não persiste entre chamadas separadas execute_code . Use arquivos e /output artefatos montados quando os dados precisarem sobreviver entre chamadas.
  4. A aprovação se aplica à execute_code invocação como um todo, não a cada indivíduo call_tool(...) dentro do mesmo bloco de código.
  5. Descrições de ferramenta, anotações de parâmetro e estruturas de retorno importam mais aqui porque o modelo está gerando código com base nesse contrato em vez de optar por chamadas diretas de ferramenta isoladas.

Próximas Etapas