> ## Documentation Index
> Fetch the complete documentation index at: https://www.plain.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Searching knowledge

> Give your agent answers from your help center and indexed documents.

To answer a customer's question, an agent needs facts. Rather than building and maintaining your own vector store, you can search the knowledge you've already added to Plain with the `searchKnowledgeSources` query. It runs a semantic search and returns the most relevant passages, ready to drop into a prompt. This is the retrieval half of a RAG ("retrieval-augmented generation") agent.

## What knowledge sources are

A knowledge source is any content in Plain that can be searched to answer a question. There are two kinds:

* **Help center articles** — the self-serve articles you publish in [Plain's help center](https://plain.support.site/article/help-center).
* **Indexed documents** — external pages and documents you've indexed for AI, like your public docs or marketing site.

You manage both in Plain, and `searchKnowledgeSources` searches across them in a single call.

## Search knowledge sources

Pass a natural-language `searchQuery` and Plain returns the passages most semantically relevant to it, ordered most-relevant first. Each result carries the matched `content` (a chunk of text) plus a reference to the source it came from.

This operation requires the `knowledgeSource:read` permission.

```ts theme={null}
const results = await plain.query.searchKnowledgeSources({
  searchQuery: "how do I reset my password?",
  pageSize: 5,
});

for (const result of results) {
  console.log(result.content);

  // Narrow on __typename to get a reference back to the source
  if (result.__typename === "HelpCenterArticleSearchResult") {
    const article = await result.helpCenterArticle;
    console.log(article.title);
  } else if (result.__typename === "IndexedDocumentSearchResult") {
    const doc = await result.indexedDocument;
    console.log(doc.url);
  }
}
```

The query returns a union of `HelpCenterArticleSearchResult` and `IndexedDocumentSearchResult`. Narrow with `__typename` (or `instanceof`) the same way as any other [union type](/graphql/sdk#union-types) in the SDK.

<Note>
  `pageSize` defaults to 10 and can be between 1 and 50. `searchQuery` must be between 1 and 1000 characters.
</Note>

## Feeding results into a prompt

The `content` field is what you usually want for generation: it's the matched passage, already trimmed to the relevant part of the source. Concatenate the top results into your prompt as context:

```ts theme={null}
const results = await plain.query.searchKnowledgeSources({
  searchQuery: customerQuestion,
  pageSize: 5,
});

const knowledge = results.map((r) => r.content).join("\n\n---\n\n");

const reply = await myModel.generate({
  system: "You are a customer support agent. Answer only from the knowledge below.",
  prompt: `Knowledge:\n\n${knowledge}\n\nQuestion: ${customerQuestion}`,
});
```

From here you can [reply directly, suggest a reply, or post a note](/agents/acting-on-threads) with whatever the model produces. Keeping the source reference (the article title or document URL) alongside each passage lets your agent cite where an answer came from.

## Narrowing the search

The optional `options` argument lets you control what gets searched:

| Option                     | Type                                        | What it does                                                             |
| -------------------------- | ------------------------------------------- | ------------------------------------------------------------------------ |
| `types`                    | `[INDEXED_DOCUMENT \| HELP_CENTER_ARTICLE]` | Restrict to one kind of source. Omit to search both.                     |
| `labelTypeIds`             | `[ID!]`                                     | Only return indexed documents tagged with these label types.             |
| `includeNonCustomerFacing` | `Boolean`                                   | Include help centers marked as not customer-facing. Defaults to `false`. |

For example, to search only your help center articles:

```ts theme={null}
const results = await plain.query.searchKnowledgeSources({
  searchQuery: customerQuestion,
  options: { types: ["HELP_CENTER_ARTICLE"] },
});
```

<Note>
  If you pass `labelTypeIds` without specifying `types`, the search is limited to indexed documents, since labels only apply to them.
</Note>

## Resources

* [GraphQL SDK](/graphql/sdk): the typed client your agent calls
* [Reading threads](/agents/reading-threads): get the customer's question as text to search with
* [Acting on threads](/agents/acting-on-threads): reply, suggest, or note with the answer
* [Help center](/graphql/help-center): manage the articles you're searching over
