---
title: "Generate knowledge suggestions from GitHub pull requests"
description: "The Brainfish Knowledge Suggestions GitHub Action turns your code changes into article suggestions. Each time a pull request is opened, merged, or run manually, the action sends the PR title, description, commits, and the code changes to Brainfish. Large changes are summarized first. Brainfish then analyses the change and suggests updates to your help content, so your documentation keeps pace with your product."
canonical_url: "https://help.brainfi.sh/articles/generate-knowledge-suggestions-from-github-pull-requests-fqZjjnDVOl"
md_url: "https://help.brainfi.sh/articles/generate-knowledge-suggestions-from-github-pull-requests-fqZjjnDVOl.md"
---
# Generate knowledge suggestions from GitHub pull requests

The Brainfish Knowledge Suggestions GitHub Action turns your code changes into article suggestions. Each time a pull request is opened, merged, or run manually, the action sends the PR title, description, commits, and the code changes to Brainfish. Large changes are summarized first. Brainfish then analyses the change and suggests updates to your help content, so your documentation keeps pace with your product.

**Action repository:** [github.com/brainfish-ai/knowledge-suggestions](https://github.com/brainfish-ai/knowledge-suggestions)

**Latest release:** [v1.0.0](https://github.com/brainfish-ai/knowledge-suggestions/releases/tag/v1.0.0). Use it in your workflows as `brainfish-ai/knowledge-suggestions@v1`.


---

## How it works


1. A GitHub workflow runs the action, either on a pull request event, on a push, or manually for a specific PR number.
2. The action collects the PR title and description, labels, commit messages, and the code diff.
3. It drops lock files, generated files, and binary files from the diff. If the remaining diff is small, it is kept in full. If it is large, it is replaced by a summary of the changed files and functions.
4. The action sends the result to Brainfish, optionally targeting a specific collection.
5. The Brainfish Knowledge Discovery Agent analyses the change **asynchronously** and generates article suggestions.
6. Suggestions go to a review queue, so you can check them before anything changes in your knowledge base.

> The action only _triggers_ the suggestion pipeline. It returns a `task_id` and does not wait for the suggestions to be generated.


---

## Before you begin

You need:

* A Brainfish **API token**. Open the [Brainfish Dashboard](https://app.brainfi.sh), go to **Settings → API Tokens**, and click **Create token**. The token starts with `bf_api_`.
* A GitHub repository where you can add workflows and secrets.
* _(Optional)_ The ID of the Brainfish collection you want suggestions to target.

### Store your API token as a GitHub secret


1. In your GitHub repository, go to **Settings → Secrets and variables → Actions**.
2. Click **New repository secret**.
3. Name it `BRAINFISH_API_KEY` and paste your token as the value.

Never put the token directly in a workflow file.

### Find a collection ID (optional)

Open the collection in the Brainfish Dashboard. The collection ID is a UUID, for example `c8b2e30c-d3a7-4314-9dec-d55dcb53b8f5`. If you leave `collection_id` out, Brainfish chooses where suggestions go.


---

## Option 1: Suggest on every pull request

Add this workflow at `.github/workflows/suggest-articles.yml`:

```yaml
name: Suggest articles
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  suggest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: brainfish-ai/knowledge-suggestions@v1
        with:
          api_key: ${{ secrets.BRAINFISH_API_KEY }}
          collection_id: "your-collection-uuid" # optional
```

`fetch-depth: 0` is required in this mode. The action compares your changes against the PR's base commit, so it needs the full git history.


---

## Option 2: Suggest when a pull request is merged

Use the `pr_number` input to fetch a pull request directly from the GitHub API. In this mode you **don't need a checkout step**, and the action can run on any event.

```yaml
name: Suggest articles from merged PR
on:
  pull_request:
    types: [closed]

permissions:
  pull-requests: read

jobs:
  suggest:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    steps:
      - uses: brainfish-ai/knowledge-suggestions@v1
        with:
          api_key: ${{ secrets.BRAINFISH_API_KEY }}
          pr_number: ${{ github.event.pull_request.number }}
```

Suggesting only on merge is a good way to avoid suggestions for work that never ships.


---

## Option 3: Run manually for any pull request

This workflow adds a **Run workflow** button in GitHub. Enter a PR number and the action generates suggestions for it. It's useful for back-filling suggestions from older PRs.

```yaml
name: Suggest articles for a PR
on:
  workflow_dispatch:
    inputs:
      pr_number:
        description: "Pull request number"
        required: true

jobs:
  suggest:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: read
    steps:
      - uses: brainfish-ai/knowledge-suggestions@v1
        with:
          api_key: ${{ secrets.BRAINFISH_API_KEY }}
          pr_number: ${{ inputs.pr_number }}
```


---

## Option 4: Suggest on every push to main

```yaml
name: Suggest articles
on:
  push:
    branches: [main]

jobs:
  suggest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: brainfish-ai/knowledge-suggestions@v1
        with:
          api_key: ${{ secrets.BRAINFISH_API_KEY }}
```


---

## What gets sent to Brainfish

The action sends a single Markdown document with this structure:

```markdown
# Changes

## <Pull request title>

Pull request: <link>
Labels: <labels>

<Pull request description>

## Commits

### <Commit subject>
<Commit body>

## Diff            (or "## Diff summary" for large changes)

<code diff or summary>
```

The PR title, description, and labels give Brainfish the _why_ behind a change, while the commits and diff show _what_ changed. **Write clear PR descriptions.** They directly improve the quality of the suggestions, especially for large changes where only a summary of the code is sent.

### Lock files and generated files are never sent

These files are dropped from the diff before anything is sent:

* **Lock files:** `package-lock.json`, `npm-shrinkwrap.json`, `pnpm-lock.yaml`, `go.sum`, and any `*.lock` file such as `yarn.lock`, `Cargo.lock`, `poetry.lock`, `uv.lock`, `Gemfile.lock`, `composer.lock`, or `Podfile.lock`
* **Generated or minified files:** `*.min.js`, `*.min.css`, `*.map`, `*.snap`
* **Build output and dependencies:** anything under `dist/`, `build/`, `node_modules/`, or `vendor/`
* **Binary files** such as images

The names of dropped files are still listed, so Brainfish knows they changed. If a pull request _only_ changes these files, for example an automated dependency update, nothing is sent.

### Large pull requests are summarized

After noise files are dropped, the action counts the lines in the remaining diff:

* **1,000 lines or fewer:** the full diff is sent.
* **More than 1,000 lines:** the raw code is left out and a summary is sent instead.

The summary is built directly from the diff, without AI, and contains:

* The total number of files changed and lines added and removed
* A table of changed files with their status (added, modified, deleted, or renamed) and line counts, largest changes first
* The functions, classes, or sections touched in each file

For example:

```markdown
## Diff summary

The full diff is 6004 lines, which is over the 1000-line limit, so only a summary is included.

Excluded 1 lock, generated or binary file(s): `go.sum`

Files changed: 70 (+3792 / -575)

### Files

| Status   | File            | Lines       |
|----------|-----------------|-------------|
| added    | `api/request.go` | +443 / -0  |
| modified | `api/client.go`  | +163 / -4  |

### Changed areas

#### `api/client.go`

- `func HandleHTTPError(resp *http.Response) error {`
```

To change the limit, set the `max_diff_lines` input. For example, `max_diff_lines: 3000` sends more diffs in full, and `max_diff_lines: 0` always sends a summary instead of code.

> For small changes, the code diff is sent to Brainfish. Don't run the action on repositories where that content shouldn't leave GitHub, or set `max_diff_lines: 0` so only file names and function names are sent.


---

## Inputs

| Input | Required | Description |
|----|----|----|
| `api_key` | Yes | Brainfish API token used for authentication |
| `collection_id` | No | Collection ID to target for suggestions |
| `pr_number` | No | Pull request number to generate suggestions from. Fetched via the GitHub API, so no checkout is needed |
| `repository` | No | Repository (`owner/name`) that contains the PR. Only used with `pr_number`. Defaults to the current repository |
| `github_token` | No | Token used to read the PR. Only used with `pr_number`. Defaults to the workflow's `github.token` |
| `base` | No | Base commit SHA to generate the diff from |
| `max_diff_lines` | No | Diffs up to this many lines are sent in full; larger diffs are replaced by a summary. Defaults to `1000` |
| `api_url` | No | Brainfish API base URL. Defaults to `https://api.brainfi.sh` |

## Outputs

| Output | Description |
|----|----|
| `task_id` | The task ID of the triggered suggestion pipeline |
| `status` | The status of the suggestion request |


---

## How the action decides what to compare

The action picks the source of the change in this order:


1. `pr_number` is set: the PR's content and diff are fetched from the GitHub API.
2. `base` is set: the diff between `base` and the current commit.
3. The workflow runs on a **pull request**: the diff against the PR's base branch.
4. The workflow runs on a **push**: the diff against the commit before the push.
5. Otherwise: the diff against the previous commit.

If there are no relevant changes to send, the action skips the request and prints a warning. It does not fail the workflow.


---

## Versions and updates

The action follows semantic versioning. Choose how you reference it in your workflow:

| Reference | What you get | Use it when |
|----|----|----|
| `brainfish-ai/knowledge-suggestions@v1` | The latest `v1.x` release. You receive fixes and new features automatically, with no breaking changes | Recommended for most teams |
| `brainfish-ai/knowledge-suggestions@v1.0.0` | Exactly version 1.0.0. Nothing changes until you update the reference | Your organization requires pinned versions |

See the [release notes](https://github.com/brainfish-ai/knowledge-suggestions/releases) for what changed in each version.


---

## Limits and good to know

* **Very large pull requests:** With `pr_number`, GitHub's API does not return diffs larger than 300 files or 20,000 lines, so the action can't summarize them. For PRs that size, use a checkout with `fetch-depth: 0` and the `base` input instead.
* **Duplicate requests:** Submitting the same content again within 5 minutes can return a `409 conflict`. Wait a few minutes and re-run.
* **Rate limit:** The Brainfish API allows 25 requests per minute.
* **Pull requests from forks:** GitHub does not give repository secrets to workflows triggered by forks, so `BRAINFISH_API_KEY` is empty and the request fails. Use the merged-PR trigger (Option 2) so the workflow runs in your repository after you merge.


---

## Troubleshooting

| Problem | Likely cause | What to do |
|----|----|----|
| `Unable to resolve action brainfish-ai/knowledge-suggestions@...` | The version reference is misspelled | Use `@v1` or an exact release tag such as `@v1.0.0` |
| `Base ref ... does not exist` | The checkout is shallow | Add `fetch-depth: 0` to `actions/checkout` |
| `pr_number must be a number` | The value isn't a plain integer | Pass only the PR number, such as `42` |
| `Failed to fetch the diff for PR` | The PR is over GitHub's diff size limit, or the token can't read it | Use `base` with a full checkout, or grant `pull-requests: read` |
| `API request failed (401)` | Missing or invalid Brainfish token | Check the `BRAINFISH_API_KEY` secret and create a new token if needed |
| `API request failed (409)` | Duplicate request within 5 minutes | Wait 5 minutes and run again |
| `API request failed (429)` | Rate limit reached | Wait a moment and retry |
| `No relevant changes ... after excluding lock, generated and binary files` warning | The change only touched lock, generated, or binary files, or there was no change at all | Nothing to do. No request was sent |

If an error includes a `requestId`, share it with Brainfish support for faster debugging.


---

## FAQ

**Do suggestions change my published articles automatically?** No. Suggestions go to a review queue so you can approve or reject them first.

**Can I target a specific collection?** Yes. Set `collection_id` to the collection's UUID.

**Do I need a checkout step?** Only when you don't use `pr_number`. With `pr_number` the action reads the PR directly from GitHub.

**Which version should I use?** Use `@v1` to get fixes automatically. Pin to an exact release such as `@v1.0.0` only if your organization requires it.

**Are lock files sent to Brainfish?** No. Lock files, generated files, build output, and binary files are always dropped. Only their names are listed.

**What happens with a very large pull request?** If the diff is over 1,000 lines after dropping lock and generated files, only a summary of the changed files and functions is sent. Change the limit with `max_diff_lines`.

**Can I use this with private repositories?** Yes. The default `github.token` can read PRs in the same repository. To read a PR from a different private repository, set `repository` and pass a `github_token` that has access to it.

**How do I see the result of a run?** Use the `task_id` output to track the request. Suggestions appear in Brainfish once the Knowledge Discovery Agent finishes.


---

## Related articles

* [Brainfish MCP Server](/articles/brainfish-mcp-server-4wP3c66Aum): generate suggestions from AI assistants such as Cursor and Claude
* [Using Import, Export, and API Tokens](/articles/using-import-export-and-api-tokens-vwijmaG0Tx)
* [How to Review and Approve Generated Answers](/articles/how-to-review-and-approve-generated-answers-nkHVRkm91r)
