Suppose your company already has an internal support system. Employees use it to check tickets, look up customer information, and create requests.
Now they want to do the same work from Microsoft 365 Copilot.
You do not necessarily need to build another chatbot from scratch. Microsoft 365 Copilot can be extended with agents, actions, connectors, and APIs so that the agent can use company-specific knowledge and services. Microsoft currently provides several paths for doing this, including declarative agents, custom engine agents, Copilot Studio, the Microsoft 365 Agents SDK, and the Microsoft 365 Agents Toolkit.
The first decision is therefore not about code.
It is about deciding how much control your agent actually needs.
Two ways to build the agent
For many applications, the choice comes down to declarative agents and custom engine agents.
A declarative agent is mostly configuration. You describe what the agent does, give it instructions, add knowledge sources and actions, and package it for Microsoft 365 Copilot. It uses the same orchestrator and foundation models that power Microsoft 365 Copilot.
A custom engine agent is different. You control the orchestration and can bring your own AI models, data integrations, and application logic. Microsoft supports building these agents with options such as Copilot Studio, the Microsoft 365 Agents SDK, Teams SDK, or Microsoft Foundry.
A simple way to think about the difference is:
Requirement | Declarative agent | Custom engine agent |
|---|---|---|
Add instructions | Yes | Yes |
Add knowledge | Yes | Yes |
Connect external APIs | Yes, through actions/plugins | Yes |
Control orchestration | Limited | Much more control |
Bring your own model | No | Yes |
Custom application logic | Limited | Yes |
Development effort | Lower | Higher |
If your agent mainly needs to answer questions using company information and call a few APIs, starting with a declarative agent can make sense.
If the agent needs its own workflow, model selection, orchestration, or application logic, a custom engine agent gives you more room.
A declarative agent is mostly a configuration problem
This is one of the easier ways to get started.
A declarative agent has a manifest that describes its name, purpose, instructions, capabilities, conversation starters, and actions. The current declarative agent schema is version 1.8.
A small manifest can look like this:
{
"version": "v1.8",
"name": "Support Agent",
"description": "Helps employees find support information and manage tickets.",
"instructions": "Help users find support information. Use the ticket action when the user asks to create or update a ticket.",
"conversation_starters": [
{
"title": "Open tickets",
"text": "Show me my open support tickets."
},
{
"title": "Create a ticket",
"text": "Create a support ticket for my issue."
}
]
}
The manifest does not contain your entire application.
It tells Copilot what the agent is for and what capabilities are available.
You can then add an action:
{
"actions": [
{
"id": "supportApi",
"file": "support-api-plugin.json"
}
]
}
The action points to an API plugin definition. Microsoft documents actions as the mechanism through which declarative agents can access external functionality.
That separation is useful.
The agent decides when a capability is relevant. Your API still owns the actual operation.
Let your API do the real work
Imagine the support system has an endpoint:
GET /api/tickets/my-open-tickets
and another one:
POST /api/tickets
The agent can be given access to those operations.
A user could then type:
Show me my open support tickets.
The agent can decide that the ticket API is relevant, call it, and use the returned information in its response.
For a new ticket:
Create a ticket for my laptop not connecting to VPN.
The agent can use the create-ticket operation.
The API should still perform authentication, authorization, validation, and business checks.
Do not put rules such as “only managers can create priority-one tickets” into the agent instructions and assume that is enough.
The API should enforce that rule.
The agent is a caller of your application. It should not become your application's security layer.
Add company knowledge
An agent usually becomes useful when it has access to information that a general-purpose assistant does not have.
That might be:
SharePoint documents
Internal support information
Product documentation
Company policies
Knowledge bases
External business systems
Declarative agents can use Microsoft 365 knowledge sources and Copilot connectors, and they can also use actions to reach external services.
For example, imagine an HR agent.
You could give it access to:
HR Policies
Benefits Documentation
Leave Policy
Employee Handbook
Then an employee can ask:
How many days of parental leave are available?
The agent can use the configured knowledge rather than relying only on its general model knowledge.
That distinction matters for internal policies. Company information changes, and you do not want employees receiving an answer based on an old general assumption.
What about Microsoft 365 data?
Microsoft 365 is where this becomes more interesting.
An agent may need to work with information already stored in Microsoft 365.
For example:
SharePoint
Teams
Outlook
Microsoft Graph
Microsoft 365 Copilot connectors
The exact access path depends on the type of agent and the capability you are building.
Microsoft's documentation notes that Copilot Studio agents have native access to Microsoft 365 and Copilot connector content, while pro-code agents can use Microsoft Graph APIs and the Retrieval API for grounding in Microsoft 365 data.
That means you should decide early whether the agent needs to read existing Microsoft 365 information, take actions, or do both.
Reading a policy document and changing a customer's record are very different operations.
Treat them differently.
When the declarative approach stops being enough
There is a point where configuration starts feeling restrictive.
Imagine an agent that has to perform this workflow:
User request
|
v
Check customer
|
v
Find related orders
|
v
Call fraud service
|
v
Choose a model
|
v
Generate response
|
v
Create CRM record
You may want to control how each step works.
You may also want to use a particular model, maintain application state, call several services, or implement your own orchestration.
That is where a custom engine agent becomes more appropriate.
Microsoft describes custom engine agents as agents where developers control orchestration, AI models, and data integrations.
Using the Microsoft 365 Agents SDK
The Microsoft 365 Agents SDK is one option for the pro-code route.
Microsoft provides SDK support for .NET, JavaScript, and Python, and the SDK can be used with different AI stacks and orchestration approaches.
A simplified application structure might look like:
Microsoft 365 Copilot
|
v
Microsoft 365 Agents SDK
|
v
Your Agent
|
+----+----+
| |
v v
Business AI Model
Services
The SDK handles the connection between the agent and the Microsoft 365 channel.
Your code handles the actual agent behavior.
This is useful if you already have an agent running elsewhere.
Microsoft also documents a path for bringing existing agents written in C#, JavaScript, or Python into Microsoft 365 Copilot with the Agents SDK and Agents Toolkit.
So you do not necessarily have to throw away an existing agent just because users now want to access it through Copilot.
The Agents Toolkit handles the project setup
If you are building with code, the Microsoft 365 Agents Toolkit is worth using instead of manually creating every application and manifest file.
Microsoft provides templates and tooling for creating and deploying agents. The toolkit is available for Visual Studio and Visual Studio Code workflows.
A typical development cycle looks more like this:
Create project
|
v
Configure agent
|
v
Add tools / APIs
|
v
Run locally
|
v
Test with Copilot
|
v
Package
|
v
Publish
The local testing step is important.
Do not wait until the agent is installed across the organization before testing basic conversations and tool calls.
Keep permissions outside the prompt
This deserves its own section because it is easy to get wrong.
Suppose your agent has a tool called:
deleteCustomer
You might write this in the instructions:
Never delete a customer unless the user has permission.
That instruction is useful, but it should not be your only protection.
Your API should check the user's identity and permissions before performing the operation.
For example:
public async Task DeleteCustomer(
string customerId,
ClaimsPrincipal user)
{
if (!authorizationService
.CanDeleteCustomer(user, customerId))
{
throw new UnauthorizedAccessException();
}
await customerService.DeleteAsync(customerId);
}
The model can request the operation.
Your application decides whether the operation is allowed.
That makes the same API safe to call from an agent, a web application, or another internal service.
Publishing is another part of the project
Building the agent is only half of the work.
You also need to decide who can use it.
Microsoft provides different publishing and distribution options, including sharing within a tenant, organizational catalogs, and the Microsoft Commercial Marketplace for applicable scenarios.
Administrators can also manage agents through Microsoft 365 administration tools.
For an internal company agent, you may want a small pilot first:
Development
|
v
IT / Product Testing
|
v
Small User Group
|
v
Organization
That gives you time to find bad tool descriptions, missing permissions, poor answers, and unexpected data access before the agent reaches everyone.
A sensible first project
If you are new to Copilot extensibility, don't start with an agent that can access ten business systems.
Pick one job.
For example:
Find my open support tickets and create a new ticket when I ask.
That gives you enough to learn the important pieces:
Instructions
+
Knowledge
+
API Action
+
Authentication
+
Agent Testing
Once that works, add another capability.
This also makes problems easier to trace. If the agent starts producing incorrect answers after adding a new connector, you have a much smaller change to investigate.
A few things to check before deployment
Before giving an internal agent to a larger group, test these cases:
Test | What to check |
|---|---|
Normal question | Does the agent answer the intended questions? |
Missing information | Does it say when it cannot find an answer? |
API failure | Does it handle a failed service call sensibly? |
Unauthorized request | Does the backend reject it? |
Sensitive data | Does the agent expose only permitted information? |
Wrong tool | Can the application stop an invalid operation? |
Large request | Does the workflow remain usable? |
Existing user data | Is access based on the correct user's identity? |
The last two are easy to overlook.
An agent may work perfectly with five test users and behave differently when it has to deal with thousands of records or real organizational permissions.
Microsoft also provides governance and admin controls for agents, and the available controls depend on how the agent was built and deployed.
Choosing the starting point
There is no need to use the most complicated option just because it gives you more control.
For a small internal assistant, a declarative agent may be enough.
For an agent that already has its own orchestration and application code, the Agents SDK and Agents Toolkit give you a way to bring that experience into Microsoft 365.
The useful question is:
What does the agent need to do that Microsoft 365 Copilot cannot do by itself?
If the answer is “use our knowledge and call two APIs,” start small.
If the answer is “run our existing multi-step agent and connect it to several business systems,” look at the custom engine route.
Microsoft's current extensibility stack supports both approaches, so the architecture can grow with the application instead of forcing every project into the same model.

Join the conversation! Your thoughts help the community grow.