Building Your First AI Chatbot in C# with Semantic Kernel
Semantic Kernel is Microsoft's open-source SDK for building AI applications in .NET, and "chatbot with skills" is its home turf: conversation state, plugin functions the model can call, prompt management, and provider independence, all in idiomatic C#. In this tutorial we'll build a working support chatbot for a fictional store — one that can actually look things up rather than hallucinate answers.
By the end you'll have: a chat loop with memory, a plugin the model calls on its own, and streaming responses — the skeleton of every real chatbot I've shipped.
Setup
The kernel is the DI container of the AI world — you register capabilities on it, then ask it to run things:
(Swap AddOpenAIChatCompletion for AddAzureOpenAIChatCompletion or a local Ollama endpoint without touching anything below — that's the provider independence working.)
The chat loop with memory
ChatHistory is the memory — the model itself remembers nothing between calls. Two production notes on that: the history grows (and costs tokens) every turn, so long conversations need trimming or summarizing; and in a web app you'd persist history per session/user rather than in a local variable.
Plugins: where chatbots become useful
A chatbot that only chats is a toy. Plugins give the model functions it can decide to call:
Register it and enable automatic invocation:
Now the conversation does this, with no routing code from you:
Under the hood, the model saw the question, decided to call GetOrderStatus("TT-10293"), Semantic Kernel invoked your C# method, fed the result back, and the model wrote the human answer. The [Description] attributes are load-bearing — they're the only documentation the model gets, so write them like you're explaining the function to a new teammate.
The safety rules for plugins
The moment the model can call your code, you're on the hook for what that code can do:
- Expose read operations freely; guard writes. Cancelling an order? Require an explicit confirmation turn ("Should I go ahead and cancel TT-10293?") and check the user's actual permissions in the plugin — never trust the model to enforce authorization.
- Validate inputs like any API endpoint. The arguments come from a model interpreting user text; treat them as untrusted user input, because that's what they are.
- Return structured results (records, not prose strings) so the model gets clean facts to phrase, and log every invocation — "why did the bot say that?" is a question you will be asked.
Streaming for a real UI
For a console demo, the wait is fine. For users, stream:
In ASP.NET Core, forward those chunks over SSE or SignalR. The pattern is identical; only the transport changes.
Where this skeleton goes next
You've now got the three pillars — memory, tools, streaming. Real deployments add, roughly in order:
- Grounding in your documents so the bot answers from your knowledge base instead of its training data — that's Retrieval-Augmented Generation.
- Persistence of chat history (database keyed by session) and a token-budget trimming strategy.
- Evaluation — a test set of expected question/answer behaviors you run when you change prompts or models, because prompt changes are code changes.
Semantic Kernel scales up with you: the same kernel handles multi-step agent orchestration and planners when you need them. But don't start there — start with this skeleton, ship the boring version, and let real user questions tell you which fancy features you actually need.
Where to go next
- RAG Explained for .NET Developers — grounding your bot in your own documents.
- LLM Function Calling in C# — the mechanics and security of tool calling, in depth.
- Getting Started with Microsoft.Extensions.AI — the lighter-weight alternative when you don't need full SK orchestration.