Agen yang Dihosting oleh Foundry

Agen yang dihosting di Microsoft Foundry Agent Service memungkinkan Anda menyebarkan aplikasi agen kontainer ke infrastruktur yang dikelola Microsoft. Platform ini menangani penskalaan, persistensi status sesi, keamanan, dan manajemen siklus hidup sehingga Anda dapat fokus pada logika agen Anda. Microsoft Foundry Hosted Agents umumnya tersedia dan mendukung agen yang dibangun dengan kode Anda sendiri atau kerangka kerja agen pilihan. Artikel ini membahas integrasi hosting Agent Framework secara khusus.

Dengan menggunakan integrasi hosting Agent Framework, Anda dapat mengekspos Agent melalui protokol Respons atau Pemanggilan Foundry dengan kode minimal. Python juga mendukung meng-host Workflow native secara langsung, tanpa mengonversinya menjadi agen.

Nota

Anda juga dapat menyebarkan kode agen yang dibangun dengan kerangka kerja lain ke agen yang dihosting Foundry dengan menggunakan alur kerja Azure Developer CLI (azd). Untuk konsep yang tidak bergantung pada framework dan panduan deployment, lihat Apa itu agen yang dihosting? Artikel ini selanjutnya berfokus pada integrasi Agent Framework.

Kapan menggunakan agen yang dihosting

Pilih Agen yang dihosting Foundry saat Anda ingin:

  • Infrastruktur terkelola — tidak perlu mengonfigurasi kontainer, server web, atau aturan penskalakan sendiri.
  • Manajemen sesi bawaan — platform mempertahankan $HOME dan file diunggah melalui giliran dan periode idle.
  • Identitas agen khusus — setiap agen yang disebarkan mendapatkan identitas Entra sendiri untuk akses aman ke model, alat, dan layanan hilir.
  • Titik akhir yang kompatibel dengan OpenAI — klien dapat berinteraksi dengan agen Anda menggunakan SDK yang kompatibel dengan OpenAI melalui protokol Respons.
  • Untuk agen audio real time, gunakan agen yang dihosting dengan Azure Speech di Foundry Tools (Voice Live) untuk deteksi aktivitas suara sisi server, pembatalan gema, dan pengurangan kebisingan. Untuk detailnya, lihat Menggunakan Voice Live dengan agen yang dihosting.

Nota

Integrasi Python agent-framework-foundry-hosting masih dalam tahap pra-rilis. Microsoft Foundry Hosted Agents, layanan hosting terkelola, umumnya tersedia.

Prerequisites

Untuk pengujian lokal, Anda juga perlu:

Pasang paket hosting NuGet:

dotnet add package Microsoft.Agents.AI.Foundry.Hosting --prerelease
  • Python 3.10 atau yang lebih baru

Instal paket hosting prarilis, klien Foundry, dan paket autentikasi Azure:

pip install --pre agent-framework-foundry agent-framework-foundry-hosting azure-identity

Di Foundry, platform menyediakan konteks pengguna pemanggil dan konteks panggilan; infrastruktur hosting menggunakannya untuk mengisolasi status per pengguna dan meneruskan konteks permintaan ke layanan Foundry. Eksekusi lokal tidak menerima konteks platform tersebut, sehingga aplikasi harus menyediakan kontrol identitas dan status mereka sendiri saat diperlukan.

Protokol respons

Protokol Respons adalah titik awal yang direkomendasikan untuk sebagian besar agen. Ini mengekspos titik akhir yang kompatibel /responses dengan OpenAI, dan platform mengelola riwayat percakapan, streaming, dan siklus hidup sesi secara otomatis.

Untuk agen Python yang dihosting, respons yang berakhir lebih awal berstatus incomplete. Klien streaming menerima event terminal response.incomplete, sedangkan klien non-streaming menerima status yang diatur ke incomplete. Alasan selesai content_filter dipetakan ke incomplete_details.reason yang disetel ke content_filter, dan length dipetakan ke max_output_tokens. Setiap output atau konten penolakan yang dihasilkan tetap tersedia dalam respons.

using Azure.AI.AgentServer.Core;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;

var projectEndpoint = new Uri(Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set."));
var deployment = Environment.GetEnvironmentVariable("FOUNDRY_MODEL")
    ?? Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME")
    ?? "gpt-4o";

AIAgent agent = new AIProjectClient(projectEndpoint, new DefaultAzureCredential())
    .AsAIAgent(
        model: deployment,
        instructions: "You are a helpful AI assistant.",
        name: "my-agent");

var builder = AgentHost.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);
builder.RegisterProtocol("responses", endpoints => endpoints.MapFoundryResponses());

