---
title: "AI Assistant agents | Nutrient"
canonical_url: "https://www.nutrient.io/guides/ai-assistant/features/agents/"
md_url: "https://www.nutrient.io/guides/ai-assistant/features/agents.md"
last_updated: "2026-08-24T00:00:00.000Z"
description: "Learn about the AI Assistant agents available out of the box and how to customize your own agent for document workflows."
---

# Agents

AI Assistant provides agents that determine the capabilities and behavior of your AI-powered document workflows. You can use one of the built-in agents out of the box, or customize your own agent for specific use cases.

## Selecting an agent

Select an agent using the `agentId` field in your AI Assistant configuration:

```js

PSPDFKit.load({
  aiAssistant: {
    sessionId: 'session123',
    jwt: 'your-jwt-token',
    backendUrl: 'http://localhost:4000',
    agentId: 'agentic', // Choose: 'chat', 'agentic', or 'base'.
  },...
});

```

## Built-in agents

AI Assistant includes three agents out of the box, each optimized for different use cases.

### Agentic (default)

The `agentic` agent provides full autonomous capabilities with read and write access to documents. This is the default agent when no `agentId` is specified.

**Capabilities:**

- Read and search document content

- Summarize and answer questions about documents

- Add, modify, and delete annotations

- Fill form fields

- Apply redactions

- Execute multistep document workflows

**Use cases:**

- Document editing and review workflows

- Automated form filling

- Compliance and redaction tasks

- Interactive document preparation

```js

PSPDFKit.load({
  aiAssistant: {
    sessionId: 'session123',
    jwt: 'your-jwt-token',
    backendUrl: 'http://localhost:4000',
    agentId: 'agentic',
  },
});

```

### Chat

The `chat` agent provides a read-only Q&A mode optimized for document analysis without modification capabilities.

**Capabilities:**

- Read and search document content

- Summarize documents

- Extract data and answer questions

- Provide document insights and analysis

**Limitations:**

- Cannot add or modify annotations

- Cannot fill forms

- Cannot apply redactions

**Use cases:**

- Customer-facing document viewers where editing is restricted

- Research and analysis workflows

- Document comprehension assistants

- Secure environments where document integrity is critical

```js

PSPDFKit.load({
  aiAssistant: {
    sessionId: 'session123',
    jwt: 'your-jwt-token',
    backendUrl: 'http://localhost:4000',
    agentId: 'chat',
  },
});

```

### Base

