A support team I worked with last spring had built a refund assistant that worked perfectly in every demo. Then it hit production and started approving refunds against orders that did not exist. The model was not misreading the refund policy. It was inventing an order lookup that never ran, then confidently reporting the result. Their fix was not a better prompt. They rebuilt the thing as semantic kernel agents, where every tool call is a typed function that the runtime either executes or refuses outright.
That gap between a demo and something you would put in front of paying customers is where framework choice starts to matter. Here is how semantic kernel agents close it, and where the seams still show.
What a Semantic Kernel agent actually is
Semantic Kernel is Microsoft’s open-source SDK for wiring language models into real code. It ships in C#, Python and Java, and the design philosophy is deliberately unexciting: models predict, code executes, and the two never blur together.
An agent is the layer sitting on top of that. You hand it a goal, a toolbox and a budget. The runtime loops. The model picks a tool, the kernel runs it, the result goes back into the conversation, and the cycle repeats until the model stops asking for tools or the loop hits a ceiling you set. Nothing mystical happens inside.
Plugins give the model verbs
A plugin is a class with methods marked as kernel functions. You write get_order_status in ordinary C# or Python, decorate it, and the SDK generates the JSON schema the model needs to call it. The code is the easy part. The description is what decides whether the agent behaves.
A function described as returns shipping status will get invoked for refund questions, delivery complaints and anything vaguely order-shaped. A description reading looks up an order by ID and returns carrier, status code and estimated delivery date gets invoked for exactly that. If your agent keeps picking the wrong tool, rewrite the summary line before you touch the temperature.
The kernel does the unglamorous work
Function schemas, argument validation, retries on 429s, token accounting, and filters that let you log or redact a prompt before it leaves your network. In regulated industries that last capability is usually the whole reason the framework gets picked. Being able to intercept and rewrite every message in flight is not a nice-to-have when legal is in the room.
One turn, traced end to end
Trace what happens when a user types: where is order 4417 and can I still change the delivery address?
- The agent serialises the three registered plugins into a function schema and ships them with the message.
- The model returns a tool call for get_order_status with order_id: 4417.
- The kernel validates the argument, runs the method, and gets back a small JSON object: carrier, status, dispatched timestamp.
- That result is appended to chat history. The model reads it and calls check_address_window with the same ID.
- The second result says eleven minutes remain. The agent writes the reply and returns no further tool calls, which is how the loop ends.
Two tool calls, roughly 1,900 tokens, about 1.4 seconds against a small model. The termination condition is structural, not a regex hunting for the word done. That is the difference between an agent and a chatbot wearing a toolbelt.
Where the framework earns its keep
If your organisation already lives in .NET, this is close to a no-brainer. I have watched teams wrap a forty-method pricing library in kernel functions in a single afternoon and have a working agent by Thursday, because the plugin layer does not care that the underlying code is fifteen years old and full of decimal maths.
The bigger payoff shows up at scale. When you are running hundreds of concurrent conversations across several models, the ability to swap a connector, add a telemetry filter and route by cost without rewriting business logic matters. There is a decent walkthrough of that architecture in this breakdown of how Semantic Kernel scales from a single agent to a system.
Where it still gets awkward
Python-first teams often find the ergonomics rough. LangChain and LlamaIndex have broader integration catalogues, more community answers and faster-moving examples, which is why so many prototypes start there before anyone worries about production. If you are weighing the two, this comparison of how LangChain works and when it beats the alternatives is a fair starting point.
Planner churn is the other friction point. Stepwise planning moved, the Handlebars planner was retired, and package versions shift under your feet more often than most teams would like. Pin your versions. Read the migration notes. Do not assume a tutorial from eight months ago still compiles.
Building your first agent in an afternoon
Scope discipline beats clever prompting. Pick a task that needs three to five tools and nothing more. A travel-expense agent with lookup_receipt, check_policy, convert_currency and submit_claim will work. One that needs nineteen tools will fail, and it will fail in ways that are hard to diagnose.
- Write and test the plugin on its own before any model touches it. If check_policy throws on a null category, fix that first.
- Write the descriptions last, after you have watched the agent choose badly at least once.
- Cap the loop at six iterations. Anything beyond that is usually a description problem wearing a costume.
- Build a 25-question eval set on day one, including four questions the agent should refuse.
- Log every prompt, tool name, argument and latency. You will need it within a week.
Multi-agent setups and the orchestration question
Semantic Kernel ships an agent group chat with selection and termination strategies, so you can put a researcher, a writer and a reviewer in the same room and let them argue. It works. It also multiplies your token bill and your debugging surface, so reach for it when one agent genuinely cannot hold the context.
The pattern shows up in serious places. A dual-tier multi-agent framework for oncology decision support splits work between agents that see patient data and agents that do not, which is exactly the kind of boundary a single monolithic agent cannot enforce. If you would rather buy guardrails than build them, the NVIDIA NeMo agent toolkit bundles observability and profiling into the runtime, at the cost of a heavier footprint.
Instrumentation is the part everyone skips
Track tool-selection accuracy separately from answer quality. They diverge, and the average hides it. A system scoring 94% on answer quality can be selecting the right tool only 71% of the time, because a confident wrong answer reads just as well as a correct one. Ten minutes of charting will show you which one is broken.
Wire OpenTelemetry spans around each function call and set per-agent token budgets so a runaway loop cannot quietly burn through a month of Azure credit in an afternoon. Run your eval set in CI on every prompt change, not just every code change. Prompts are code now, and the ones that look harmless are usually the ones that break the tool selection you spent three weeks tuning.

