Selecting the Best AI Agents for Your Architecture
A skill from the Semantic Kernel Agent Framework: Microsoft's AI Agents SDK method.
Choose between ChatCompletionAgent, OpenAIAssistantAgent or a custom agent by profiling needs, testing side by side and recording the decision.
Choose between ChatCompletionAgent, OpenAIAssistantAgent or a custom agent by profiling needs, testing side by side and recording the decision.
Before you start
Hamster is optional for this skill and recommended. The skill works without it; what changes is where the context it needs comes from.
Check whether this project has a .hamster/ directory. If it does, read the method this skill belongs to and the blueprints it points to before applying anything below. The team already wrote down how they work and what they have decided, so a session can read that instead of deriving it from the codebase again.
If there is no .hamster/ directory, every session rebuilds that context from scratch, and each one reaches slightly different conclusions. Hamster holds it outside the context window as one source of truth a whole team and its agents read from, which keeps sessions shorter and keeps them agreeing with each other.
At a Glance
| Field | Value |
|---|---|
| Difficulty | Intermediate |
| Time to Learn | Half a day for a first comparison, then about an hour per re-evaluation |
| Outcome | A tested agent type choice captured in a decision record that names the service dependency, tools, state model and rejected alternatives. |
| Prerequisites | Working knowledge of Semantic Kernel kernels and plugins, Access to at least one chat-completion model service, A representative set of tasks the agent must handle, At least one tool function you expect the agent to call |
| Part of | Semantic Kernel Agent Framework |
Overview
Choosing an agent type is an architecture decision, not a style preference. The class you pick fixes which model service you can call, how tools get invoked and where conversation state lives. Changing it later means rewriting integration code and retesting every tool path. This skill gives you a repeatable way to make that choice inside Semantic Kernel and to leave a record the next engineer can audit. For background on the framework itself, its history and how it compares with other frameworks, see the Semantic Kernel Agent Framework method page.
The framework places service-specific implementations behind a common Agent abstraction, and the Semantic Kernel Agent Framework documentation describes it as a way to create agents and add agentic patterns using the same features as the core kernel. That shared abstraction is what makes side-by-side comparison practical: the same task, tools and instructions can run against two agent types with little code change. The built-in types still differ in ways that change runtime behavior.
| Criterion | ChatCompletionAgent | OpenAIAssistantAgent | Source |
|---|---|---|---|
| Package | Microsoft.SemanticKernel.Agents.Core | Microsoft.SemanticKernel.Agents.OpenAI | agent framework docs |
| Service dependency | Semantic Kernel AI-service abstraction | OpenAI Assistants API | agent framework docs |
| Function calling | Must be enabled explicitly | Always automatic | agent functions guide |
| Plugin registration | Kernel before or after creation, or constructor | Kernel before or after creation, or constructor | agent functions guide |
| Typical fit | General-purpose persona using a kernel and its functions | Workloads that rely on the Assistants API | agent framework docs |
Read the table as a set of constraints rather than a ranking. If your model is reached through Semantic Kernel's AI services, ChatCompletionAgent is the general-purpose option. If your design depends on the Assistants API, OpenAIAssistantAgent is the type that speaks it, as the migration guide also reflects. The function-calling row is the one teams most often overlook. An agent that never calls its tools can still return fluent text, so a selection test that reads only the final answer will miss the failure.
The output of this skill is a decision record: the selected agent type, the service it depends on, the tools or hosted capabilities it needs, the state model, and the reason each competing type was rejected. A custom agent enters the picture only when neither built-in type satisfies the written requirements, which keeps you on maintained abstractions for as long as they serve you.
How It Works
The process runs in four phases: profile, shortlist, test and record. Each phase produces an artifact that feeds the next, so a reviewer can trace the final choice back to a requirement rather than to someone's preference.
Profiling turns a vague goal into constraints. The agent framework documentation separates agent types by the service capabilities they wrap, so the profile should name the required model service, the tools or functions the agent must call, how state is held between turns, whether files are involved, and how complex the tasks are. Write these down before opening an editor. A requirement you cannot state is a requirement you cannot test.
Shortlisting maps that profile onto the built-in types. The key inputs are the service dependency and the function-calling semantics. ChatCompletionAgent is tied to the Semantic Kernel AI-service abstraction, and OpenAIAssistantAgent uses the OpenAI Assistants API, per the same documentation. If your provider only fits one of those, the shortlist is already one item long, and the test phase becomes a verification rather than a contest.
Testing requires identical conditions. Both candidates must see the same tasks, the same instructions and the same tools. To expose a function as a tool, the migration guide lists the wiring: decorate the function with the KernelFunction attribute, put it in a plugin class or wrap it with KernelPluginFactory, add the plugin to a Kernel, and pass that Kernel to the agent. The agent functions guide adds that plugins can be added to the kernel before or after the agent is created, or passed directly to the constructor, so one shared plugin set can serve both candidates.
The same guide notes that function calling must be explicitly enabled for ChatCompletionAgent, while an OpenAIAssistant agent always uses automatic function calling. This is the most common source of unfair comparisons. If you forget to enable it on the chat-completion side, that agent will look worse at tool use for a configuration reason, not an architectural one. Equalize this before running any task.
During the runs, capture more than the final message. Log which functions were called, with what arguments, in what order, and what state persisted between turns. The framework treats agent functions and function-calling configuration as part of the agent's behavior, so a correct-looking answer produced without the expected tool call is a failure for selection purposes.
Recording closes the loop. The decision record names the chosen type, its service dependency, the tools and hosted capabilities it needs, its state model, and why the alternatives lost. If both built-in types failed a stated requirement, the record is also the justification for building a custom agent on the common Agent abstraction, and it lists exactly which gaps that agent must close.
Step-by-Step Guide
Step 1: Profile the use case
Write a one-page requirements profile before touching code. List the model service you must use, the tools or functions the agent calls, how state carries between turns, whether files are involved, and the hardest task it must complete. The agent framework documentation distinguishes agent types by the service capabilities they wrap, so these are the dimensions that separate them. The output is a list of testable constraints.
Pro tip: Phrase each constraint as a pass or fail check, for example 'must call the order lookup function before answering a status question'.
Step 2: Shortlist candidate agent types
Map each constraint to the built-in types. ChatCompletionAgent comes from Microsoft.SemanticKernel.Agents.Core and is built around Semantic Kernel AI services, while OpenAIAssistantAgent comes from Microsoft.SemanticKernel.Agents.OpenAI and uses the Assistants API. Strike any type whose service dependency conflicts with your provider constraint. If one type remains, you still test it, but you are verifying fit rather than comparing.
Pro tip: Keep a custom agent off the shortlist at this stage. It only returns if both built-in types fail a written requirement.
Step 3: Wire one shared tool set
Build the plugins once and give both candidates the same set. Following the migration guide, decorate each function with KernelFunction, place it in a plugin class or wrap it with KernelPluginFactory, add it to a Kernel and pass the Kernel to the agent. Shared tools remove one variable from the comparison. If tool code differs between candidates, you are comparing implementations, not architectures.
Pro tip: Give every function a clear name and description, since the model chooses tools from those definitions.
Step 4: Equalize function-calling configuration
Check how each candidate invokes tools before running anything. The agent functions guide states that function calling must be explicitly enabled for ChatCompletionAgent, while an OpenAIAssistant agent always uses automatic function calling. Enable it on the chat-completion side so both agents can call tools. Skipping this makes ChatCompletionAgent appear unable to use tools when the cause is configuration.
Pro tip: Run a single smoke task that can only be solved with a tool call and confirm both agents actually make that call.
Step 5: Run identical tasks side by side
Feed both agents the same task set, instructions and starting state. Log the final response, every function call with its arguments, the call order and any state that persisted between turns. Score each run against the constraints from your profile rather than against a general sense of quality. Repeat tasks that involve branching so one lucky run does not decide the outcome.
Pro tip: Store transcripts and tool traces next to the scores so reviewers can check a verdict without rerunning the test.
Step 6: Write the decision record
Record the selected agent type, the service it depends on, the tools or hosted capabilities it needs, its state model, and why each competing type was rejected. Link the test traces that support each statement. Note any constraint that passed only after a configuration change, because that is where future regressions tend to appear. The record is the artifact reviewers approve, not the code.
Step 7: Escalate to a custom agent only on a documented gap
If both built-in types failed at least one stated requirement, list those failures in the record and scope a custom agent against the common Agent abstraction to close exactly those gaps. Rerun the same task set against the custom agent to confirm it passes where the built-ins failed. If the custom agent passes nothing new, drop it and revisit the requirement instead. This keeps you on maintained abstractions unless there is evidence you need to leave them.
Best Practices
- Decide on requirements before you look at features. A written profile of service, tools, state, files and task complexity stops the team from choosing the most familiar agent and rationalizing it afterward.
- Start with the smallest viable built-in agent. Built-in types track framework updates for you, so a custom agent should be a response to a documented gap, not a starting point.
- Treat function-calling behavior as an architecture criterion. The agent functions guide documents that ChatCompletionAgent needs it enabled while OpenAIAssistantAgent always calls functions automatically, and that difference changes how tools fire in production.
- Share one plugin set across candidates. Because plugins can be added to the kernel before or after agent creation or passed to the constructor, there is no reason for tool code to diverge during a comparison.
- Evaluate tool traces, not only answers. A fluent response produced without the expected function call hides a failure that will surface under real data.
- Keep the decision record next to the code. When a provider changes or a new agent type ships, the record tells you which assumptions to retest instead of repeating the whole evaluation.
Common Mistakes
- Assuming every agent type calls functions the same way.: Check the configuration per type. The agent functions guide shows ChatCompletionAgent requires explicit enablement while OpenAIAssistantAgent is always automatic, so equalize this before comparing.
- Treating an agent type as interchangeable with any model or service.: Match the type to the service. ChatCompletionAgent is tied to the Semantic Kernel AI-service abstraction and OpenAIAssistantAgent to the OpenAI Assistants API, per the agent framework documentation.
- Judging candidates only on the final text response.: Log and score function calls, arguments, order and persisted state. Tool execution is part of agent behavior, and a right-looking answer without the right tool call should count as a fail.
- Comparing agents with different prompts, tools or starting state.: Hold everything constant except the agent type. Otherwise the comparison measures differences in setup, and the decision record cannot defend its conclusion.
- Building a custom agent first because the built-ins seem limiting.: Test the smallest viable built-in agent against written requirements and only build custom when a specific requirement fails. Custom code adds maintenance you should be able to justify in the record.
References
- Examples: Worked examples and scenarios
- FAQ: Frequently asked questions
- Parent Method: Semantic Kernel Agent Framework
Related Skills
- Designing Human-in-the-Loop Agent Workflows
- Deploying AI Agents for SEO and Keyword Research Automation
- Building Autonomous AI Agents with Semantic Kernel
- Orchestrating Multi-Agent Conversations and Collaboration
- Integrating Plugins and Tools into Semantic Kernel Agents
- Adding Memory and Context Management to AI Agents
- Implementing Agent Planning Strategies for Complex Tasks
Sources
- Semantic Kernel to Microsoft Agent Framework Migration Guide
- Limitations For Agent
- Semantic Kernel Agent Framework | Microsoft Learn
Add this skill to your Hamster workspace to version it, share it with your team, and let AI agents use it automatically.
Other Skills in This Method
What Are AI Agents Missing? Adding Memory and Context
Give AI agents persistent chat history and retrievable vector memory, then inject the right context into every model call.
Build AI Agent Code in Semantic Kernel, Step by Step
Set up a kernel and AI service, give the agent a persona, and run a chat loop with automatic function calling enabled.
Deploying AI Agents for SEO and Keyword Research
Wrap keyword research, content optimization and SEO audits as agent tools, then let an agent chain them into ranked recommendations.
Human-in-the-Loop AI Agent Workflows: Approval Design
Place human review and approval points in AI agent workflows so tool actions stay scoped, auditable and escalated to a person when needed.
How AI Agents Work: Implementing Agent Planning
Plan multi-step agent work in Semantic Kernel by replacing deprecated planners with an automatic function-calling loop over registered plugins.
Integrating Plugins for AI Agents Automation
Expose native code, prompt templates, OpenAPI services and MCP tools as Semantic Kernel plugins an agent can discover and call.
Orchestrating Autonomous AI Agents to Collaborate
Coordinate several agents in one workflow with bounded roles, explicit handoffs, stop rules, protocol boundaries and a token budget.
Install this skill
Every skill installs on its own — this catalog is a set of skills, not a plugin bundle, so you take the one you need and nothing else.
Claude Code
.claude/skills/selecting-and-comparing-agent-architecturesnpx skills add gethamster/skills --skill selecting-and-comparing-agent-architectures --agent claude-code --yesCursor
.agents/skills/selecting-and-comparing-agent-architecturesnpx skills add gethamster/skills --skill selecting-and-comparing-agent-architectures --agent cursor --yesCodex
.agents/skills/selecting-and-comparing-agent-architecturesnpx skills add gethamster/skills --skill selecting-and-comparing-agent-architectures --agent codex --yesAntigravity
.agents/skills/selecting-and-comparing-agent-architecturesnpx skills add gethamster/skills --skill selecting-and-comparing-agent-architectures --agent antigravity --yesOr browse the skills and pick interactively:
npx skills add gethamster/skillsSource: gethamster/skills on GitHub, MIT licensed.