The `base` agent provides a minimal configuration intended for full customization. Use this agent when you want complete control over behavior through the [agent configuration](https://www.nutrient.io/guides/ai-assistant/features/agent-configuration.md).

**Capabilities:**

- All tools enabled by default, customizable through `toolApproval` settings

- Full customization through `agentConfiguration`

- Suitable for building specialized agents

**Use cases:**

- Building an agent with only a subset of available tools

- Creating a focused agent for a single task, such as document summarization

- Overriding default behaviors that preset agents don’t allow

```js

PSPDFKit.load({
  aiAssistant: {
    sessionId: 'session123',
    jwt: 'your-jwt-token',
    backendUrl: 'http://localhost:4000',
    agentId: 'base',
    agentConfiguration: {
      systemPromptTemplate: 'You are a specialized legal document analyst...',
      skills: [
        {
          name: 'contract-review',
          description: 'Analyze contracts for key terms',
          content: 'Focus on liability and payment terms...',
        },
      ],
      toolApproval: {
        defaults: { default: 'allow', write: 'deny' },
      },
    },
  },
});

```

## Customizing agents

The built-in agents provide a starting point, but you can further customize behavior using the [agent configuration](https://www.nutrient.io/guides/ai-assistant/features/agent-configuration.md). Configuration options layer on top of the selected agent:

```js

PSPDFKit.load({
  aiAssistant: {
    sessionId: 'session123',
    jwt: 'your-jwt-token',
    backendUrl: 'http://localhost:4000',
    agentId: 'agentic', // Start with full capabilities and skills.
    agentConfiguration: {
      // Require approval for write operations.
      toolApproval: {
        defaults: {
          default: 'allow',
          read: 'allow',
          write: 'ask',
        },
      },
      // Add domain-specific guidance.
      systemPromptTemplate: 'You are a legal document assistant...',
    },
  },
});

```

## Saved agents

The agents above are chosen per session from the client. You can also save a custom agent and reuse it with a stable ID. A saved agent behaves like a built-in preset: Reference it by ID instead of sending the full `agentConfiguration` on every load.

Saved agents live under the AI Assistant REST API base path `/inference/api/v2`. They use the same JSON Web Token (JWT) authentication as the rest of the API. The [`agents` JWT claim](#authorizing-saved-agents) controls who can create, run, and manage them.

### Create a saved agent

Send a `POST` request to `/inference/api/v2/agents`. Set `agent_id` to the slug that your application will use to select the agent. Define the agent in `context` with the fields from the [agent configuration](https://www.nutrient.io/guides/ai-assistant/features/agent-configuration.md) guide.

```bash

curl -X POST "$BACKEND_URL/inference/api/v2/agents" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "contract-review",
    "name": "Contract review assistant",
    "description": "Reviews contracts for key terms and risks.",
    "context": {
      "systemPromptTemplate": "You are a legal document analyst. Cite the clause number for every finding.",
      "toolApproval": { "defaults": { "default": "allow", "write": "ask" } }
    }
  }'

```

Request body fields:

- `agent_id` (required) — Lowercase letters, numbers, and single dashes, up to 255 characters. It cannot use a UUID format or change after creation.

- `name`, `description` (optional) — Display metadata.

- `context` (optional) — The agent definition.

- `metadata` (optional) — Arbitrary key-value data.

A successful request returns `201` with the saved agent at `version: 1`.

Create responses use these status codes:

| Status | Condition                                              |
| ------ | ------------------------------------------------------ |
| `201`  | Agent created at version 1                             |
| `400`  | Validation error                                       |
| `401`  | Authentication failed                                  |
| `403`  | The `agents` claim doesn’t grant `create`              |
| `409`  | `agent_id` already taken, or reserved by a built-in ID |

### Invoke a saved agent

Select a saved agent by its `agent_id`, the same way you select a preset. From the client, set `agentId` to the saved agent’s slug:

```js

PSPDFKit.load({
  aiAssistant: {
    sessionId: 'session123',
    jwt: 'your-jwt-token',
    backendUrl: 'http://localhost:4000',
    agentId: 'contract-review', // Your saved agent's ID.
  },
});

```

To run the agent through the REST API, pass `agent_id` to a run endpoint such as `POST /inference/api/v2/runs/stream`:

```bash

curl -X POST "$BACKEND_URL/inference/api/v2/runs/stream" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "contract-review",
    "input": { "messages": [{ "role": "human", "content": "Summarize the termination clauses." }] }
  }'

```

Invoking a saved agent requires `run` access in the `agents` claim.

### Versioning

Each update creates a new version of the saved agent and makes that version current.

Update an agent with `PATCH /inference/api/v2/agents/:agent_id`. Omitted top-level fields keep their current values. The request replaces the complete `context` or `metadata` object when you include either field. The `agent_id` can’t change.

```bash

curl -X PATCH "$BACKEND_URL/inference/api/v2/agents/contract-review" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "context": {
      "systemPromptTemplate": "You are a senior legal analyst. Cite clause numbers and flag uncapped liability.",
      "toolApproval": { "defaults": { "default": "allow", "write": "ask" } }
    }
  }'

```

Manage saved agents with these endpoints:

- List available versions with `POST /inference/api/v2/agents/:agent_id/versions`.

- Make an existing version current with `POST /inference/api/v2/agents/:agent_id/latest` and a `{ "version": <n> }` body.

- Delete an agent and its versions with `DELETE /inference/api/v2/agents/:agent_id`.

Built-in presets can’t be updated or deleted.

For access control, see [authorizing saved agents](#authorizing-saved-agents) below.

### Credentials in saved agents

Do not include provider credentials in a saved agent.

Requests that include provider credentials in `modelServices` — such as `apiKey`, `accessKeyId`, or `secretAccessKey` — return `400`.

Configure credentials in the deployment’s model configuration with environment variables such as `OPENAI_API_KEY`. To supply credentials for one run, send them in `context.modelServices` on the run request. The JWT must grant the provider through [`agent_configuration.model_services.providers`](https://www.nutrient.io/guides/ai-assistant/viewer-integration/client-authentication/generate-a-jwt/#token-requirements).

The same guard covers HTTP MCP servers. Saving an agent returns `400` if its `mcps` set request `headers` (such as `Authorization` or `X-API-Key`) or embed credentials in a server `url` (userinfo, as in `https://user:pass@host`). A plain endpoint URL or a non-secret query parameter still saves.

Send MCP authentication with each run request in the per-request agent configuration, the same way you supply per-run provider credentials. Per-request MCP `headers` are never persisted.

## Authorizing saved agents

Use the `agents` JWT claim to control which saved agents a client can read, run, update, or delete, and whether it can create saved agents. A token without a matching grant can only read and run the built-in `chat`, `agentic`, and `base` presets.

For the claim format, permission behavior, and examples, refer to the guide on [saved-agent authorization](https://www.nutrient.io/guides/ai-assistant/viewer-integration/client-authentication/generate-a-jwt.md#saved-agent-authorization).

## What’s next

- [Agent configuration](https://www.nutrient.io/guides/ai-assistant/features/agent-configuration.md) — Customize system prompts, skills, and tool approval policies.

- [Saved-agent authorization](https://www.nutrient.io/guides/ai-assistant/viewer-integration/client-authentication/generate-a-jwt.md#saved-agent-authorization) — Authorize access to saved agents.

- [Nutrient Web SDK integration](https://www.nutrient.io/guides/ai-assistant/viewer-integration/nutrient-web-sdk.md) — Connect AI Assistant with your document viewer.
---

## Related pages

- [Agent configuration](/guides/ai-assistant/features/agent-configuration.md)
- [AI text comparison](/guides/ai-assistant/features/ai-text-comparison.md)
- [Subagents](/guides/ai-assistant/features/subagents.md)

