AI
Microsoft Agent Framework 1.0: Panduan Migrasi Semantic Kernel
Oktober 202613 menit baca

Belum. Microsoft berkomitmen tetap memperbaiki bug kritis dan masalah keamanan di Semantic Kernel v1.x setidaknya satu tahun setelah Agent Framework berstatus generally available pada 2 April 2026. Sebagian besar fitur baru, termasuk agent harness dan CodeAct, kini dibangun untuk Agent Framework.
Tidak ada pengganti langsung; Kernel memang dihilangkan. Agent dibuat dari chat client dengan AsAIAgent di C# atau Agent dan as_agent di Python, dan tool diberikan saat agent dibuat. Tipe pesan dan konten berasal dari Microsoft.Extensions.AI.
Di Python bisa: semantic-kernel 1.38 ke atas menambahkan method as_agent_framework_tool yang mengubah KernelFunction, termasuk fungsi berbasis prompt dan pencarian vector, menjadi tool Agent Framework. Di C#, cara yang umum adalah memberikan method yang sama ke AIFunctionFactory.Create dan membuang attribute KernelFunction. Dengan cara mana pun, tool bisa dipindahkan satu per satu.
AsHarnessAgent di .NET dan create_harness_agent di Python secara default menyusun function invocation, penyimpanan history per pemanggilan, todo tracking, mode plan dan execute, file memory, middleware tool approval, dan OpenTelemetry. Context compaction juga tersedia, tetapi baru aktif jika batas token atau strategi kustom diberikan. Setiap kemampuan punya flag opt-out sendiri.
Masih pre-release. Paket Python agent-framework-hyperlight diumumkan sebagai alpha dan disebut beta di dokumentasi, serta butuh Linux dengan KVM atau Windows dengan WHP. Paket .NET-nya masih preview dan belum bisa restore sampai dependensi sandbox-nya tersedia di nuget.org, jadi anggap klaim penghematan latency 52% dan token 64% dari Microsoft sebagai alasan untuk menguji workload Anda sendiri.