var app = builder.Build();
app.Run();

AgentHost.CreateBuilder menciptakan host aplikasi yang telah dikonfigurasi sebelumnya untuk lingkungan hosting Foundry. AddFoundryResponses mendaftarkan agen Anda dengan penangan protokol Responses, dan MapFoundryResponses memetakan titik akhir HTTP /responses.

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.identity import DefaultAzureCredential

client = FoundryChatClient(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    model=os.environ.get("FOUNDRY_MODEL") or os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
    credential=DefaultAzureCredential(),
)

agent = Agent(
    client=client,
    instructions="You are a helpful AI assistant.",
)

server = ResponsesHostServer(agent)
server.run()

ResponsesHostServer mengelilingi agen Anda dan mengeksposnya melalui protokol Foundry Responses. Field milik pemanggil store menentukan apakah respons eksternal, sesi yang dikelola host, dan status persetujuan disimpan. Pengaturan history_source secara independen memilih siapa yang menyediakan riwayat model:

history_source Perilaku riwayat model
"agent_server" (standar) Host merekonstruksi transkrip Respons luar yang disimpan dan menonaktifkan penyimpanan layanan hilir untuk mencegah riwayat duplikat.
"service" Host hanya mengirim input saat ini dan secara privat menyimpan ID kelanjutan layanan model penyimpanan. Percakapan penyedia tersimpan tidak dapat bercabang dari respons sebelumnya.
"agent" Host tersebut hanya mengirim input saat ini. Setelan default penyimpanan agen HistoryProvider atau layanan downstream mengelola riwayat.

Jangan gabungkan "agent_server" atau "service" dengan HistoryProvider yang mendukung beban. Mode default juga menolak opsi kelanjutan hilir tetap seperti conversation_id, , previous_response_iddan conversation. Gunakan history_source="agent" untuk implementasi kustom SupportsAgentRun .

Parameter response_store konstruktor memilih backend untuk persistensi Respons luar. Parameter konstruktor store yang lebih lama adalah alias yang tidak digunakan lagi untuk response_store; tidak ada parameter yang mengatur bidang per permintaan store pemanggil. Permintaan dengan store=false bersifat sekali pakai: tidak menyimpan status yang dikelola oleh host, menonaktifkan penyimpanan downstream yang didukung, dan tidak dapat menggunakan background=true.

Host memiliki agen yang disediakan dan mungkin menambahkan penyedia konteks khusus hosting. Jangan gunakan kembali agen dengan host lain atau memanggilnya secara langsung setelah host dibuat.

Host Respons mempertahankan panggilan komputer asli, cuplikan layar, dan pemeriksaan keamanan. Aplikasi Anda harus menjalankan tindakan yang diminta dan secara eksplisit mengakui pemeriksaan keamanan apa pun. Untuk alur lengkap, lihat Penggunaan komputer asli.

Memilih instans agen atau pabrik

Baik ResponsesHostServer maupun InvocationsHostServer menerima instans agen atau objek yang dapat dipanggil secara sinkron maupun asinkron tanpa argumen melalui parameter agent. Host menggunakan kembali instans selama masa pakainya. Fungsi yang dapat dipanggil dijalankan satu kali untuk setiap permintaan, dan agen yang dihasilkan merupakan milik permintaan tersebut.

Gunakan callable ketika agen reguler mempertahankan state yang dapat diubah di luar AgentSession. Host hanya menyimpan store sesi, checkpoint, dan persetujuan fungsi yang didukungnya, bukan bidang arbitrer pada agen yang dilingkup permintaan.

Warning

Menghosting WorkflowAgent, seperti workflow.as_agent(), melalui agent= tidak lagi didukung. WorkflowAgent menyimpan status alur kerja dalam memori di antara eksekusi, sehingga satu instans tidak boleh melayani permintaan dari pengguna atau percakapan yang berbeda. Host alur kerja secara native melalui workflow= dan factory yang memahami konteks request.

