Hyperlight CodeAct

Hyperlight är den för närvarande dokumenterade serverdelen för CodeAct i Agent Framework. Det exponerar ett execute_code verktyg som backas upp av en isolerad sandbox-körning och kan anropa providerägda värdverktyg via call_tool(...).

Översikt över mönsternivå finns i CodeAct.

Varför Hyperlight CodeAct

Moderna agenter begränsas ofta mer av verktygets anropskostnader än av själva modellen. En uppgift som läser data, utför lätt beräkning och sammanställer ett resultat kan enkelt förvandlas till en modellkedja –> verktyg –> modell –> interaktion med verktyg, även när varje enskilt steg är enkelt.

Hyperlight-backade CodeAct komprimerar den loopen. Modellen skriver ett kort Python-program, sandbox-miljön kör det en gång och providerägda verktyg nås inifrån sandbox-miljön med call_tool(...). I representativa verktygsintensiva arbetsbelastningar kan det skiftet minska svarstiden till hälften och tokenanvändningen med över 60%, samtidigt som körningen förblir isolerad och möjlig att granska.

Get started

Kommer snart.

Installera paketet

pip install agent-framework-hyperlight --pre

agent-framework-hyperlight levereras separat från agent-framework-core, så du använder bara sandbox-miljön när du behöver den.

Anmärkning

Paketet är beroende av Hyperlight-sandbox-komponenter. Om serverdelen inte har publicerats för din aktuella plattform ännu misslyckas execute_code när den försöker skapa en sandbox.

Använd HyperlightCodeActProvider

HyperlightCodeActProvider är den rekommenderade startpunkten när du vill att CodeAct ska läggas till automatiskt för varje körning. Den matar in run-scoped CodeAct-instruktioner plus execute_code verktyget, samtidigt som providerägda verktyg hålls borta från verktygsytan för direktagenten.

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}")

Verktyg som är registrerade på providern är tillgängliga i sandbox-miljön via call_tool(...), men de exponeras inte som direkt agentverktyg. Providern exponerar också CRUD-stilhantering för verktyg, filmonteringar och utgående tillåtna listposter via metoder som add_tools(...), remove_tool(...), add_file_mounts(...)och add_allowed_domains(...).

Så här fungerar godkännanden och värdverktyg

Agent Framework-verktyg har en approval_mode som styr om de kan anropas automatiskt eller måste pausas för användarens godkännande.

Den största skillnaden mellan att registrera ett verktyg på HyperlightCodeActProvider och registrera det direkt på Agent(tools=...) är hur verktyget anropas, inte där Python-funktionen slutligen körs:

  • Verktyg som är registrerade på HyperlightCodeActProvider(tools=...) är dolda från modellen som direkta verktyg. Modellen når dem genom att skriva kod som anropar call_tool("name", ...) inuti execute_code.
  • Verktyg som är registrerade på Agent(tools=...) visas i modellen som förstklassiga verktyg, och varje direktanrop respekterar verktygets egna approval_mode.

call_tool(...) är en brygga tillbaka till värdåteranrop; det är inte en omimplementering av verktyget i sandbox-miljön. Det innebär att providerägda verktyg fortfarande körs i värdprocessen, med alla filsystem, nätverk och autentiseringsuppgifter som själva värdprocessen kan komma åt.

Som tumregel:

  • Sätt billiga, deterministiska, säkra verktyg på leverantören så att modellen kan skriva många anrop i en execute_code sväng.
  • Behåll sidoeffektgivande eller godkännande-gaterade åtgärder som direkta agentverktyg, ofta med approval_mode="always_require", så att varje anrop förblir individuellt synliga och godkännandebara.

Eftersom värdverktyg körs utanför sandbox-miljön file_mounts och allowed_domains begränsar själva sandbox-koden, inte värdåteranropet bakom call_tool(...). När du behöver kontrollerad åtkomst till en känslig resurs föredrar du ett smalt värdverktyg framför breddning av sandbox-behörigheter.

