Building Your First Declarative Agent with Schema v1.4 and v1.5

Building Your First Declarative Agent with Schema v1.4 and v1.5

I spent most of last week rebuilding a customer’s internal knowledge agent. They had a working v1.3 manifest, it did the job, but they wanted two things: stop the agent from hallucinating with its own model knowledge, and let it pull context from Teams meetings. Turns out, both of those landed in the latest schema versions. So I figured I’d write down what I learned while it’s still fresh.

This post walks through the declarative agent manifest schema v1.4 and v1.5 – what changed, what’s new, and how to build an agent from scratch using these versions.

What changed in v1.4

Schema v1.4 added a few things on top of v1.3:

  • behavior_overrides – a new top-level property that lets you control suggestions and discourage model knowledge.
  • disclaimer – display a disclaimer message to users at the start of every conversation.
  • part_type and part_id on the SharePoint IDs object – you can now reference parts of a SharePoint item, like a specific OneNote page.
  • ScenarioModels capability – lets agents use task-specific fine-tuned models.
  • New Connection object properties for scoping Copilot connector content more precisely.

The behavior_overrides property is the one that matters most in practice. Here’s what it looks like:

{
  "behavior_overrides": {
    "suggestions": {
      "disabled": true
    },
    "special_instructions": {
      "discourage_model_knowledge": true
    }
  }
}

Setting discourage_model_knowledge to true tells the agent to avoid using the LLM’s built-in knowledge when generating responses. It sticks to the knowledge sources you defined. For enterprise scenarios where you want answers grounded strictly in company data, this was the single most requested feature I kept hearing about.

The disclaimer property does what you’d expect:

{
  "disclaimer": {
    "text": "This agent provides information from internal documentation only. Always verify critical decisions with your team lead."
  }
}

The text shows up at the start of every conversation. Max 500 characters. Simple, but it makes legal and compliance teams much happier.

What changed in v1.5

Schema v1.5 adds exactly one thing on top of v1.4: the Meetings capability.

{
  "capabilities": [
    {
      "name": "Meetings"
    }
  ]
}

That’s it. One new capability object. But it opens up a lot – your agent can now search meeting metadata (subject, organizer, attendees), transcript content, and meeting chats. Imagine a project status agent that can answer “What was discussed about the budget in last Tuesday’s standup?” without anyone manually writing notes. That’s the scenario my customer actually wanted.

The Meetings capability requires a Microsoft 365 Copilot license for the user. No additional scoping properties exist in v1.5 – the agent gets access to all meetings the user has access to. (If you need to scope to specific meetings by UID, that came later in v1.6 with the items_by_id property.)

Building a declarative agent from scratch

We’ll build an internal knowledge agent that uses SharePoint documents and Teams meetings as knowledge sources, discourages model hallucination, and shows a disclaimer. Basically the same thing I built for that customer, simplified a bit.

Prerequisites

You need:

Create the project

  1. Open VS Code.
  2. Select Microsoft 365 Agents Toolkit > Create a New Agent/App.
  3. Select Declarative Agent.
  4. Select No Action (we’re building a knowledge-only agent).
  5. Pick a folder and name it something meaningful – I’ll use ProjectKnowledgeAgent.

The toolkit generates a project with the key file at appPackage/declarativeAgent.json. That’s our manifest.

The full manifest

Here’s the complete manifest for our agent. I’ll break it down section by section afterward:

{
  "$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.5/schema.json",
  "version": "v1.5",
  "name": "Project Knowledge Agent",
  "description": "Answers questions about our project using internal documentation and meeting context.",
  "instructions": "You are a project knowledge assistant. Answer questions based on the SharePoint documents and meeting transcripts provided as knowledge sources. Be concise and cite specific documents or meetings when possible. If you cannot find the answer in the provided sources, say so clearly. Do not speculate or use general knowledge.",
  "conversation_starters": [
    {
      "title": "Project Status",
      "text": "What's the current status of Project Alpha based on the latest documents?"
    },
    {
      "title": "Meeting Recap",
      "text": "Summarize the key decisions from last week's project meetings."
    },
    {
      "title": "Open Items",
      "text": "What action items are still open from our recent meetings?"
    }
  ],
  "behavior_overrides": {
    "suggestions": {
      "disabled": false
    },
    "special_instructions": {
      "discourage_model_knowledge": true
    }
  },
  "disclaimer": {
    "text": "This agent answers based on internal project documents and meeting transcripts only. Always verify critical information with the project lead."
  },
  "capabilities": [
    {
      "name": "OneDriveAndSharePoint",
      "items_by_url": [
        {
          "url": "https://contoso.sharepoint.com/sites/ProjectAlpha/Shared Documents"
        }
      ]
    },
    {
      "name": "Meetings"
    },
    {
      "name": "TeamsMessages",
      "urls": [
        {
          "url": "https://teams.microsoft.com/l/channel/19%3Aabc123def456@thread.tacv2/Project%20Alpha?groupId=your-group-id&tenantId=your-tenant-id"
        }
      ]
    }
  ]
}

Here’s what each part does.

Schema and version

{
  "$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.5/schema.json",
  "version": "v1.5"
}

The $schema property points to the JSON Schema definition. Set version to v1.5 to get access to both the v1.4 behavior overrides and the v1.5 meetings capability. Use v1.4 if you don’t need meetings.

Instructions that work

The instructions field is your agent’s core prompt. Up to 8,000 characters. I’ve found that being explicit about what the agent should not do is just as important as what it should do. “Do not speculate” and “say so clearly if you can’t find the answer” are lines I include in almost every agent I build.

A few tips from real deployments:

  • Start with the agent’s role (“You are a project knowledge assistant”).
  • Define the expected behavior (“Be concise and cite specific documents”).
  • Set boundaries (“Do not speculate or use general knowledge”).
  • Keep it focused. Trying to make one agent do everything is a recipe for mediocre results.

Conversation starters

You can define up to 12 conversation starters. Each needs a text property (required) and an optional title. Both are localizable. These show up as suggestion chips when the user opens the agent – they’re the first impression, so make them specific to what the agent actually does well.

Configuring knowledge sources

Declarative agents support a bunch of different knowledge sources, and v1.4/v1.5 give you more control over how they’re scoped.

SharePoint and OneDrive

The OneDriveAndSharePoint capability is probably the most-used knowledge source. You can reference content in two ways:

By URL – point to a site, library, or folder:

{
  "name": "OneDriveAndSharePoint",
  "items_by_url": [
    {
      "url": "https://contoso.sharepoint.com/sites/ProjectAlpha/Shared Documents"
    }
  ]
}

By SharePoint IDs – more precise, using site_id, web_id, list_id, and unique_id:

{
  "name": "OneDriveAndSharePoint",
  "items_by_sharepoint_ids": [
    {
      "site_id": "bc54a8cc-8c2e-4e62-99cf-660b3594bbfd",
      "web_id": "a5377427-f041-49b5-a2e9-0d58f4343939",
      "list_id": "78A4158C-D2E0-4708-A07D-EE751111E462",
      "unique_id": "304fcfdf-8842-434d-a56f-44a1e54fbed2"
    }
  ]
}

New in v1.4: you can use part_type and part_id to reference specific parts of a SharePoint item. Right now, the only supported part_type is OneNotePart, which lets you point to a specific OneNote page. Niche, but very handy if your team keeps project notes in OneNote.

The file limit reality

Here’s something that catches people off guard – and it’s documented in the Microsoft Learn best practices. You can reference a large number of SharePoint files, but Copilot’s retrieval behavior changes depending on how many you specify:

  • 20 or fewer files: Copilot searches the full contents of all files.
  • More than 20 files: Copilot searches the full contents of the 20 most relevant files.

So if you specify 50 files, Copilot first determines which 20 are most relevant to the user’s query, then searches those. The best practice from Microsoft is to keep your referenced files under 300 total pages if you want thorough coverage.