Hingga Anda memigrasikan host Responses, pabrik yang membuat alur kerja baru, pelaksana, agen terbungkus, klien, penyedia, dan alat untuk setiap permintaan adalah bentuk warisan yang aman. Jaga agar nama alur kerja dan ID pelaksana tetap stabil sehingga host dapat memulihkan titik pemeriksaan. Untuk host Invocations, bentuk factory lama ini hanya sesuai dengan alur kerja satu giliran tanpa status karena hosting agen tidak memulihkan titik pemeriksaan alur kerja.

Gunakan juga factory saat integrasi menyertakan identitas permintaan atau memiliki sumber daya spesifik permintaan. Misalnya, buat koneksi MCP, Kotak Alat, penyedia keterampilan, klien Pencarian, penyedia Memori, dan kredensial mereka di dalam pabrik saat mereka menggunakan panggilan platform atau konteks pengguna saat ini. Menggunakan kembali koneksi MCP di seluruh proses dapat mempertahankan identitas permintaan yang membukanya.

Host memasukkan dan keluar dari agen yang dibuat pabrik untuk setiap permintaan. Agent mengelola klien yang dikelola konteks dan alat MCP, tetapi pabrik Anda harus menutup penyedia, transportasi, atau kredensial lain yang dibuatnya. Jangan tutup objek bersama yang disediakan aplikasi dari luar pabrik.

Menjalankan alur kerja native dengan Respons

Python dapat menghosting alur kerja yang dibangun secara langsung melalui workflow=. Workflow native memerlukan parse_response panggilan balik yang memetakan permintaan Responses saat ini ke input awal bertipe atau batch lengkap balasan yang tertunda:

from pydantic import BaseModel

from agent_framework_foundry_hosting import (
    CheckpointStoreProvider,
    HostedResponseRequest,
    ResponsesHostServer,
    WorkflowTurn,
)


class Ticket(BaseModel):
    text: str


def build_workflow(request: HostedResponseRequest):
    return build_fresh_workflow()


async def parse_response(request: HostedResponseRequest) -> WorkflowTurn[Ticket]:
    items = await request.get_input_items()
    if any(item.get("type") in ("function_call_output", "mcp_approval_response") for item in items):
        return WorkflowTurn(responses=await request.get_workflow_responses())

    text = await request.get_input_text()
    return WorkflowTurn(input=Ticket.model_validate_json(text or ""))


server = ResponsesHostServer(
    workflow=build_workflow,
    parse_response=parse_response,
    checkpoint_store_provider=CheckpointStoreProvider(
        allowed_checkpoint_types=[f"{Ticket.__module__}:{Ticket.__qualname__}"],
    ),
)

Gunakan factory sinkron atau asinkron yang sadar permintaan untuk alur kerja yang dapat menjeda, melanjutkan, atau memulihkan pekerjaan latar belakang. Factory harus mengembalikan grafik yang baru dibangun dengan executor, agen, klien, penyedia, dan tool yang baru serta dapat diubah. Jaga agar nama alur kerja dan ID pelaksana tetap stabil sehingga host dapat memulihkan titik pemeriksaan yang tepat yang terkait dengan respons luar.

Pengguna tepercaya platform dan kotak pasir Foundry mengisolasi status alur kerja asli. Host memvalidasi batch balasan tertunda lengkap sebelum menggunakan otoritas balasan apa pun. Balasan basi, parsial, duplikat, diputar ulang, lintas pengguna, dan antar-sandbox gagal sebelum eksekusi alur kerja. Permintaan dengan store=false tidak menyimpan status alur kerja dan tidak dapat mengembalikan jeda yang dapat dilanjutkan.

Untuk alur kerja warisan yang menerima list[Message], gunakan response_input_messages(request) untuk mengonversi hanya giliran Respons saat ini. Ini tidak memuat outer history sebelumnya atau mendekode balasan alur kerja yang tertunda. Hosting agent=workflow.as_agent() tetap tersedia selama beta saat ini, tetapi memancarkan peringatan penghentian. Untuk contoh lengkapnya, lihat contoh alur kerja native Responses.

Mempertahankan status dan menangani percakapan jangka panjang

ResponsesHostServer dan InvocationsHostServer konfigurasikan penyimpanan sesi persisten secara default. AgentSessionStoreProvider menyediakan sebuah FoundryAgentSessionStore; Sesi respons menggunakan penyimpanan logis agent_sessions, sementara sesi invokasi menggunakan penyimpanan invocation_sessions yang terpisah. Penyimpanan ini menggunakan Foundry State Store saat dihosting dan penyimpanan berbasis file milik SDK saat Anda menjalankannya secara lokal.

