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:

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.