Ringkasan Utama
Migrasi dari Semantic Kernel ke Microsoft Agent Framework menghapus Kernel: agent dibuat lewat chatClient.AsAIAgent, tool lewat AIFunctionFactory.Create atau fungsi Python biasa, thread menjadi session yang dibuat agent, dan InvokeAsync menjadi RunAsync. Semantic Kernel tetap menerima perbaikan bug kritis dan keamanan setidaknya setahun setelah GA April 2026, jadi pindahkan tool lebih dulu, baru agent.
Bayangkan sebuah distributor di Jakarta yang add-on ERP-nya menjawab pertanyaan stok lewat ChatCompletionAgent dari Semantic Kernel. Semuanya berjalan. Lalu Microsoft merilis Agent Framework 1.0 pada 2 April 2026, menyebutnya sebagai penyatuan AutoGen dan Semantic Kernel menjadi satu platform yang didukung, dan semua sample baru, agent harness, serta sandbox CodeAct hadir di sana, bukan di Semantic Kernel. Pertanyaan bagi tim itu bukan lagi apakah perlu migrasi, melainkan berapa banyak kode yang bisa dipertahankan dan dengan urutan apa memindahkannya.
Tulisan ini menjawab keduanya berdasarkan panduan migrasi resmi dari Semantic Kernel dan AutoGen, dokumentasi harness dan tool approval, serta pengumuman BUILD 2026. Isinya memetakan setiap konsep Semantic Kernel ke penggantinya di Agent Framework, menunjukkan kode C# dan Python sebelum dan sesudah, lalu membahas tiga hal dari BUILD yang tidak pernah dimiliki agent Semantic Kernel buatan sendiri: context compaction, standing tool approval, dan tracing OpenTelemetry bawaan.
Agent Framework dibangun oleh tim yang sama dengan Semantic Kernel dan AutoGen, dan diposisikan sebagai penerus langsung keduanya. Framework ini mengambil abstraksi agent yang sederhana dari AutoGen dan bagian enterprise dari Semantic Kernel, yaitu session, type safety, middleware, dan telemetry, lalu menambahkan workflow berbasis graph untuk orkestrasi multi-agent yang eksplisit. Tersedia untuk .NET dan Python, dengan Go dalam public preview. Rilis 1.0 tanggal 2 April 2026 adalah versi yang disebut Microsoft production-ready dengan API yang stabil.
Semantic Kernel tidak langsung dimatikan. Pada Oktober 2025 Microsoft berkomitmen tetap mendukung Semantic Kernel v1.x, memperbaiki bug kritis dan masalah keamanan, setidaknya satu tahun setelah Agent Framework berstatus generally available, sehingga batas paling awal periode itu jatuh pada April 2027. Tulisan yang sama juga tegas bahwa sebagian besar fitur baru akan dibangun untuk Agent Framework. Jadi agent Semantic Kernel yang sudah berjalan bukan keadaan darurat, tetapi setiap bulan agent itu tetap di sana adalah sebulan tanpa harness, model approval yang baru, dan CodeAct. Karena itu migrasi bertahap per tool lebih masuk akal daripada menulis ulang semuanya atau membekukannya.
Perubahan terbesar adalah hilangnya Kernel. Di Semantic Kernel setiap agent bergantung pada sebuah instance Kernel, dan di Kernel itulah plugin, service, dan setting disimpan. Di Agent Framework, agent membungkus chat client secara langsung, tool diberikan saat agent dibuat, dan tipe pesan berasal dari Microsoft.Extensions.AI. Hampir semua baris lain di tabel ini adalah akibat dari satu keputusan tersebut.
| Aspek | Semantic Kernel | Agent Framework | Yang sering menjebak |
|---|---|---|---|
| Paket | Microsoft.SemanticKernel dan Microsoft.SemanticKernel.Agents; pip semantic-kernel | Microsoft.Agents.AI ditambah tipe dari Microsoft.Extensions.AI; pip agent-framework, di-import sebagai agent_framework | Meta package Python ikut memasang beberapa provider. Setelah tahu provider yang dipakai, pasang agent-framework-core dan paket provider yang benar-benar dibutuhkan saja. |
| Membuat agent | Sebuah Kernel ditambah ChatCompletionAgent, OpenAIAssistantAgent, atau AzureAIAgent | chatClient.AsAIAgent yang mengembalikan AIAgent; satu ChatClientAgent untuk IChatClient apa pun; di Python Agent(client=...) atau client.as_agent() | Tiga class agent khusus per service dilebur menjadi satu. Kode yang bercabang berdasarkan tipe agent tidak punya apa-apa lagi untuk dicabangkan. |
| State percakapan | Pemanggil memilih subclass AgentThread: ChatHistoryAgentThread, OpenAIResponseAgentThread, AzureAIAgentThread | agent.CreateSessionAsync atau agent.create_session mengembalikan AgentSession | AgentSession tidak punya method delete. Jika history yang di-host harus dihapus, simpan sendiri conversation ID dari provider. |
| Tool | Attribute KernelFunction, sebuah KernelPlugin, dan kernel.Plugins.Add | AIFunctionFactory.Create pada method biasa, atau fungsi Python biasa, diberikan lewat tools | Konsep plugin tidak ada lagi. Kelompokkan fungsi terkait dalam satu class jika mau, lalu berikan bound method-nya. |
| Menjalankan | InvokeAsync mengembalikan async stream berisi AgentResponseItem | RunAsync atau run mengembalikan satu AgentResponse dengan Text dan Messages | Loop yang menelusuri item untuk mencari jawaban akhir sebaiknya membaca response.Text; tool call dan hasilnya ada di Messages. |
| Streaming | InvokeStreamingAsync, invoke_stream | RunStreamingAsync yang mengembalikan AgentResponseUpdate; di Python run dengan stream=True | Python tidak lagi punya method streaming terpisah, hanya flag. |
| Opsi model | OpenAIPromptExecutionSettings yang dibungkus KernelArguments | ChatClientAgentRunOptions di atas ChatOptions; di Python TypedDict lewat options atau default_options | MaxTokens menjadi MaxOutputTokens, dan ChatClientAgentRunOptions hanya berlaku untuk ChatClientAgent. |
| Dependency injection | services.AddKernel, lalu Kernel di-inject ke setiap agent | Daftarkan AIAgent itu sendiri, misalnya sebagai keyed singleton | Registrasi Kernel bisa dihapus setelah tidak ada lagi kode Semantic Kernel yang me-resolve-nya. |
Baca tabel ini sebagai urutan dependensi. Tool tidak bergantung pada tipe agent, jadi tool dipindahkan lebih dulu. Pembuatan agent dan session dipindahkan bersamaan, karena session dimiliki oleh agent yang membuatnya. Opsi dan dependency injection menyusul terakhir dan sebagian besar hanya search and replace.
Berikut agent pencarian stok yang ditulis dengan gaya Semantic Kernel, dibuat semirip mungkin dengan pola di panduan resmi. Hitung objek yang ada hanya untuk membawa satu fungsi dan satu percakapan: KernelFunction, KernelPlugin, Kernel, setting yang dibungkus KernelArguments, dan class thread yang harus dicocokkan pemanggil dengan provider-nya.
// Before: Semantic Kernel
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
KernelFunction onHand = KernelFunctionFactory.CreateFromMethod(InventoryPlugin.GetOnHand);
KernelPlugin plugin = KernelPluginFactory.CreateFromFunctions("Inventory", [onHand]);
Kernel kernel = BuildKernel(); // every SK agent needs one
kernel.Plugins.Add(plugin);
OpenAIPromptExecutionSettings settings = new() { MaxTokens = 1000 };
AgentInvokeOptions options = new() { KernelArguments = new(settings) };
ChatCompletionAgent agent = new() { Instructions = StockInstructions, Kernel = kernel };
// The caller has to know which thread class matches the provider.
AgentThread thread = new OpenAIResponseAgentThread(responsesClient);
await foreach (AgentResponseItem<ChatMessageContent> item
in agent.InvokeAsync(question, thread, options))
{
Console.WriteLine(item.Message);
}
public class InventoryPlugin
{
[KernelFunction] // required, or the model never sees it
public static int GetOnHand(string itemCode, string warehouseCode) => /* ERP query */ 0;
}Versi Agent Framework mempertahankan chat client dan method yang sama. AsAIAgent mendaftarkan tool dalam pemanggilan yang sama dengan pembuatan agent, attribute Description menggantikan KernelFunction dan sifatnya opsional, dan agent sendiri yang menentukan tipe session yang dibutuhkan provider-nya.
// After: Microsoft Agent Framework
using System.ComponentModel;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
// chatClient is any IChatClient: Azure OpenAI, OpenAI, Foundry, Ollama...
AIAgent agent = chatClient.AsAIAgent(
instructions: StockInstructions,
tools: [AIFunctionFactory.Create(GetOnHand)]);
// The agent creates the right session type for its provider.
AgentSession session = await agent.CreateSessionAsync();
// MaxTokens is now MaxOutputTokens, on ChatOptions.
ChatClientAgentRunOptions options = new(new() { MaxOutputTokens = 1000 });
// One AgentResponse instead of an async stream of items.
AgentResponse response = await agent.RunAsync(question, session, options);
Console.WriteLine(response.Text); // tool calls and results are in response.Messages
[Description("On-hand quantity for an item code in one warehouse.")] // optional
static int GetOnHand(string itemCode, string warehouseCode) => /* ERP query */ 0;Perbedaan perilaku yang perlu diuji adalah bentuk hasilnya. InvokeAsync menghasilkan beberapa item dan kebanyakan kode Semantic Kernel mencetak satu per satu; RunAsync mengembalikan satu AgentResponse yang daftar Messages-nya memuat tool call, hasil fungsi, reasoning update, dan jawaban akhir sekaligus. Kode yang mencatat setiap item untuk audit trail kini harus menelusuri response.Messages, atau diam-diam hanya mencatat teks akhirnya.
Jangan memindahkan cleanup hosted thread baris demi baris. Thread Semantic Kernel punya method delete; AgentSession tidak, karena tidak semua provider mendukung hosted history atau penghapusannya. Jika kebijakan retensi mewajibkan percakapan dihapus, catat conversation ID milik session saat dibuat lalu hapus lewat SDK provider itu sendiri.
Di sisi Python yang berubah sama saja, dengan satu jalan keluar yang berguna. Sejak semantic-kernel 1.38, sebuah KernelFunction punya method as_agent_framework_tool yang mengubahnya menjadi tool Agent Framework, termasuk fungsi yang dibangun dari prompt template dan fungsi pencarian vector store. Dengan begitu tim bisa memindahkan agent lebih dulu dan memindahkan tool satu per satu, satu pull request setiap kali.
# pip install agent-framework (imported as agent_framework)
from typing import Annotated
from agent_framework import tool
from agent_framework.openai import OpenAIChatClient
from semantic_kernel.functions import kernel_function # still installed during the move
# Ported: a plain function. Name -> tool name, docstring -> description.
@tool(approval_mode="never_require") # read-only lookup, safe to auto-run
def get_on_hand(
item_code: Annotated[str, "ERP item code, e.g. BRG-00412"],
warehouse_code: Annotated[str, "Warehouse code, e.g. SBY-01"],
) -> int:
"""On-hand quantity for an item code in one warehouse."""
...
# Not ported yet: the existing Semantic Kernel function, bridged.
# Needs semantic-kernel 1.38 or later.
@kernel_function(name="reorder_hint", description="Suggest a reorder quantity from min/max policy")
def reorder_hint(item_code: str) -> str:
...
reorder_tool = reorder_hint.as_agent_framework_tool()
agent = OpenAIChatClient().as_agent(
instructions="Answer stock questions for the Surabaya warehouse.",
tools=[get_on_hand, reorder_tool],
default_options={"max_tokens": 1000}, # was OpenAIPromptExecutionSettings + KernelArguments
)
session = agent.create_session() # was ChatHistoryAgentThread()
response = await agent.run(question, session=session, options={"max_tokens": 500})
print(response.text)
# Streaming is a flag on run(), not a separate invoke_stream() method.
async for update in agent.run(question, session=session, stream=True):
print(update.text, end="")Dua detail di kode itu disengaja. Fungsi biasa menjadi tool yang namanya diambil dari nama fungsi dan deskripsinya dari docstring, jadi docstring yang samar kini menjadi deskripsi tool yang samar pula bagi model. Selain itu opsi pindah ke typed dictionary: default_options saat pembuatan, options per pemanggilan, sementara tools dan instructions tetap sebagai keyword argument biasa.
Pengguna AutoGen menghadapi perubahan konsep yang lebih besar daripada pengguna Semantic Kernel, karena yang berubah adalah model orkestrasinya, bukan sekadar nama. AutoGen memadukan core berbasis event dengan Team tingkat tinggi; Agent Framework berpusat pada Workflow berbasis graph yang bertipe, yang mengalirkan data lewat edge dan mengaktifkan executor ketika input-nya siap. Pemetaan yang paling penting:
Satu batasan yang perlu direncanakan: AutoGen menyediakan runtime embedded dan runtime terdistribusi yang masih eksperimental, sedangkan panduan AutoGen menyebut Agent Framework saat ini berfokus pada komposisi dalam satu proses, dengan eksekusi terdistribusi masih dalam rencana. Sistem yang bergantung pada runtime terdistribusi AutoGen sebaiknya tidak berada di urutan pertama migrasi.
Harness adalah bagian Agent Framework yang sebelumnya harus dibangun sendiri oleh tim Semantic Kernel. AsHarnessAgent di .NET, dari paket Microsoft.Agents.AI.Harness, dan create_harness_agent di Python mengembalikan agent biasa dengan pipeline yang sudah tersusun: function invocation dengan batas iterasi, history yang disimpan setelah setiap pemanggilan model, todo tracking, mode plan dan execute, file memory per session, middleware tool approval, dan instrumentasi OpenTelemetry. Di sini harness menjalankan rekonsiliasi stock opname: pencarian data berjalan bebas, tetapi penyesuaian stok menunggu persetujuan supervisor.
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
// Lookups run freely. Anything that writes to the ledger waits for a person.
AIFunction onHand = AIFunctionFactory.Create(GetOnHand);
AIFunction postAdjustment = new ApprovalRequiredAIFunction(
AIFunctionFactory.Create(PostStockAdjustment));
AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
Name = "stock-reconciler",
HarnessInstructions = "Use tools deliberately and report verified results.",
ChatOptions = new ChatOptions
{
Instructions = "Reconcile cycle-count sheets against ERP on-hand quantities.",
Tools = [onHand, postAdjustment],
},
// Compaction only switches on when the harness has a budget to work against.
MaxContextWindowTokens = 128_000,
MaxOutputTokens = 16_384,
// Web search is added by default where the client supports it.
// An internal ERP agent has no reason to browse.
DisableWebSearch = true,
});
AgentSession session = await agent.CreateSessionAsync();
AgentResponse response = await agent.RunAsync(countSheetSummary, session);
// A posting attempt comes back as a request, not as a result.
List<ToolApprovalRequestContent> pending = Pending(response);
while (pending.Count > 0)
{
List<AIContent> answers = [];
foreach (ToolApprovalRequestContent request in pending)
{
var call = (FunctionCallContent)request.ToolCall;
bool approved = await AskSupervisorAsync(call.Name, call.Arguments);
answers.Add(request.CreateResponse(approved));
}
// Same session: approval responses are bound to the requests recorded in it.
response = await agent.RunAsync(new ChatMessage(ChatRole.User, answers), session);
pending = Pending(response);
}
static List<ToolApprovalRequestContent> Pending(AgentResponse r) =>
r.Messages.SelectMany(m => m.Contents).OfType<ToolApprovalRequestContent>().ToList();Ada tiga perilaku di kode itu yang mudah keliru. Compaction, fitur yang meringkas chat history di tengah loop agar tool loop yang panjang tidak melampaui context window, hanya aktif jika batas token atau strategi kustom diberikan, jadi harness tanpa MaxContextWindowTokens tidak melakukan compaction. Web search ditambahkan secara default di mana pun chat client mendukungnya, karena itu contohnya mematikan fitur tersebut. Dan loop approval harus memakai session yang sama, karena respons approval terikat pada request yang tercatat di session itu; approval palsu atau hasil replay yang tidak cocok dengan request mana pun akan diabaikan.
Lapisan approval punya dua bagian yang dipisahkan dalam dokumentasi. ApprovalRequiredAIFunction di .NET, atau approval_mode bernilai always_require di Python, menandai tool yang butuh persetujuan. Harness lalu menambahkan middleware ToolApprovalAgent di atasnya, yang mengantrekan beberapa request, mengingat standing approval dari jawaban sebelumnya, dan bisa menerapkan aturan auto-approval yang Anda berikan. Mengaktifkan DisableToolAutoApproval hanya menghapus middleware tersebut; kewajiban approval pada tool yang sudah dibungkus tidak pernah ikut hilang.
Setiap kemampuan harness punya opt-out sendiri, jadi pangkas alih-alih menerima semuanya. Di .NET pilihannya antara lain DisableWebSearch, DisableFileMemory, DisableTodoProvider, DisableAgentModeProvider, DisableAgentSkillsProvider, DisableOpenTelemetry, dan DisableCompaction; Python punya disable_web_search, disable_file_memory, disable_todo, disable_mode, dan disable_compaction. Agent back-office ERP jarang butuh web search atau skills, tetapi hampir selalu perlu tracing tetap menyala.
CodeAct mengubah loop tool calling itu sendiri. Alih-alih rantai model, tool, model, tool, model menulis satu program Python pendek yang memanggil tool lewat call_tool, dan program itu berjalan di micro-VM Hyperlight yang baru dan terisolasi. Benchmark BUILD dari Microsoft pada workload multi-langkah turun dari 27,81 detik dan 6.890 token dengan tool call biasa menjadi 13,23 detik dan 2.489 token dengan CodeAct, yaitu penurunan latency 52,4% dan token 63,9% yang dilaporkan. Anggap itu satu workload yang diuji vendor, bukan janji; dokumentasinya sendiri menyarankan mengukur kedua mode pada tugas Anda sendiri.
# pip install agent-framework-hyperlight --pre
# Needs x86-64 Linux with KVM or AMD64 Windows with WHP, Python 3.10 to 3.14.
from agent_framework import Agent, tool
from agent_framework.hyperlight import HyperlightCodeActProvider
@tool
def get_stock_card(item_code: str, month: str) -> list[dict]:
"""Every stock movement for one item in one month (read-only)."""
...
@tool
def get_standard_cost(item_code: str) -> float:
"""Current standard cost of an item (read-only)."""
...
@tool(approval_mode="always_require")
def post_revaluation(item_code: str, new_cost: float) -> str:
"""Post a cost revaluation journal. Changes the books."""
...
codeact = HyperlightCodeActProvider(
# Hidden from the model as direct tools; reachable only via call_tool(...)
# inside one execute_code program. These still run in the HOST process.
tools=[get_stock_card, get_standard_cost],
approval_mode="never_require",
)
agent = Agent(
client=client,
name="CostAnalyst",
instructions=(
"To analyse many items, write one program that uses call_tool(...) "
"and end it with print(...). Never revalue without asking."
),
tools=[post_revaluation], # stays a first-class tool, approved per call
context_providers=[codeact],
)Pembagian di contoh itu mengikuti rule of thumb yang terdokumentasi. Tool yang murah, deterministik, dan read-only diletakkan di provider, sehingga model bisa merangkai puluhan pemanggilan dalam satu giliran execute_code; persis bentuk analisis kartu stok akhir bulan. Tool revaluasi tetap menjadi tool langsung dengan approval_mode always_require, karena approval di CodeAct berlaku untuk seluruh pemanggilan execute_code, bukan untuk setiap call_tool di dalamnya.
CodeAct masih pre-release dan cakupannya lebih sempit dari kesan pertama. Paket Python agent-framework-hyperlight diumumkan sebagai alpha dan kini disebut beta di dokumentasi; paket ini butuh Linux x86-64 dengan KVM atau Windows AMD64 dengan WHP, serta Python 3.10 sampai 3.14. Paket .NET-nya masih preview dan, menurut dokumentasi, gagal restore sampai dependensi Hyperlight.HyperlightSandbox.Api dipublikasikan ke nuget.org. Selain itu sandbox tidak membungkus tool Anda: call_tool adalah jembatan kembali ke proses host, jadi tool yang didaftarkan di provider berjalan dengan credential dan jaringan milik host.
Banyak perusahaan Indonesia sudah berjalan di atas stack Microsoft, dan region Azure Indonesia Central di Jakarta memudahkan resource pendukungnya tetap berada di dalam negeri. Bagi tim seperti itu, urutan yang menjaga sistem tetap bisa dirilis di setiap langkah kira-kira seperti ini:
Urutan ini penting karena setiap langkah bisa diuji secara terpisah. Tool yang dipindahkan di langkah kedua mengembalikan baris yang sama ke agent Semantic Kernel lama maupun agent baru, sehingga ketidakcocokan tertangkap sebelum agent-nya berubah, bukan sesudahnya.
Pindah dari Semantic Kernel ke Microsoft Agent Framework sebagian besar adalah soal menghapus: Kernel, pembungkus plugin, dan class thread hilang, sementara chat client, method, dan modelnya tetap. Aturan yang perlu dibawa: pindahkan tool sebelum agent, tandai setiap side effect untuk approval sebelum harness menyentuhnya, dan perlakukan angka utama CodeAct sebagai alasan untuk mengukur, bukan sebagai hasil.
Sumber dan bacaan lanjutan