Untuk agen alur kerja Responses, CheckpointStoreProvider menyediakan FoundryCheckpointStore. Workflow Native Responses dan Invocations menggunakan provider yang sama untuk checkpoint kelanjutan yang sama persis. FunctionApprovalStoreProvider menyediakan FoundryFunctionApprovalStore untuk persetujuan alat agen yang tertunda. Permintaan alur kerja bawaan dan balasan persetujuan terikat ke titik pemeriksaan alur kerja sebagai gantinya.

Saat berjalan di Foundry, penyimpanan Python bawaan menyimpan status namespace berdasarkan ID pengguna platform dan ID sesi sandbox Foundry. Mereka juga memerlukan ID panggilan platform untuk setiap operasi status. ID panggilan mengotorisasi dan menghubungkan operasi; ini bukan ID percakapan dan bukan bagian dari kunci penyimpanan.

Untuk respons, FOUNDRY_AGENT_SESSION_ID yang dikonfigurasi platform mengidentifikasi sandbox, dan agent_session_id berbeda yang diberikan oleh pemanggil akan ditolak. Untuk Pemanggilan, host memverifikasi parameter kueri yang dirutekan agent_session_id terhadap konteks permintaan. Jika FOUNDRY_AGENT_SESSION_ID tidak dikonfigurasi, parameter kueri harus ada, tidak kosong, dan cocok dengan konteks permintaan. Nilai yang hilang, duplikat, atau bertentangan akan ditolak alih-alih menggunakan ID cadangan SDK.

Jaminan ini berlaku untuk store yang di-host secara default. Penyedia penyimpanan kustom harus menerapkan isolasi pengguna dan sandbox yang setara, mempertahankan konten di dalam AgentSession.session_id secara terpisah dari kunci pencarian host, dan menggunakan operasi tulis bersyarat agar permintaan kedaluwarsa tidak dapat menimpa snapshot yang lebih baru. Kunci baru harus menggunakan tulisan buat-saja daripada upsert tanpa syarat. Lihat sampel penyimpanan kustom untuk implementasi Cosmos DB dengan penulisan dan penghapusan yang dilindungi ETag.

Dengan history_source="agent", penyimpanan sesi yang dikonfigurasi mempertahankan status penyedia yang dibawa oleh AgentSession, termasuk pesan dari InMemoryHistoryProvider.

Kedua host mendukung StoreProvider[SessionStore] hingga agent_session_store_provider. Status sesi harus mendukung AgentSession serialisasi. Mendaftarkan codec untuk jenis status kustom dengan register_state_type(); status yang dipulihkan tidak mempertahankan identitas objek Python. Penyimpanan default baru kedaluwarsa sesi 30 hari setelah penulisan terakhir mereka. Penyedia kustom mengontrol retensi mereka sendiri.

Penyimpanan default yang dicakup tidak membaca data lama tanpa cakupan agent_sessions, invocation_sessions, titik pemeriksaan, atau persetujuan fungsi. Mulai percakapan Responses yang baru alih-alih menggunakan kembali previous_response_id lama atau ID percakapan. Pemanggilan dimulai dengan sebuah sesi Agent Framework yang kosong dalam penyimpanan yang tercakup.

Rekaman yang dimuat AgentSession menggunakan kondisi ETag. Jika permintaan lain lebih dahulu memajukan sesi yang sama, maka penulisan usang akan gagal alih-alih menimpa status yang lebih baru. Pemeriksaan ini tidak menyediakan transaksi atau eksekusi yang dijamin hanya sekali untuk efek samping pada agen atau alat, sehingga aplikasi tetap harus mengoordinasikan permintaan yang saling tumpang tindih.

Untuk penyimpanan khusus Respons, teruskan StoreProvider ke function_approval_store_provider atau ContextScopedStoreProvider ke checkpoint_store_provider.

Pekerjaan latar belakang eksternal menggunakan response.id yang terlihat oleh pemanggil untuk polling. Konfigurasi default background_source="agent_server" tetap menjalankan eksekusi di latar belakang pada host. Tetapkan background_source="provider" hanya dengan history_source="service" dan klien Responses yang menyimpan dan dapat dilanjutkan kembali. Jika ResponsesServerOptions(resilient_background=True) juga diatur, host hanya dapat melanjutkan kembali polling penyedia setelah menyimpan token kelanjutan privat. Buat efek samping alat lokal bersifat idempoten, karena kegagalan sebelum token berikutnya disimpan dapat menyebabkan efek tersebut dijalankan kembali.