Anmärkning

Verktyg som anropas via call_tool(...) returnerar sitt interna Python värde (dict, list, primitivt eller anpassat objekt) direkt till gästen. Alla result_parser som konfigureras på en FunctionTool är avsedda för konsumenter riktade mot LLM och körs inte på sandbox-miljön – om du behöver formatering för konsumenter inom sandbox-miljön, använd själva verktygsfunktionen för detta.

Använd HyperlightExecuteCodeTool för direktkoppling

När du behöver blanda execute_code med endast direkta verktyg på samma agent, använd HyperlightExecuteCodeTool istället för leverantören. För fasta konfigurationer kan du skapa CodeAct-instruktionerna en gång och koppla verktyget direkt:

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)

Det här mönstret är användbart när CodeAct-ytan är fast och du inte behöver providerns livscykel vid varje körning. Till skillnad från HyperlightCodeActProvider injicerar det fristående verktyget inte promptvägledning automatiskt, så du ansvarar själv för att lägga till build_instructions(...)-utdata i agentinstruktionerna.

Konfigurera filer och utgående åtkomst

Hyperlight kan exponera ett skrivskyddat /input träd plus ett skrivbart /output område för genererade artefakter.

  • Använd workspace_root för att göra en arbetsyta tillgänglig under /input/.
  • Använd file_mounts för att mappa specifika värdsökvägar till sandbox-miljön.
  • Använd allowed_domains för att endast aktivera utgående åtkomst för specifika mål eller metoder.

file_mounts accepterar en korthandssträng, ett explicit (host_path, mount_path) par eller en FileMount namngiven tupel. allowed_domains accepterar ett strängmålobjekt, ett explicit (target, method-or-methods)-par eller en namngiven tuppel.

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"),
    ],
)

Vägledning för resultat

Om du vill visa text från execute_codeavslutar du koden med print(...); Hyperlight returnerar inte värdet för det senaste uttrycket automatiskt.

När filsystemåtkomst är aktiverad skriver du större artefakter till /output/<filename> istället. Returnerade filer är kopplade till verktygsresultatet, medan filer under /input är tillgängliga för läsning i sandbox-miljön.

Jämför CodeAct- och direktverktygsanrop

Benchmark-exemplet kör samma uppgift med samma klient, modell, verktyg, prompt och strukturerade utdataschema en gång via traditionella verktygsanrop och en gång via Hyperlight-backad CodeAct. Den enda skillnaden är kabeldragningen: direkta verktyg jämfört med ett enda execute_code verktyg som backas upp av 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

I det exemplet beräknar agenten totalsummor över en datauppsättning med användare och beställningar genom att upprepade gånger leta upp data och utföra lätta beräkningar. Det är precis den typ av arbetsflöde med många små steg där CodeAct kan ta bort orkestreringskostnader. Det fullständiga exemplet skriver ut förfluten tid och tokenanvändning för båda körningarna så att du kan jämföra körningsformen i din egen miljö.

Aktuella begränsningar

Det här paketet är fortfarande alfa, och några begränsningar är värda att planera runt:

  1. Plattformsstödet följer de publicerade Hyperlight-backendpaketen. Idag innebär det linux- och Windows-miljöer som stöds. plattformar som inte stöds misslyckas när sandbox-miljön skapas.
  2. Den aktuella integreringen kör Python-gästkod. .NET-dokumentationen kommer fortfarande snart.
  3. Minnesintern tolkstatus bevaras inte mellan separata execute_code anrop. Använd monterade filer och /output artefakter när data behöver överleva mellan anrop.
  4. Godkännande gäller för anropet execute_code som helhet, inte för varje individ call_tool(...) i samma kodblock.
  5. Verktygsbeskrivningar, parameteranteckningar och returformer betyder mer här eftersom modellen skriver kod mot kontraktet i stället för att välja isolerade direktverktygsanrop.

Nästa steg