· AI & Automation · 14 min read
AI työkalut osa 3 - Semantic Kernel: AI-Agentit .NET:llä
Hallitse Microsoft Semantic Kernel tuotantovalmiiden AI-agenttien rakentamiseen. Opi moniagenttiorkestrointia, MCP-integraatiota, vektorivarastoja ja yritysratkaisuja aidoilla C# koodiesimerkeillä.
Kuinka Semantic Kernel Auttaa Rakentamaan Moniagentti AI-Järjestelmiä .NET:llä
Tämä artikkeli on osa 5-osaista sarjaamme AI-Agentti- ja Työnkulkutyökaluista, jossa tutkimme johtavia alustoja ja kehyksiä tuotantovalmiiden AI-ratkaisujen rakentamiseen.
📚 Sarja: Työkalut Joita Käytämme AI-Kehityksessä
- Azure AI Foundry - Kuinka Azure AI Foundry auttaa rakentamaan turvallisia yritystason AI-ratkaisuja
- LangChain - Kuinka LangChain auttaa rakentamaan tuotantovalmiita AI-agentteja Pythonilla
- Semantic Kernel (tämä artikkeli) - Kuinka Semantic Kernel auttaa rakentamaan moniagentti AI-järjestelmiä .NET:llä
- n8n - Kuinka n8n demokratisoi AI-automaation low-code-työnkuluilla
- Microsoft Agent Framework - Kuinka Microsoft Agent Framework mahdollistaa skaalautuvat moniagenttityönkulut
Mikä on Microsoft Semantic Kernel?
Semantic Kernel on Microsoftin avoimen lähdekoodin AI-orkestrointikehys, joka tekee .NET-kehittäjille helpommaksi ja nopeammaksi rakentaa yritystason AI-ratkaisuja ja älykkäitä agentteja.
Se toimii “aivoina” ja koordinointikerroksena, joka yhdistää suuret kielimallit (kuten GPT-4 ja GPT-5) organisaatiosi järjestelmiin, dataan ja liiketoimintalogiikkaan. Sen todellinen voima piilee tilattomien tekstigenerointimallien muuntamisessa tilallisiksi, päätteleviksi agenteiksi, jotka voivat olla vuorovaikutuksessa olemassa olevan yritysinfrastruktuurisi kanssa.
Semantic Kernel ratkaisee keskeisen ongelman: todennäköisyyspohjaisen AI-päättelyn ja deterministisen liiketoimintalogiikan (SQL-tietokannat, ERP-järjestelmät, REST API:t) välisen kuilun ylittämisen säilyttäen samalla tyyppiturvalli suuden ja idiomaattiset .NET-mallit.
Miksi moniagenttijärjestelmät?
Varhaiset AI-ratkaisut luottivat usein yhteen, monoliittiseen promptiin - niin sanottuun “God Promptiin” - joka yritti hallita jokaista ohjetta, sääntöä ja poikkeusta kerralla. Tämä lähestymistapa hajoaa nopeasti: sitä on vaikea ylläpitää, vaikea debugata, ja se ylittää helposti mallin kontekstirajoitukset.
Moniagenttijärjestelmät (MAS) ratkaisevat tämän jakamalla monimutkaisen työn erikoistuneisiin rooleihin - aivan kuten todellinen tiimi. Yksi agentti suunnittelee tehtävän. Toinen hakee tietoa. Toinen on vuorovaikutuksessa ydinjärjestelmien kanssa. Toinen validoi laatua tai vaatimustenmukaisuutta.
Jakamalla vastuuta moniagentti AI-järjestelmät tarjoavat:
- Korkeamman luotettavuuden - agentit tarkistavat ja tasapainottavat toisiaan
- Paremman ylläpidettävyyden - jokainen agentti on pienempi, selkeämpi ja helpompi parantaa
- Skaalautuvuuden - useat agentit voivat tehdä yhteistyötä ongelmissa, jotka ovat liian suuria yhdelle mallille
- Vahvemman tarkkuuden ja johdonmukaisuuden - erikoistuminen parantaa tulosteen laatua
- Suuremman mukautuvuuden - agentteja voidaan vaihtaa, päivittää tai käyttää uudelleen eri ratkaisuissa
Semantic Kernel Ydinarkkitehtuuri .NET-Kehittäjille
Kernel on keskusorkestrointiyksikkösi - muuttuva kontekstisäiliö, joka sisältää AI-palvelut, pluginit ja suodattimet. Toisin kuin staattiset clientit, se on suunniteltu lyhytaikaiseen, pyyntökohtaiseen käyttöön.
Kernelin Elinkaaren Hallinta: Miksi Transient-Rekisteröinti on Tärkeä
Kriittinen: Rekisteröi Kernel aina Transient-tyyppisenä riippuvuusinjektiossa. Kernel.Plugins-kokoelma on muuttuva - jos rekisteröit Singletoniksi, plugin-tila vuotaa samanaikaisten käyttäjien välillä (vakava tietoturvahaavoittuvuus).
Yritystason Semantic Kernel Asennus HostApplicationBuilderilla
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
var builder = Host.CreateApplicationBuilder(args);
// 1. Rekisteröi AI-palvelut (Singleton - uudelleenkäytä HTTP-clientit)
// ServiceId mahdollistaa monimaллireitityksen (esim. nopeat vs. tarkat mallit)
builder.Services.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4o",
endpoint: Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!,
apiKey: Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY")!,
serviceId: "gpt4-fast"
);
builder.Services.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4-turbo",
endpoint: Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!,
apiKey: Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY")!,
serviceId: "gpt4-reasoning" // Monimutkaisiin suunnittelutehtäviin
);
// 2. Rekisteröi Kernel (AINA Transient)
builder.Services.AddTransient<Kernel>(sp =>
{
var kBuilder = Kernel.CreateBuilder();
// Propagoi lokitus ja telemetria
kBuilder.Services.AddLogging(l =>
{
l.AddConsole();
l.SetMinimumLevel(LogLevel.Trace); // Näe LLM-päättely kehityksessä
});
// Injektoi AI-palvelut host-kontainerista
kBuilder.Services.AddSingleton(sp.GetRequiredService<IChatCompletionService>());
return kBuilder.Build();
});
using var host = builder.Build();Semantic Kernel Pluginit: Yhdistä AI Liiketoimintalogiikkaan
LLM on “aivot purkissa” - se voi päätellä, mutta ei pääse käsiksi tiedostoihin, tietokantoihin tai API:eihin. Semantic Kernel Pluginit kuromivat tämän kuilun paljastamalla C#-metodit “työkaluina”, joita LLM voi kutsua.
Miten Semantic Kernel Pluginit Toimivat
- Koristelet metodit
[KernelFunction]-attribuutilla - SK käyttää reflektiota luodakseen JSON-skeeman metodistasi
- Tämä skeema lähetetään LLM:lle sen järjestelmäpromptissa
- LLM tulostaa strukturoituja työkalukutsuja (esim.
{"function": "CheckStock", "args": {"sku": "ABC123"}}) - SK sieppaa, suorittaa C#-koodisi ja palauttaa tulokset LLM:lle
Vahvasti Tyypitettyjen Semantic Kernel Pluginien Rakentaminen
Älä koskaan käytä primitiivisiä merkkijonoja monimutkaiseen dataan. Hyödynnä C#-recordeja ja LLM:n strukturoitua päättelyä.
using Microsoft.SemanticKernel;
using System.ComponentModel;
// Määrittele sopimus käyttäen recordeja (muuttumaton, tiivis)
public record OrderRequest(
[Description("Tuotteen SKU-koodi")] string Sku,
[Description("Tilausmäärä (1-1000)")] int Quantity,
[Description("Toimitusprioriteetti: Standard, Express, Overnight")] string Priority = "Standard"
);
// Plugin-luokka DI-tuella
public class ERPPlugin
{
private readonly IErpService _erpService;
private readonly ILogger<ERPPlugin> _logger;
public ERPPlugin(IErpService erpService, ILogger<ERPPlugin> logger)
{
_erpService = erpService;
_logger = logger;
}
[KernelFunction("create_order")]
[Description("Lähetä uusi tilaus ERP-järjestelmään. Palauttaa tilaus-ID:n.")]
public async Task<string> CreateOrderAsync(
[Description("Tilauksen tiedot")] OrderRequest order,
CancellationToken ct = default)
{
_logger.LogInformation("Luodaan tilausta SKU:lle: {Sku}", order.Sku);
// SK takaa, että 'order' on täytetty JSON-skeeman perusteella
var orderId = await _erpService.SubmitAsync(
order.Sku,
order.Quantity,
order.Priority,
ct
);
return $"Tilaus {orderId} luotu onnistuneesti";
}
[KernelFunction("check_inventory")]
[Description("Tarkista tuotteen reaaliaikaiset varastotasot")]
public async Task<int> CheckStockAsync(
[Description("Tuotteen SKU")] string sku,
[Description("Varaston sijaintikoodi")] string location = "MAIN")
{
var stock = await _erpService.GetStockLevel(sku, location);
return stock;
}
}
// Rekisteröi DI:ssä
builder.Services.AddSingleton<IErpService, ErpService>();
builder.Services.AddSingleton<ERPPlugin>();
// Lisää Kerneliin
var plugin = serviceProvider.GetRequiredService<ERPPlugin>();
kernel.Plugins.AddFromObject(plugin, "ERP");Keskeiset edut:
- LLM näkee JSON-skeeman ja “ymmärtää”, että sen on toimitettava
Sku,Quantityja valinnaisestiPriority - Tyyppiturvallisuu: saat vahvasti tyypitetyn
OrderRequest-olion, ei sanakirjaa - Validointi tapahtuu ennen liiketoimintalogiikkasi suorittamista
Model Context Protocol (MCP) Integraatio Semantic Kerneliin
Model Context Protocol (MCP) on avoin standardi, joka eliminoi mukautetun liitinkoodin. Sen sijaan, että kirjoittaisit erilliset Semantic Kernel -pluginit GitHubille, Google Drivelle ja Slackille, muodostat yhteyden olemassa oleviin MCP-palvelimiin, joita toimittajat tarjoavat.
Arkkitehtuuri
- MCP-palvelin: Itsenäinen prosessi (Node.js, Python, Docker), joka paljastaa työkalut MCP-standardin kautta
- MCP-client: .NET-sovelluksesi toimii isäntänä
- Transport: Viestintäkanava (stdio paikallisille, SSE etäisille)
3.1 Ulkoisten MCP-palvelimien käyttäminen
Paketti: Microsoft.SemanticKernel.Plugins.Mcp
using Microsoft.SemanticKernel.Plugins.Mcp;
// Muodosta yhteys GitHub MCP -palvelimeen (vaatii Node.js:n asennuksen)
await using IMcpClient mcpClient = await McpClientFactory.CreateAsync(
new StdioClientTransport(new()
{
Name = "GitHub",
Command = "npx",
Arguments = ["-y", "@modelcontextprotocol/server-github"],
// Välitä halutessasi ympäristömuuttujia
Environment = new()
{
["GITHUB_TOKEN"] = Environment.GetEnvironmentVariable("GITHUB_TOKEN")
}
})
);
// Löydä saatavilla olevat työkalut palvelimelta
var mcpTools = await mcpClient.ListToolsAsync();
Console.WriteLine($"Löydettiin {mcpTools.Tools.Count} työkalua");
// Muunna MCP-työkalut Kernel-funktioiksi (automaattinen skeemamapattaus)
var functions = mcpTools.Tools.Select(tool => tool.AsKernelFunction());
kernel.Plugins.AddFromFunctions("GitHub", functions);
// Agentti voi nyt kutsua: list_issues, create_pull_request, search_code, jne.Polyglot-etu: Python-tiimi rakentaa MCP-palvelimen datatieteellisille työkaluille. C#-agenttisi käyttävät sitä kirjoittamatta logiikkaa uudelleen .NET:iin.
3.2 MCP-palvelimen rakentaminen C#:lla
Paljasta C#-liiketoimintalogiikkasi MCP-palvelimena Claude Desktopille, Python-agenteille tai muille SK-instansseille.
Paketti: ModelContextProtocol
// Program.cs (Console App)
using Microsoft.Extensions.Hosting;
using Microsoft.SemanticKernel;
var builder = Host.CreateApplicationBuilder(args);
// Rekisteröi pluginisi
builder.Services.AddSingleton<ERPPlugin>();
builder.Services.AddSingleton<InventoryPlugin>();
// Lisää MCP-palvelinominaisuus
builder.Services.AddMcpServer()
.WithStdioServerTransport() // stdio paikallisille, SSE HTTP-endpointeille
.WithToolsFromAssembly(typeof(ERPPlugin).Assembly); // Automaattinen [KernelFunction]-löytäminen
var app = builder.Build();
await app.RunAsync(); // Blokkaa ja kuuntelee MCP JSON-RPC-viestejäNyt Claude Desktop tai mikä tahansa MCP-client voi löytää ja kutsua create_order- ja check_inventory-funktioitasi.
Semantic Kernel Agenttikehys: Tyypit ja Käyttötapaukset
Paketti: Microsoft.SemanticKernel.Agents
| Agenttityyppi | Suoritus | Tilan sijainti | Parhaiten |
|---|---|---|---|
| ChatCompletionAgent | .NET in-process | Client-puoli (muisti/DB) | Pieni latenssi, mukautettu historia, ei-OpenAI-mallit |
| OpenAIAssistantAgent | OpenAI API | Palvelinpuoli (OpenAI) | Code Interpreter, File Search, pysyvät säikeet |
| AzureAIAgent | Azure AI Foundry | Palvelinpuoli (Azure) | Yritysturvallisuus, VNET:it, Azure AI Search -integraatio |
4.1 ChatCompletionAgent: .NET-natiivi työjuhta
Tilaton suunnittelultaan - sinä hallitset keskusteluhistoriaa. Toimii minkä tahansa IChatCompletionService:n kanssa (Azure OpenAI, Hugging Face, Ollama).
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Connectors.OpenAI;
// Luo erikoistuneet agentit
ChatCompletionAgent plannerAgent = new()
{
Name = "Planner",
Instructions = """
Olet strateginen suunnittelija. Jaa käyttäjän pyynnöt toiminnallisiin vaiheisiin.
Tulosta numeroitu suunnitelma. ÄLÄ suorita - vain suunnittele.
""",
Kernel = kernel,
Arguments = new KernelArguments(new OpenAIPromptExecutionSettings
{
Temperature = 0.7,
MaxTokens = 500
})
};
ChatCompletionAgent coderAgent = new()
{
Name = "Developer",
Instructions = """
Kirjoitat siistiä, idiomaattista C#-koodia käyttäen dependency injectionia.
Noudata SOLID-periaatteita. Käytä annettua ERP-pluginia tarvittaessa.
""",
Kernel = kernel, // Tällä kernelillä on ERPPlugin rekisteröity
Arguments = new KernelArguments(new OpenAIPromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(), // Ota työkalukutsut käyttöön
Temperature = 0.2 // Alempi deterministiselle koodille
})
};
ChatCompletionAgent reviewerAgent = new()
{
Name = "Reviewer",
Instructions = """
Tarkista Developerin koodi seuraavien osalta:
- Tietoturvahaavoittuvuudet (SQL-injektio, XSS)
- SOLID-periaatteiden rikkomukset
- Puuttuva virheidenkäsittely
Jos kelvollinen, tulosta: APPROVED
Jos ongelmia löytyy, tulosta: REJECTED syineen
""",
Kernel = kernel,
Arguments = new KernelArguments(new OpenAIPromptExecutionSettings
{
Temperature = 0.1 // Hyvin deterministinen tarkistukselle
})
};4.2 AgentGroupChat: moniagenttiorkestraatio
Yhteistyöajoympäristö - hallitsee vuoronvaihtoa, jaettua historiaa ja lopetuslogiikkaa.
using Microsoft.SemanticKernel.Agents.Chat;
// Luo ryhmäkeskustelu valintastrategialla
AgentGroupChat chat = new(plannerAgent, coderAgent, reviewerAgent)
{
ExecutionSettings = new()
{
// Valintastrategia: Kuka puhuu seuraavaksi?
SelectionStrategy = new SequentialSelectionStrategy(),
// Voi käyttää myös KernelFunctionSelectionStrategya dynaamiseen reititykseen
// Lopetusstrategia: milloin lopetetaan?
TerminationStrategy = new RegexTerminationStrategy("APPROVED")
{
Agents = [reviewerAgent], // Vain reviewer voi hyväksyä
MaximumIterations = 15 // Turvaraja
}
}
};
// Alusta keskustelu
chat.AddChatMessage(new ChatMessageContent(
AuthorRole.User,
"Luo OrderService, joka validoi varaston ennen tilausten tekemistä"
));
// Suorita silmukka
await foreach (var message in chat.InvokeAsync())
{
Console.WriteLine($"[{message.AuthorName}] {message.Content}");
// Käsittele striimaus tai artefaktit
if (message.Items.Any(i => i is FileReferenceContent))
{
// Käsittele tiedostotulosteet
}
}
Console.WriteLine($"Keskustelu päättyi {chat.History.Count} viestin jälkeen");4.3 Edistynyt: dynaaminen valintastrategia (ReAct-malli)
Peräkkäisen sijaan käytä LLM:ää reitittämään dynaamisesti kontekstin perusteella.
// Luo reititysfunktio
KernelFunction selectionFunction = AgentGroupChat.CreatePromptFunctionForStrategy(
$$$"""
Analysoi keskustelu ja valitse seuraava puhuva agentti.
Saatavilla olevat agentit:
- Planner: Luo strategisia suunnitelmia, jakaa monimutkaiset tehtävät
- Developer: Kirjoittaa C#-koodia, toteuttaa ratkaisut
- Reviewer: Tarkistaa koodin laadun, hyväksyy tai hylkää
Säännöt:
- Käyttäjän pyynnön jälkeen → Planner
- Suunnitelman jälkeen → Developer
- Koodin jälkeen → Reviewer
- REJECTED-vastauksen jälkeen → Developer (korjaamaan)
- APPROVED-vastauksen jälkeen → DONE
Keskusteluhistoria:
{{$history}}
Tulosta vain agentin nimi.
"""
);
var strategy = new KernelFunctionSelectionStrategy(selectionFunction, kernel)
{
// Varajärjestely, jos LLM tulostaa virheellisen nimen
ResultParser = (result) => result.GetValue<string>() ?? "Planner",
// Historia lähettää reititys-LLM:lle
HistoryVariableName = "history",
HistoryReducer = new ChatHistoryTruncationReducer(10) // Vain viimeiset 10 viestiä
};
chat.ExecutionSettings.SelectionStrategy = strategy;Tämä mahdollistaa Handoff-mallit: jos käyttäjä kysyy laskutuskysymyksen keskellä keskustelua, reititin voi siirtää BillingAgent:lle dynaamisesti.
Azure AI Foundry Integraatio: Yritystason Semantic Kernel Agentit
Paketti: Microsoft.SemanticKernel.Agents.AzureAI
Tuotantoskenaarioille, jotka vaativat Code Interpreteria (turvallinen Python-hiekkalaatikko), File Searchia (RAG) ja Managed Identity -integraatiota.
5.1 Code Interpreter & File Search -esimerkki
using Microsoft.SemanticKernel.Agents.AzureAI;
using Azure.AI.Projects;
using Azure.Identity;
// 1. Luo Azure AI Project Client (käyttää Managed Identitya tuotannossa)
var projectClient = new AIProjectClient(
new Uri(Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT")!),
new DefaultAzureCredential()
);
// 2. Määrittele agentti hallinnoiduilla ominaisuuksilla
var agentDefinition = await AzureAIAgent.CreateAsync(
kernel,
client: projectClient,
definition: new AzureAIAgentDefinition("DataScientist")
{
ModelId = "gpt-4-turbo",
Instructions = """
Olet data-analyytikko. Käytä Pythonia:
- Lataa ja puhdista CSV-data
- Luo tilastollisia yhteenvetoja
- Luo visualisointeja (matplotlib/seaborn)
Selitä aina analyysisi ennen koodin näyttämistä.
""",
// Ota käyttöön hallinnoidut työkalut (Azure isännöi suorituksen)
CodeInterpreter = new AzureAICodeInterpreterToolDefinition(),
FileSearch = new AzureAIFileSearchToolDefinition()
}
);
// 3. Lataa tiedosto analyysiin (tallennetaan Azureen, ei paikalliseen muistiin)
var agentsClient = projectClient.GetAgentsClient();
var fileInfo = await agentsClient.UploadFileAsync(
"sales_data.csv",
AgentFilePurpose.Agents
);
await agentDefinition.AddFileAsync(fileInfo.Id);
// 4. Luo pysyvä säie (tila elää Azuressa)
AgentThread thread = await agentDefinition.CreateThreadAsync();
await agentDefinition.AddChatMessageAsync(
thread,
"Analysoi Q4-myyntitrendit ja luo kuukausittainen pylväskaavio"
);
// 5. Suorita (agentti kirjoittaa Pythonia, Azure ajaa sen hiekkalaatikossa)
await foreach (var msg in agentDefinition.InvokeAsync(thread))
{
Console.WriteLine($"[{msg.AuthorName}]: {msg.Content}");
// Pura generoidut kuvat (kaaviot)
foreach (var item in msg.Items)
{
if (item is ImageContent imgContent)
{
var imageBytes = imgContent.Data!.Value.ToArray();
await File.WriteAllBytesAsync("sales_chart.png", imageBytes);
Console.WriteLine("Kaavio tallennettu sales_chart.png:ksi");
}
}
}
// 6. Siivoa
await agentDefinition.DeleteAsync();Keskeiset erot ChatCompletionAgentiin:
- Tilan hallinta Azuressa, ei sovelluksessasi (säie säilyy uudelleenkäynnistyksien aikana)
- Turvallinen Python-suoritus Hyper-V-eristetyissä konteissa
- Natiivi RAG File Searchin kautta (ei manuaalista pilkkomista/upotusta)
- Managed Identity -tuki (ei API-avaimia koodissa)
Semantic Kernel Muisti: Vektorivarastot ja RAG-Toteutus
Muisti erottaa reaktiiviset chatbotit tilapäisistä AI-assistenteista. Semantic Kernel erottaa:
- Lyhytaikainen muisti: LLM:n konteksti-ikkuna (keskusteluhistoria)
- Pitkäaikainen muisti: Vektori-/semanttinen haku (RAG - Retrieval-Augmented Generation)
Paketti: Microsoft.Extensions.VectorData
Uusi abstraktio tarjoaa yhtenäisen rajapinnan Azure AI Searchille, CosmosDB:lle, Qdrantille, Redisille ja muistivarastoille.
6.1 Vektoridatamallin määrittäminen
Käytä attribuutteja C#-ominaisuuksien kartoittamiseen vektorivarasto-skeemaan.
using Microsoft.Extensions.VectorData;
public class ProductDocument
{
[VectorStoreRecordKey]
public string ProductId { get; set; } = string.Empty;
[VectorStoreRecordData]
public string Name { get; set; } = string.Empty;
[VectorStoreRecordData]
public string Description { get; set; } = string.Empty;
[VectorStoreRecordData]
public decimal Price { get; set; }
[VectorStoreRecordData]
public string Category { get; set; } = string.Empty;
// Upotus vektori (1536 dimensiota text-embedding-ada-002:lle)
[VectorStoreRecordVector(1536, DistanceFunction.CosineSimilarity)]
public ReadOnlyMemory<float> DescriptionEmbedding { get; set; }
}6.2 CosmosDB:n käyttäminen vektorivarastona
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.AzureCosmosDBMongoDB;
using Microsoft.SemanticKernel.Embeddings;
// 1. Rekisteröi upotuspalvelu
builder.Services.AddAzureOpenAITextEmbeddingGeneration(
deploymentName: "text-embedding-ada-002",
endpoint: azureOpenAiEndpoint,
apiKey: azureOpenAiKey
);
// 2. Luo vektorivaarasto-client
var mongoClient = new MongoClient(cosmosConnectionString);
var vectorStore = new AzureCosmosDBMongoDBVectorStore(mongoClient);
// 3. Hae kokoelma (luo automaattisesti tarvittaessa)
var collection = vectorStore.GetCollection<string, ProductDocument>("products");
await collection.CreateCollectionIfNotExistsAsync();
// 4. Generoi upotus ja tallenna
var embeddingService = kernel.GetRequiredService<ITextEmbeddingGenerationService>();
var product = new ProductDocument
{
ProductId = "SKU-12345",
Name = "Langaton näppäimistö",
Description = "Ergonominen langaton näppäimistö mekaanisilla kytkimillä",
Price = 89.99m,
Category = "Elektroniikka"
};
// Generoi upotus kuvaukselle
var embedding = await embeddingService.GenerateEmbeddingAsync(product.Description);
product.DescriptionEmbedding = embedding;
// Tallenna vektoritietokantaan
await collection.UpsertAsync(product);
// 5. Semanttinen haku
var queryEmbedding = await embeddingService.GenerateEmbeddingAsync(
"Tarvitsen mukavan näppäimistön koodaukseen"
);
var searchResults = await collection.VectorizedSearchAsync(
queryEmbedding,
new VectorSearchOptions { Top = 5 }
);
await foreach (var result in searchResults.Results)
{
Console.WriteLine($"Osuma: {result.Record.Name} (Pisteet: {result.Score:F3})");
}6.3 Muisti-rajatut agentit
Moniagenttijärjestelmissä muistin rajaus estää kontekstin saastumisen:
// Jaettu muisti: Kaikki agentit näkevät saman keskustelun
var sharedHistory = new ChatHistory();
chat.AddChatMessage(sharedHistory);
// Yksityinen muisti: Jokaisella agentilla on eristetty tieto
var menuKernel = kernel.Clone();
menuKernel.Plugins.AddFromObject(new MenuPlugin(vectorStore)); // Menu-data
var kitchenKernel = kernel.Clone();
kitchenKernel.Plugins.AddFromObject(new KitchenPlugin(equipmentDb)); // Laitetieto
ChatCompletionAgent menuAgent = new()
{
Name = "MenuAgent",
Kernel = menuKernel, // Sisältää menuvektorivaraston
Instructions = "Vastaa kysymyksiin menueristä käyttämällä menutietokantaa"
};
ChatCompletionAgent kitchenAgent = new()
{
Name = "KitchenAgent",
Kernel = kitchenKernel, // Sisältää laitetietokannan
Instructions = "Hallitse keittiölaitteita ja varastoa"
};
// Jokainen agentti näkee vain omat työkalunsa ja muistinsaKriittinen malli: Käytä kernel.Clone()-metodia tai erillisiä DI-scopeja eristääksesi pluginpääsyn. Ilman tätä kaikki agentit jakavat saman Kernel.Plugins-kokoelman, luoden turvallisuus- ja logiikkaongelmia.
Tuotantovalmis Semantic Kernel: Havainnoitavuus ja Virheidenkäsittely
Semantic Kernelin Monitorointi OpenTelemetrylla
Agenttipäättelyn debuggaus on tunnetusti vaikeaa (“Miksi se valitsi tuon työkalun?”). SK integroituu syvällisesti OpenTelemetryn kanssa.
using OpenTelemetry.Trace;
using OpenTelemetry.Logs;
var builder = Host.CreateApplicationBuilder(args);
// Ota käyttöön OpenTelemetry-jäljitys
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddSource("Microsoft.SemanticKernel*")
.AddAzureMonitorTraceExporter() // Tai Jaeger, Zipkin
.AddConsoleExporter(); // Vain kehityksessä
});
// Lokien integraatio
builder.Logging.AddOpenTelemetry(logging =>
{
logging.AddAzureMonitorLogExporter();
});SK lähettää Activities-tapahtumia:
- Funktion kutsut (mikä plugin, mitkä argumentit)
- Mallikutsut (prompt, käytetyt tokenit, vastausaika)
- Suunnittelijan vaiheet (päättelyjäljet)
7.2 Suodattimet: väliohjelmistoputki
Suodattimet sieppaavat suorituksen lokitusta, PII-poistoa tai uudelleenyrityslogiikkaa varten.
using Microsoft.SemanticKernel;
// Funktion kutsusuodatin (lokittaa työkalukutsut)
public class FunctionLoggingFilter : IFunctionInvocationFilter
{
private readonly ILogger<FunctionLoggingFilter> _logger;
public FunctionLoggingFilter(ILogger<FunctionLoggingFilter> logger)
=> _logger = logger;
public async Task OnFunctionInvocationAsync(
FunctionInvocationContext context,
Func<FunctionInvocationContext, Task> next)
{
_logger.LogInformation(
"Agentti kutsuu {Plugin}.{Function} argumenteilla: {Args}",
context.Function.PluginName,
context.Function.Name,
context.Arguments
);
await next(context); // Suorita funktio
_logger.LogInformation(
"Funktio {Function} palautti: {Result}",
context.Function.Name,
context.Result?.ToString()
);
}
}
// Prompt-suodatin (PII-poisto ennen LLM:lle lähettämistä)
public class PiiRedactionFilter : IPromptRenderFilter
{
private readonly Regex _ssnRegex = new(@"\b\d{3}-\d{2}-\d{4}\b");
private readonly Regex _emailRegex = new(@"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b");
public async Task OnPromptRenderAsync(
PromptRenderContext context,
Func<PromptRenderContext, Task> next)
{
await next(context); // Renderöi prompt
// Poista PII ennen LLM:lle lähettämistä
var renderedPrompt = context.RenderedPrompt!;
renderedPrompt = _ssnRegex.Replace(renderedPrompt, "***-**-****");
renderedPrompt = _emailRegex.Replace(renderedPrompt, "***@***.***");
context.RenderedPrompt = renderedPrompt;
}
}
// Rekisteröi suodattimet DI:ssä
builder.Services.AddSingleton<IFunctionInvocationFilter, FunctionLoggingFilter>();
builder.Services.AddSingleton<IPromptRenderFilter, PiiRedactionFilter>();7.3 Virheidenkäsittely & häiriönsietokyky
using Polly;
using Polly.Extensions.Http;
// Uudelleenyritys politiikka tilapäisille virheille (429-rajoitus, verkko-ongelmat)
var retryPolicy = HttpPolicyExtensions
.HandleTransientHttpError()
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
builder.Services.AddHttpClient("AzureOpenAI")
.AddPolicyHandler(retryPolicy);
// Agenttitason virheidenkäsittely
try
{
await foreach (var message in chat.InvokeAsync())
{
Console.WriteLine(message.Content);
}
}
catch (HttpOperationException ex) when (ex.StatusCode == 429)
{
// Rajoitettu - takaisinveto tai siirry toiseen malliin
_logger.LogWarning("Nopeus rajoitettu. Yritetään uudelleen hitaammalla mallilla...");
}
catch (KernelException ex) when (ex.InnerException is JsonException)
{
// LLM generoi virheellisen JSON:n funktiokutsulle
_logger.LogError("Virheellinen työkalukutsumuoto: {Error}", ex.Message);
// Injektoi virhe keskusteluhistoriaan LLM:n nähtäväksi ja uudelleenyritystä varten
chat.AddChatMessage(new ChatMessageContent(
AuthorRole.System,
$"Virhe: Virheellinen funktiokutsumuoto. Yritä uudelleen."
));
}7.4 Tilan pysyvyys tilattomille hosteille
Agentit Azure Functionsissa tai Kubernetesissa on selvittävä uudelleenkäynnistyksistä.
using System.Text.Json;
// Serialisoi AgentGroupChat-tila
public class AgentChatStateManager
{
public async Task SaveStateAsync(AgentGroupChat chat, string sessionId)
{
var state = new
{
History = chat.History.Select(m => new
{
m.Role,
m.Content,
m.AuthorName
}).ToList(),
Iteration = chat.History.Count
};
var json = JsonSerializer.Serialize(state);
await _blobStorage.UploadAsync($"sessions/{sessionId}.json", json);
}
public async Task<ChatHistory> LoadStateAsync(string sessionId)
{
var json = await _blobStorage.DownloadAsync($"sessions/{sessionId}.json");
var state = JsonSerializer.Deserialize<dynamic>(json);
var history = new ChatHistory();
foreach (var msg in state.History)
{
history.AddMessage(
new ChatMessageContent(msg.Role, msg.Content)
{
AuthorName = msg.AuthorName
}
);
}
return history;
}
}Yhteenveto: Yritystason AI Rakentaminen Semantic Kernelillä
Semantic Kernel on kehittynyt yksinkertaisesta LLM-kääreobjektista kattavaksi kehykseksi yritys-AI-järjestelmien rakentamiseen. Keskeiset opit senior-kehittäjille:
- Hajota, älä monoliitti: Jaa monimutkaiset tehtävät erikoistuneisiin agentteihin (Planner, Coder, Reviewer, Data Analyst)
- Tyyppiturvallisuu ensin: Käytä vahvasti tyypitettyjä DTO:ita plugineissa. Anna LLM:n päätellä strukturoitua dataa.
- Hyödynnä standardit: MCP eliminoi mukautetut integraatiot. Käytä toimittajien tarjoamia työkalupalvelimia.
- Muisti = Pitkäaikainen + lyhytaikainen: Vektorivarastot tiedolle, konteksti-ikkuna välittömälle historialle
- Tuotantovalmiit mallit:
- Transient
Kernel-rekisteröinti (vältä tilan vuotoja) - OpenTelemetry havainnoitavuuteen
- Suodattimet PII-poistoon ja lokitukseen
- Tilan pysyvyys tilattomille hosteille (Azure Functions, Kubernetes)
- Transient
- Agenttiorkestraatio:
- Peräkkäinen deterministisille putkille
- KernelFunctionSelectionStrategy dynaamiselle reititykselle (ReAct-malli)
- Lopetusstrategiat estämään päättymättömät silmukat
Tulevaisuus piilee Process Frameworkissa (BPMN-kaltaiset tilakoneet agenteille, tällä hetkellä esikatselussa) ja syvemmässä Azure AI Foundry -integraatiossa. Mutta periaatteet pysyvät: orkestroi tarkasti, työkalut tarkasti ja tarkkaile selkeästi.
Rakenna moniagenttijärjestelmäsi kuten rakennat mikropalvelut - eristettyinä, testattavina ja häiriönsietoisina. Semantic Kernel tarjoaa primitiivit. Sinä tarjoat arkkitehtuurin.
Usein Kysytyt Kysymykset (UKK)
Mihin Semantic Kernel on tarkoitettu?
Semantic Kernel on tarkoitettu tuotantovalmiiden AI-agenttien ja moniagenttijärjestelmien rakentamiseen .NET:llä. Se yhdistää LLM:t kuten GPT-4:n liiketoimintalogiikkaasi, tietokantoihisi ja API:hin, mahdollistaen älykkään automatisoinnin monimutkaisille yritystyönkuluille.
Onko Semantic Kernel ilmainen?
Kyllä, Semantic Kernel on avoimen lähdekoodin ja ilmainen MIT-lisenssillä. Tarvitset kuitenkin API-avaimia AI-palveluille kuten Azure OpenAI tai OpenAI, joilla on omat hinnoittelunsa.
Mikä on ero Semantic Kernelin ja LangChainin välillä?
Semantic Kernel on suunniteltu .NET-kehittäjille vahvalla tyypityksellä, riippuvuusinjektiolla ja yritysmalleilla. LangChain on Python-ensisijainen. SK:lla on myös ensimm äisen luokan tuki Model Context Protocol (MCP) -yhteensopivuudelle ja Azure AI Foundry -integraatiolle.
Voinko käyttää Semantic Kernel paikallisten LLM:ien kanssa?
Kyllä! Semantic Kernel tukee mitä tahansa IChatCompletionService-toteutusta, mukaan lukien Ollama, Hugging Face -mallit ja muut paikalliset LLM-palveluntarjoajat. Et ole lukittu Azure OpenAI:hin.
Miten debuggaan Semantic Kernel -agentteja?
Käytä OpenTelemetry-integraatiota jäljittääksesi funktiokutsuja, mallikutsuja ja päättelyvaiheita. Ota käyttöön yksityiskohtainen lokitus LogLevel.Trace:llä kehityksen aikana nähdäksesi koko LLM-keskustelun kulun.
Mikä on Model Context Protocol (MCP)?
MCP on avoin standardi, joka mahdollistaa Semantic Kernel -agenteille valmiiden työkalupalvelimien (GitHub, Slack, Google Drive) käytön ilman mukautettujen pluginien kirjoittamista. Se mahdollistaa monikieliset AI-järjestelmät, joissa Python, Node.js ja .NET-agentit jakavat työkaluja.
Tukeeko Semantic Kernel moniagenttijärjestelmiä?
Kyllä, AgentGroupChat-kehys mahdollistaa kehittyneen moniagenttiorkestraation peräkkäisillä, dynaamisilla tai mukautetuilla reitit ysstrategioilla. Agentit voivat tehdä yhteistyötä jaetuilla tai eristetyillä muistikonteksteilla.
Seuraavat Askeleet: Hallitse Semantic Kernel
- Tutki Viralliset Semantic Kernel Esimerkit
- Opi Agent Framework -malleja
- Integroi MCP-palvelimet työnkulkuihisi
- Julkaise Azure AI Foundrylla yritystuotantoon