Impor ResponsesServerOptions dari azure.ai.agentserver.responses, dan teruskan ke ResponsesHostServer melalui options parameter . Opsi percakapan jangka panjang yang tersedia bergantung pada jenis agen:

Kemampuan Jenis agen Persyaratan dan perilaku
Pemulihan latar belakang titik pemeriksaan alur kerja Hanya alur kerja Atur ResponsesServerOptions(resilient_background=True). Kirim permintaan Respons dengan store=true dan background=true. Setelah menghidupkan ulang, host melanjutkan titik pemeriksaan alur kerja tahan lama terbaru atau memutar ulang input asli jika tidak ada titik pemeriksaan. Jangan konfigurasikan penyimpanan titik pemeriksaan pada alur kerja karena host mengelolanya. Buat efek samping eksternal bersifat idempoten karena pekerjaan setelah checkpoint persisten terakhir mungkin terulang.
Respons latar belakang native dari penyedia Di luar alur kerja Agent dengan klien penyimpanan Responses Atur history_source="service" dan background_source="provider". Atur resilient_background=True saat token kelanjutan penyedia yang disimpan harus tetap ada setelah host dimulai ulang.
Percakapan yang dapat diarahkan Untuk sementara tidak tersedia Jangan atur steerable_conversations=True. Host memunculkan RuntimeError selama proses konstruksi hingga SDK Server Agen dapat menangani perubahan arah kemudi yang ditolak dengan aman.

Untuk implementasi lengkap, lihat penyimpanan kustom, riwayat dan latar belakang Respons dasar, dan sampel alur kerja yang berjalan lama yang tangguh .

Baca file dari sandbox yang di-host

Perlakukan $HOME persisten milik sandbox yang dihosting sebagai sumber daya yang dirutekan berdasarkan permintaan, bukan sebagai batas umum sistem file. Hanya terima file yang secara eksplisit diunggah oleh aplikasi Anda ke direktori khusus, validasikan identitas sandbox saat ini, dan tolak jalur absolut, path traversal, tautan, file yang bukan file reguler, serta konten yang terlalu besar atau tidak valid.

Untuk protokol Respons, rutekan permintaan ke sesi yang dihosting dengan agent_session_id bidang isi. Pemilih string kueri digunakan untuk Invocations. Unggahan sesi dan file interpreter kode Toolbox merupakan sumber daya yang terpisah; file kotak pasir yang diunggah tidak secara otomatis di-mount ke dalam kontainer Toolbox. Lihat contoh file sesi untuk pembacaan UTF-8 terbatas dan panduan untuk unggahan lokal dan yang dihosting.

Opsi untuk permintaan kontrol

Host memetakan bidang pembuatan Respons asli ke opsi eksekusi Kerangka Kerja Agen. Misalnya, max_output_tokens menjadi max_tokens, dan parallel_tool_calls menjadi allow_multiple_tool_calls. Nilai yang diratakan dari extra_body mengambil alih nilai asli yang diterjemahkan.

Gunakan hook sinkron atau asinkron prepare_options(request, options) untuk menghapus atau mengganti opsi model pemanggil sebelum agen reguler berjalan. Kait tidak dapat mengatur bidang identitas, penyimpanan, kelanjutan, atau transportasi yang dikontrol host. Untuk implementasi kustom SupportsAgentRun yang tidak dapat menerima opsi model runtime, atur unsupported_options ke "warn" (default), "ignore", atau "error".

Ketika alat MCP yang di-host di Foundry memerlukan persetujuan pengguna, ResponsesHostServer mengembalikan respons yang tidak lengkap dengan item output oauth_consent_request. Sajikan consent_link kepada pengguna, lalu lanjutkan dengan ID respons yang belum lengkap, yaitu previous_response_id, setelah pengguna memberikan persetujuan. Host tersebut mempertahankan sesi agen untuk percobaan ulang ini dan hanya menyediakan tautan persetujuan HTTPS absolut saja.

Jika host Anda mengetahui asal otorisasi yang diharapkan, batasi tautan persetujuan dengan allowed_oauth_consent_origins:

server = ResponsesHostServer(
    agent,
    allowed_oauth_consent_origins=[
        "https://logic-region.consent.azure-apihub.net",
        "https://auth.partner.example",
    ],
)

