Share via


Connect to custom knowledge sources

Copilot Studio includes built-in knowledge sources such as SharePoint and Dataverse. Many organizations also use their own search endpoints, like custom APIs, existing enterprise search systems, or Azure AI Search, while maintaining full control over the query that is executed.

Copilot Studio supports this scenario with the OnKnowledgeRequested trigger. Any topic that uses this trigger acts as a custom knowledge source and contributes results to generative answers.

This article explains how to build and integrate custom knowledge sources in Copilot Studio by using the OnKnowledgeRequested trigger. You learn how Copilot Studio rewrites queries, how to connect to your own search API, how to format results for generative answers, and best practices when working with custom knowledge.

The OnKnowledgeRequested trigger

Use the OnKnowledgeRequested trigger in these two situations:

  • When the orchestrator determines that knowledge retrieval is required to answer a user query.
  • When a generative answers node is explicitly invoked in the conversation.

Important

You can only configure this trigger in code view by using YAML. There's no visual designer support.

Topics that use OnKnowledgeRequested have access to system variables that aren't available in regular topics:

  • System.SearchQuery: A context‑aware, rewritten version of the user's query that's optimized for semantic search.
  • System.KeywordSearchQuery: A rewritten query that's optimized for keyword‑based search engines.
  • System.SearchResults: Where the topic stores formatted knowledge snippets.

Copilot Studio intelligently rewrites queries by using conversation history, ensuring that it preserves multi-turn context.

Building a custom knowledge source

To build a custom knowledge source, you create a topic with the OnKnowledgeRequested trigger that calls your search API and transforms results into the format that Copilot Studio expects.

Step 1: Create the trigger

Create a new topic in Copilot Studio, switch to code view, and define the OnKnowledgeRequested trigger.

kind: AdaptiveDialog
beginDialog:
  kind: OnKnowledgeRequested
  id: main
  intent: {}
  actions:
    # Actions go here
inputType: {}
outputType: {}

This structure tells Copilot Studio that this topic is responsible for fulfilling knowledge requests.

Step 2: Add an HTTP request

Add an HTTP action that calls your search endpoint.

Example:

- kind: HttpRequestAction
  id: searchRequest
  url: = "https://search-api.contoso.com/search?q=" & System.KeywordSearchQuery
  response: Topic.searchResults
  responseSchema:
    kind: Record
    properties:
      query: String
      results:
        type:
          kind: Table
          properties:
            snippet: String
            title: String
            url: String

Concatenate System.KeywordSearchQuery to your base URL because Copilot Studio automatically rewrites the user query with conversation context before making the search request. This step is important to maintain context across multi-turn conversations.

Tip

Instead of a raw HTTP request, you can use any method that gets results from a search endpoint, including custom connectors, built-in connectors like Azure AI Search, or agent flows.

Example of query rewriting

  • User query 1: "What's our official data retention period for customer records?"
  • Follow-up query: "Does it change for financial information?"
  • Follow-up query: "And are there exceptions?"

Rewritten query becomes: "exceptions to data retention policy customer and financial data retention exceptions regulatory exemptions policy exception handling compliance guidelines"

Notice that the rewritten query:

  • Resolves "there" to data retention policy
  • Pulls forward context from both prior turns: customer data + financial data
  • Adds enterprise policy language: exceptions, exemptions, regulatory, guidelines

Step 3: Transform results

A custom knowledge source must output results in the format that Copilot Studio expects. This format uses:

  • Content: Snippet or excerpt.
  • ContentLocation (optional): URL.
  • Title (optional): Title of the result.

To define the structure of the HTTP response, configure the response schema in the Copilot Studio user interface.

  • Select From sample data for the response data type.
  • Select Get schema from sample JSON.
  • Paste your sample JSON payload to automatically generate the schema.

This process generates the response schema in your YAML file.

responseSchema:
  kind: Record
  properties:
    query: String
    results:
      type:
        kind: Table
        properties:
          snippet: String
          title: String
          url: String

Next, transform your API's response to match this format. Assign the transformed data to System.SearchResults.

Example transformation

kind: AdaptiveDialog
beginDialog:
  kind: OnKnowledgeRequested
  id: main
  intent: {}
  actions:
    - kind: HttpRequestAction
      id: searchRequest
      url: ="https://search-api.contoso.com/search?q=" & System.KeywordSearchQuery
      response: Topic.searchResults
      responseSchema:
        kind: Record
        properties:
          query: String
          results:
            type:
              kind: Table
              properties:
                snippet: String
                title: String
                url: String
    
    - kind: SetVariable
      id: setSearchResults
      variable: System.SearchResults
      value: |-
        =ForAll(Topic.searchResults.results,
        {
          Content: snippet,
          ContentLocation: url,
          Title: title
        })

inputType: {}
outputType: {}

The SetVariable action performs both operations:

  • The ForAll function transforms each search result, mapping snippet to Content, url to ContentLocation, and title to Title.
  • The transformed table is assigned to System.SearchResults, which is the variable Copilot Studio uses to generate answers.

Considerations

Keep these key considerations in mind when you build custom knowledge sources.

Result limits

Copilot Studio uses up to 15 snippets from System.SearchResults to generate a response. If your API returns more results, consider:

  • Implementing relevance scoring to return the best results first.
  • Limiting your API response to 15 results.
  • Sorting results by relevance before transformation.

Multiple custom knowledge topics

You can create multiple topics by using OnKnowledgeRequested, and each topic can query different backend systems. Copilot Studio invokes all of them simultaneously when it needs knowledge. This approach allows you to query different search endpoints or implement fallback strategies.

Warning

The result limit applies across all knowledge topics combined. If Topic A returns 10 results and Topic B returns 8, only the top 15 combined results are used.

Recommendations

  • Sort or score results before returning them.
  • Keep response schemas consistent.
  • Use clear topic names and descriptions. This practice is useful when large result sets require relevance filtering.