Also worth noting: keep individual files under 36,000 characters (roughly 15-20 pages). Larger files make it harder for Copilot to find the right content. If you have a massive document, break it into smaller, focused files.

Teams meetings as a knowledge source

Adding the Meetings capability (v1.5) gives your agent access to:

  • Meeting metadata: subject, organizer, attendees, title
  • Transcript content
  • Meeting chats

In v1.5, the capability is unscoped – the agent can search all meetings the user has access to. There’s no property to limit it to specific meetings in this version.

One thing to keep in mind: meeting transcripts are only available if transcription was actually enabled during the meeting. No transcript, no content for the agent to search. Make sure your organization has transcription policies set up correctly.

Teams messages

Separate from meetings, the TeamsMessages capability lets the agent search through channels, meeting chats, group chats, and 1:1 chats. You can scope it to up to five specific URLs, or leave the urls array empty to search everything.

{
  "name": "TeamsMessages",
  "urls": [
    {
      "url": "https://teams.microsoft.com/l/channel/19%3A...@thread.tacv2/General?groupId=...&tenantId=..."
    }
  ]
}

To get the URL for a channel, right-click the channel name in Teams and select “Get link to channel.” For group or 1:1 chats, you need the deep link format: https://teams.microsoft.com/l/chat/<chatId>/conversations.

Provisioning and testing

Once your manifest is ready:

  1. In VS Code, open the Microsoft 365 Agents Toolkit sidebar.
  2. Under Lifecycle, click Provision.
  3. Sign in with your Microsoft 365 account.
  4. The toolkit packages your manifest and uploads it.

To test:

  1. Go to https://m365.cloud.microsoft/chat.
  2. Click the conversation drawer icon next to New Chat.
  3. Find and select your agent.
  4. Try your conversation starters first, then ask questions that should hit your knowledge sources.

I always test in three rounds:

  1. Happy path: Questions the agent should answer well from the provided knowledge.
  2. Edge cases: Questions that are adjacent but not directly covered – does the agent admit it doesn’t know?
  3. Out of scope: Questions completely outside the agent’s domain – with discourage_model_knowledge set to true, the agent should not try to answer these from general knowledge.

Manifest best practices

After building a few of these, here’s what I keep coming back to.

The instructions matter way more than you’d think. Vague instructions produce vague results. “Help with project questions” is bad. “Answer questions about Project Alpha timelines, deliverables, and meeting decisions using the provided SharePoint documents and meeting transcripts” is good. Spend time on this.

If the agent should only answer from your data, turn on discourage_model_knowledge. Users trust the agent more when it says “I don’t have that information” instead of making something up. I set this to true on every enterprise agent now.

Don’t point to an entire SharePoint tenant as a knowledge source. Point to the specific site, library, or folder that’s relevant. Less noise, better answers. Same principle as not dumping your entire file server into a search index.

Break large documents into topic-specific files under 20 pages each. Copilot retrieves better from many small files than from a few massive ones. I learned this the hard way with a 200-page operations manual that the agent could barely use.

Test with real questions – not “What is Project Alpha?” but the actual questions your users will ask. “When is the next milestone for the backend migration?” is the kind of query you should test against.

If your agent handles HR policies, financial data, or anything regulated, add a disclaimer. It takes two minutes and saves you headaches later.

One more thing: use the latest schema version you actually need. Don’t use v1.5 if you don’t need meetings – v1.4 is fine. But don’t stick with v1.3 if you need behavior overrides.

What’s next

Schema v1.5 is already not the latest – v1.6 added scoped meetings (with items_by_id), the include_related_content property for People, and more. Things are moving fast. But the core ideas from v1.4 and v1.5 – behavior overrides, knowledge scoping, composing capabilities – still apply in every newer version. Learn them once and you’re set.

If you’ve been waiting to try your first declarative agent, the tooling is in a good place right now. The Agents Toolkit makes the feedback loop fast enough that you can go from zero to a working agent in an afternoon.

Go build something. Then tell me about it.

Read more

Enjoyed this post? Let's connect on LinkedIn:

Follow on LinkedIn →