Menghilangkan daftar izin menjaga validasi absolut-HTTPS tanpa membatasi asal tujuan. Memberikan daftar kosong akan menolak semua tautan persetujuan. Konfigurasikan hanya origin HTTPS yang persis; entri yang menyertakan jalur, kueri, atau fragmen akan ditolak.

Protokol pemanggilan

Protokol Pemanggilan memberi Anda kontrol penuh atas permintaan dan respons HTTP. Gunakan saat Anda memerlukan payload kustom, pemrosesan non-percakapan, atau protokol streaming yang tidak kompatibel dengan OpenAI.

Dengan protokol Pemanggilan di C#, Anda menerapkan kustom InvocationHandler untuk memproses permintaan masuk:

using Azure.AI.AgentServer.Core;
using Azure.AI.AgentServer.Invocations;
using Microsoft.Agents.AI;

var builder = AgentHost.CreateBuilder(args);

builder.Services.AddSingleton<AIAgent, MyAgent>();
builder.Services.AddInvocationsServer();
builder.Services.AddScoped<InvocationHandler, MyInvocationHandler>();

builder.RegisterProtocol("invocations", endpoints => endpoints.MapInvocationsServer());

var app = builder.Build();
app.Run();

Metode ini AddInvocationsServer mendaftarkan layanan protokol Invokasi. Anda menerapkan InvocationHandler untuk menentukan bagaimana agen Anda memproses setiap permintaan.

Untuk pengaturan ringan, gunakan InvocationsHostServer dari agent_framework_foundry_hosting paket. Ini membungkus agen Anda yang mirip dengan ResponsesHostServer dan menangani manajemen sesi secara otomatis:

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import InvocationsHostServer
from azure.identity import DefaultAzureCredential

client = FoundryChatClient(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    model=os.environ.get("FOUNDRY_MODEL") or os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
    credential=DefaultAzureCredential(),
)

agent = Agent(
    client=client,
    instructions="You are a friendly assistant. Keep your answers brief.",
    default_options={"store": False},
)

server = InvocationsHostServer(agent)
server.run()

InvocationsHostServer menerima instance yang sama atau bentuk factory dengan cakupan permintaan seperti yang dijelaskan untuk host Responses. Ini memulihkan sesi yang diserialkan dari penyimpanan yang telah dikonfigurasi, sehingga percakapan yang telah selesai dapat dilanjutkan setelah host dimulai ulang. Untuk perilaku penyimpanan, retensi, dan kustomisasi, lihat Mempertahankan status dan menangani percakapan yang berjalan lama.

Saat di-host, Invocations menggunakan cakupan permintaan yang terverifikasi sebagaimana dijelaskan dalam Mempertahankan status dan menangani percakapan yang berjalan lama. Perlakukan AgentSession.session_id sebagai satu nilai buram; jangan mengurai atau bergantung pada representasi internalnya. Proses yang berjalan secara lokal tetap menggunakan perilaku penyimpanan untuk satu pengguna yang sudah ada.

Menjalankan alur kerja native dengan Invocations

Berikan workflow= dan callback eksplisit parse_request untuk menghosting alur kerja asli. Callback memiliki skema JSON aplikasi dan mengembalikan WorkflowTurn dengan input bertipe atau batch lengkap dari balasan yang tertunda:

from pydantic import BaseModel
from starlette.requests import Request

from agent_framework_foundry_hosting import (
    CheckpointStoreProvider,
    InvocationsHostServer,
    WorkflowTurn,
)


class Ticket(BaseModel):
    ticket_id: str
    question: str


class TicketDecision(BaseModel):
    approved: bool


def build_workflow(_request: Request):
    return build_fresh_workflow()


async def parse_request(request: Request) -> WorkflowTurn[Ticket]:
    payload = await request.json()
    stream = payload.get("stream", False)

    if "responses" in payload:
        decisions = {
            request_id: TicketDecision.model_validate(value)
            for request_id, value in payload["responses"].items()
        }
        return WorkflowTurn(responses=decisions, stream=stream)

    ticket = Ticket.model_validate(payload)
    return WorkflowTurn(input=ticket, stream=stream)


server = InvocationsHostServer(
    workflow=build_workflow,
    parse_request=parse_request,
    checkpoint_store_provider=CheckpointStoreProvider(
        allowed_checkpoint_types=[
            f"{Ticket.__module__}:{Ticket.__qualname__}",
            f"{TicketDecision.__module__}:{TicketDecision.__qualname__}",
        ],
    ),
)

