> For the complete documentation index, see [llms.txt](https://docs.imerit.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.imerit.net/plugins/first-party-ango-plugins/chatgpt.md).

# ChatGPT

## Overview

The ChatGPT Plugin enables seamless integration of OpenAI’s language and multimodal models into your annotation workflows on Ango Hub. This plugin is designed to support a wide range of use cases, including text processing, image understanding, named entity recognition (NER), and audio processing.

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th align="center"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td align="center">ChatGPT</td><td data-object-fit="contain"><a href="https://angohub-docs-assets.s3.eu-central-1.amazonaws.com/plugin-icons-banners/chatgpt.png">https://angohub-docs-assets.s3.eu-central-1.amazonaws.com/plugin-icons-banners/chatgpt.png</a></td></tr></tbody></table>

## Plugin Functionality

The ChatGPT Plugin processes assets and generates outputs based on the selected mode, model, and prompt configuration.

* **Text Processing:** Generate summaries, classifications, structured outputs, or rewritten content from text inputs.
* **Image Understanding:** Analyze visual content and generate descriptions, extract text (OCR-style), or answer questions about images.
* **Named Entity Recognition (NER):** Identify and extract structured entities such as names, organizations, locations, and dates from text.
* **Audio Processing:** Transcribe, summarize, or analyze audio content using prompt-based instructions.

<figure><img src="/files/FDzpuC1WfmiyLmRodJWW" alt=""><figcaption></figcaption></figure>

#### Prompt Construction

The plugin dynamically constructs the final prompt using:

```
[prompt_prefix] + [input content] + [prompt_suffix]
```

* **prompt\_prefix** defines the task or instruction
* **Input content** comes from the asset or annotation
* **prompt\_suffix** refines output format or constraints

This flexible structure allows you to standardize instructions across all assets.

### Supported Modes

#### Workflow-1: Text Processing (Asset)

<div data-with-frame="true"><figure><img src="/files/VdovFtnOKIuAC1yaaECa" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/Lsq9CiMtyHryL4b0sdeq" alt="" width="563"><figcaption></figcaption></figure>

```json
{
  "mode": "text-prompt",
  "model_name": "gpt-4.1-nano",
  "openai_api_key": "<YOUR_OPENAI_API_KEY>",
  "prompt_prefix": "Summarize the following text in one sentence: ",
  "prompt_suffix": ""
}
```

<details>

<summary>Category Schema</summary>

```json
{
  "tools": [],
  "classifications": [
    {
      "schemaId": "746971b8c6130e3e67aa164",
      "tool": "text",
      "title": "Summary",
      "required": false,
      "classifications": [],
      "multiple": false,
      "options": [],
      "shortcutKey": "1",
      "frameSpecific": false,
      "richText": false,
      "katex": false,
      "katexBottom": true,
      "regex": ""
    }
  ],
  "relations": []
}
```

</details>

#### Workflow-2: Text Processing (Text Tool)

<div data-with-frame="true"><figure><img src="/files/HboXmmh5WatbMqIe8lll" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/1hyBZv2VOgWTLUgOzqRi" alt="" width="563"><figcaption></figcaption></figure>

<pre class="language-json"><code class="lang-json">{
  "mode": "text-prompt",
<strong>  "model_name": "gpt-4.1-nano",
</strong>  "openai_api_key": "&#x3C;YOUR_OPENAI_API_KEY>",
  "prompt_prefix": "What is the capital of ",
  "prompt_suffix": "? Provide only the city name."
}
</code></pre>

<details>

<summary>Category Schema</summary>

```json
{
  "tools": [],
  "classifications": [
    {
      "schemaId": "0dbcd5baf0e3bdd94a43241",
      "tool": "text",
      "title": "Input Prompt",
      "required": false,
      "classifications": [],
      "multiple": false,
      "options": [],
      "shortcutKey": "1",
      "frameSpecific": false,
      "richText": false,
      "katex": false,
      "katexBottom": true,
      "regex": ""
    },
    {
      "schemaId": "cfa74f8424770119a0cd684",
      "tool": "text",
      "title": "Response",
      "required": false,
      "classifications": [],
      "multiple": false,
      "options": [],
      "shortcutKey": "2",
      "frameSpecific": false,
      "richText": false,
      "katex": false,
      "katexBottom": true,
      "regex": ""
    }
  ],
  "relations": []
}
```

</details>

#### Workflow-3: Image Understanding

<div data-with-frame="true"><figure><img src="/files/8bgOyIEBpeQXR2IJumZa" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/eYCq709S5WEce1TsTdju" alt="" width="563"><figcaption></figcaption></figure>

```json
{
  "mode": "image-prompt",
  "model_name": "gpt-4.1-nano",
  "openai_api_key": "<YOUR_OPENAI_API_KEY>",
  "prompt_prefix": "Describe this image in detail, including objects, colors, and environment.",
  "prompt_suffix": ""
}
```

<details>

<summary>Category Schema</summary>

```json
{
  "tools": [],
  "classifications": [
    {
      "schemaId": "48ad366ed63db5859587335",
      "tool": "text",
      "title": "Response",
      "required": false,
      "classifications": [],
      "multiple": false,
      "options": [],
      "shortcutKey": "1",
      "frameSpecific": false,
      "richText": false,
      "katex": false,
      "katexBottom": true,
      "regex": ""
    }
  ],
  "relations": []
}
```

</details>

#### Workflow-4: Named Entity Recognition

<div data-with-frame="true"><figure><img src="/files/yiSXRBpXLiLPrFdJp3HY" alt=""><figcaption></figcaption></figure></div>

```json
{
  "mode": "ner",
  "model_name": "gpt-4.1-nano",
  "openai_api_key": "<YOUR_OPENAI_API_KEY>",
  "prompt_prefix": "",
  "prompt_suffix": ""
}
```

{% hint style="info" %}
In the "ner" mode, class mapping is not required. The plugin automatically assigns entity labels based on the project's category schema, so no manual mapping configuration is needed.
{% endhint %}

<details>

<summary>Category Schema</summary>

```json
{
  "tools": [
    {
      "schemaId": "796d1292cfbf6229e793571",
      "tool": "ner",
      "title": "Adjective",
      "required": false,
      "classifications": [],
      "multiple": false,
      "color": "#f44336",
      "shortcutKey": "1"
    },
    {
      "schemaId": "fd74cf3157e7805f080f405",
      "tool": "ner",
      "title": "Verb",
      "required": false,
      "classifications": [],
      "multiple": false,
      "color": "#03a9f4",
      "shortcutKey": "2"
    },
    {
      "schemaId": "c956228f2b8e2effebac917",
      "tool": "ner",
      "title": "Noun",
      "required": false,
      "classifications": [],
      "multiple": false,
      "color": "#9c27b0",
      "shortcutKey": "3"
    }
  ],
  "classifications": [],
  "relations": []
}
```

</details>

#### Workflow-5: Speech-to-Text

<div data-with-frame="true"><figure><img src="/files/rSuV9xoAnyLkhmeBlev9" alt=""><figcaption></figcaption></figure></div>

```json
{
  "mode": "audio-prompt",
  "model_name": "whisper-1",
  "openai_api_key": "<YOUR_OPENAI_API_KEY>",
  "prompt_prefix": "",
  "prompt_suffix": ""
}
```

<figure><img src="/files/XFfYjoQTtzcpckHKNO9v" alt="" width="563"><figcaption></figcaption></figure>

<details>

<summary>Category Schema</summary>

```json
{
  "tools": [
    {
      "schemaId": "8280042f0f98b800b6cc860",
      "tool": "ner",
      "title": "Transcription Entity",
      "required": false,
      "classifications": [
        {
          "schemaId": "f9a4e85dc1d215022e31013",
          "tool": "text",
          "title": "Transcription Text",
          "required": false,
          "classifications": [],
          "multiple": false,
          "options": [],
          "parentToolType": "ner",
          "parentToolId": "8280042f0f98b800b6cc860",
          "shortcutKey": "3",
          "frameSpecific": false,
          "richText": false,
          "katex": false,
          "katexBottom": true,
          "regex": ""
        }
      ],
      "multiple": false,
      "color": "#f44336",
      "shortcutKey": "1"
    }
  ],
  "classifications": [
    {
      "schemaId": "0912500394b493f68cdd406",
      "tool": "text",
      "title": "Full Transcription Text",
      "required": false,
      "classifications": [],
      "multiple": false,
      "options": [],
      "shortcutKey": "2",
      "frameSpecific": false,
      "richText": false,
      "katex": false,
      "katexBottom": true,
      "regex": ""
    }
  ],
  "relations": []
}
```

</details>

### Supported Data Types <a href="#supported-data-types" id="supported-data-types"></a>

* Audio (*audio-prompt*)
* Image (*image-prompt*)
* Text (*NER, text-prompt+asset source*)
* Any Data Type (*text-prompt+text annotation source*)

### Supported Annotation Tools <a href="#supported-annotation-tools" id="supported-annotation-tools"></a>

* Text
* Entity
* Radio
* Checkbox
* Single-Select Dropdown
* Multi-Select Dropdown

## Plugin Configuration <a href="#plugin-configuration" id="plugin-configuration"></a>

The **Overwrite** setting in model plugins controls whether existing annotations are replaced or kept. When enabled, the plugin replaces all existing annotations with new model predictions; when disabled, it simply adds the new results without deleting what’s already there.

In the **class mapping**, the ChatGPT plugin uses two fields: “Prompt Body” and “Reply Text”.

* **Prompt Body** refers to the text tool from which the main content of the prompt is retrieved.
* **Reply Text** refers to the text tool where the ChatGPT response will be written.

<figure><img src="/files/GMk3lcYafnmqn0kyAHOk" alt=""><figcaption><p>ChatGPT plugin integration to the workflow</p></figcaption></figure>

You may vary a number of settings related to the model plugin from the **Config JSON** field. Each option is detailed below:

```json
{
  "mode": "text-prompt",
  "model_name": "gpt-4.1-nano",
  "openai_api_key": "",
  "prompt_prefix": "",
  "prompt_suffix": "",
  "model_parameters": {
    "reasoning_effort": "none",
    "temperature": 0.7,
    "max_output_tokens": 1000
  }
}
```

* **"mode":** Defines the operating mode of the plugin. The selected mode determines the type of input the plugin processes and the kind of task it performs.
  * Options:
    * <kbd>"text-prompt"</kbd>
    * <kbd>"image-prompt"</kbd>
    * <kbd>"ner"</kbd>
    * <kbd>"audio-prompt"</kbd>
  * Example:
    * <kbd>"mode": "text-prompt"</kbd>&#x20;

* **"model\_name":** Specifies the OpenAI model that the plugin will use for inference. See the OpenAI [models](https://developers.openai.com/api/docs/models) and [pricing](https://developers.openai.com/api/docs/pricing) pages for available options and details.
  * Options:
    * <kbd>"gpt-5.4"</kbd>
    * <kbd>"gpt-5.4-mini"</kbd>
    * <kbd>"gpt-5.4-nano"</kbd>
    * <kbd>"gpt-5.4-pro"</kbd>
    * <kbd>...</kbd>
  * Example:
    * <kbd>"model\_name": "gpt-4.1-nano"</kbd>

* **"openai\_api\_key":** Specifies the OpenAI API key used to authenticate requests sent by the plugin. You can generate and manage your API keys from the [OpenAI dashboard](https://platform.openai.com/settings/organization/api-keys).
  * Example:
    * <kbd>"openai\_api\_key": "\<YOUR\_OPENAI\_API\_KEY>"</kbd>&#x20;

* **"prompt\_prefix":** A text string added before the main input content when constructing the prompt sent to the model.
  * Example:
    * <kbd>"prompt\_prefix": "Extract all company names from the following text:"</kbd>

* **"prompt\_suffix":** A text string added after the main input content when constructing the prompt sent to the model.
  * Example:
    * <kbd>"prompt\_suffix": "Return the result as a JSON array."</kbd>

* **"reasoning\_effort":** Controls how much internal reasoning the model performs before generating a response. Higher reasoning effort can improve performance on complex tasks but may increase latency and token usage.
  * Options:
    * <kbd>"none"</kbd>
    * <kbd>"minimal"</kbd>
    * <kbd>"low"</kbd>
    * <kbd>"medium"</kbd>
    * <kbd>"high"</kbd>
    * <kbd>"xhigh"</kbd>&#x20;

{% hint style="danger" %}
Not all OpenAI models support reasoning.
{% endhint %}

{% hint style="warning" %}
Enabling `reasoning_effort` disables temperature control. OpenAI reasoning models determine their own reasoning strategy and do not allow customization of the `temperature` parameter. Any provided temperature value will be ignored.
{% endhint %}

* **"temperature":** Controls the randomness and creativity of the model’s responses.
  * Example:
    * <kbd>"temperature": 0.7</kbd>

* **"max\_output\_tokens":** Defines the maximum number of tokens that the model can generate in its response.
  * Example:
    * <kbd>"max\_output\_tokens": 1000</kbd>