Sertakan setiap jenis aplikasi kustom yang disimpan oleh alur kerja dalam daftar allowed_checkpoint_types milik penyedia checkpoint.

Alur kerja yang dihosting memerlukan factory yang memahami konteks request dan mengembalikan graf yang baru dibangun dengan ID alur kerja dan eksekutor yang stabil. Workflow yang dibuat langsung hanya tersedia untuk eksekusi lokal sekali jalan yang tidak dijeda.

Respons alur kerja non-streaming menggunakan JSON aplikasi dengan output daftar peristiwa. Streaming memancarkan peristiwa output dan request_info berbingkai, diikuti done hanya setelah kursor alur kerja yang tepat disimpan. Perlakukan output yang dialirkan sebagai bersifat sementara hingga done. Alur kerja asli tidak mendukung legacy_wire_format=True.

Host memvalidasi respons terhadap checkpoint tertunda yang tepat di lingkup pengguna tepercaya dan kotak pasir. Jika workflow memiliki beberapa permintaan yang tertunda, tanggapi seluruh batch dalam satu kali respons. Untuk pengurai yang dapat dijalankan, alur kerja tiket bertipe, daftar yang diizinkan untuk jenis checkpoint, dan contoh JSON/SSE, lihat contoh alur kerja native Invocations.

Menyesuaikan permintaan dan respons invokasi

Secara default, POST /invocations menerima objek JSON dengan string message, objek opsional options , dan nilai Boolean stream opsional. Untuk menerima payload khusus aplikasi, lewati panggilan balik sinkron atau asinkron parse_request yang mengembalikan InvocationRun(messages, options, stream). Gunakan prepare_options untuk memfilter atau mengganti salinan opsi pembuatan caller sebelum agen dijalankan.

Host memvalidasi keluaran hook dan menolak kontrol identitas platform, penyimpanan, kelanjutan, dan eksekusi agen. Untuk agen yang tidak menerima opsi runtime, atur unsupported_options ke "warn" (default), "ignore", atau "error". Lihat contoh parser Invocations untuk implementasi lengkap.

Permintaan non-streaming yang berhasil akan mengembalikan JSON dalam bentuk {"response": "..."}. Streaming menggunakan event yang dikirim server: satu atau beberapa frame event: delta, diikuti oleh event: done saat berhasil atau event: error saat gagal. Aliran dapat menghasilkan delta sebelum terjadi kesalahan, sehingga klien harus menganggap done, bukan delta, sebagai tanda bahwa proses telah selesai dengan sukses. Host memancarkan done hanya setelah menyelesaikan aliran respons dan mempertahankan AgentSession. session_id-nya adalah ID rute sandbox platform, bukan AgentSession.session_id yang diserialisasikan.

Setel legacy_wire_format=True hanya saat memigrasikan klien yang sudah ada yang memerlukan respons teks biasa sebelumnya dan stream potongan teks mentah. Mode kompatibilitas ini tidak digunakan lagi dan tidak mengonversi kegagalan menjadi teks yang berhasil. Host menserialisasikan permintaan sesi yang sama hanya dalam satu proses; konflik perbandingan dan pertukaran lintas proses masih dapat terjadi setelah efek alat eksternal.

Protokol Invocation tidak melanjutkan kembali eksekusi workflow yang tertunda atau terinterupsi. Gunakan pola handler kustom di bagian berikut saat Anda memerlukan perilaku kelanjutan alur kerja yang berbeda.

Untuk kontrol penuh atas penanganan permintaan, gunakan InvocationAgentServerHost dari azure.ai.agentserver.invocations paket secara langsung dan terapkan handler pemanggil Anda sendiri:

import os
from collections.abc import AsyncGenerator

from agent_framework import Agent, AgentSession
from agent_framework.foundry import FoundryChatClient
from azure.ai.agentserver.invocations import InvocationAgentServerHost
from azure.identity import DefaultAzureCredential
from starlette.requests import Request
from starlette.responses import JSONResponse, Response, StreamingResponse

_sessions: dict[str, AgentSession] = {}

client = FoundryChatClient(
    project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
    model=os.environ.get("FOUNDRY_MODEL") or os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
    credential=DefaultAzureCredential(),
)

agent = Agent(
    client=client,
    instructions="You are a friendly assistant. Keep your answers brief.",
    default_options={"store": False},
)

app = InvocationAgentServerHost()


@app.invoke_handler
async def handle_invoke(request: Request):
    """Handle streaming multi-turn chat."""
    data = await request.json()
    session_id = request.state.session_id
    stream = data.get("stream", False)
    user_message = data.get("message", None)

    if user_message is None:
        return Response(content="Missing 'message' in request", status_code=400)

    session = _sessions.setdefault(session_id, AgentSession(session_id=session_id))

    if stream:

        async def stream_response() -> AsyncGenerator[str]:
            async for update in agent.run(user_message, session=session, stream=True):
                yield update.text

        return StreamingResponse(
            stream_response(),
            media_type="text/event-stream",
            headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
        )

    response = await agent.run([user_message], session=session, stream=stream)
    return JSONResponse({"response": response.text})


if __name__ == "__main__":
    app.run()

Warning

Penyimpanan sesi dalam memori dalam contoh handler kustom hilang saat menghidupkan ulang. Gunakan penyimpanan tahan lama (misalnya, Cosmos DB) dalam produksi.

Untuk deployment Invocations yang lengkap, lihat contoh Telegram yang dihosting di Foundry. Ini menempatkan API Management di depan webhook agen yang dihosting dan menggunakan identitas terkelola, Key Vault, dan Cosmos DB untuk riwayat percakapan yang tahan lama.

Nota

Dukungan Go untuk agen yang dihosting Foundry akan segera hadir. Lihat repositori Agent Framework Go untuk status terbaru.

Tip

Lihat sampel Python atau sampel C# untuk contoh proyek agen yang dihosting. Atau gunakan perintah azd ai agent init untuk menginisiasi sebuah proyek agen baru yang di-host dari awal. Lihat panduan mulai cepat ini untuk instruksi langkah demi langkah.

Beroperasi secara lokal

Azure Developer CLI (azd) menyediakan cara term mudah untuk menjalankan dan menguji agen yang dihosting secara lokal.

Menginisialisasi proyek

Buat folder baru dan inisialisasi dari manifes sampel:

mkdir my-hosted-agent && cd my-hosted-agent
azd ai agent init -m <path-to-agent.manifest.yaml>

Tip

Manifes dapat menjadi jalur ke file YAML lokal atau URL ke manifes jarak jauh.

Mengatur variabel lingkungan

export FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
export FOUNDRY_MODEL="<your-model-deployment>"

Jalankan host agen

azd ai agent run

Host agen dimulai pada http://localhost:8088.

Memanggil agen

azd ai agent invoke --local "Hello!"

Atau gunakan curl:

curl -X POST http://localhost:8088/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!"}'

Atau di PowerShell:

(Invoke-WebRequest -Uri http://localhost:8088/responses -Method POST -ContentType "application/json" -Body '{"input": "Hello!"}').Content

Menyebarkan ke Foundry

Setelah Anda memverifikasi agen Anda secara lokal, sebarkan ke Microsoft Foundry:

  1. Memprovisikan sumber daya (jika Anda belum memiliki proyek Foundry):

    azd provision
    

    Ini membuat grup sumber daya dengan instans Foundry, proyek, penyebaran model, Application Insights, dan registri kontainer.

  2. Sebarkan agen:

    azd deploy
    

    Ini mengemas agen Anda sebagai image kontainer, mengunggahnya ke Azure Container Registry, dan mendeploykannya ke Foundry Agent Service.

Infrastruktur hosting Foundry secara otomatis menyuntikkan variabel lingkungan berikut ke dalam kontainer agen Anda saat runtime:

Variable Deskripsi
FOUNDRY_PROJECT_ENDPOINT URL titik akhir untuk proyek Foundry.
AZURE_AI_MODEL_DEPLOYMENT_NAME Nama penyebaran model yang dikelola azd yang dikonfigurasi selama azd ai agent init. Kode Python dapat lebih memilih FOUNDRY_MODEL secara lokal dan beralih ke nilai yang dihosting ini sebagai cadangan.
APPLICATIONINSIGHTS_CONNECTION_STRING String koneksi dari Application Insights untuk telemetri.

Setelah ditempatkan, agen Anda dapat diakses melalui titik akhir yang khusus di Foundry dan juga dapat diuji dari portal Foundry.

Langkah berikutnya