Book a Demo

Cabinee AI Integration Guide

Purpose

This documentation describes AI (LLM) integration in Cabinee:

  • automatic text processing
  • ticket classification and routing
  • extraction of structured data
  • generation of emails, comments, and documents
  • preparation of data for decision-making in BPMN

The document is intended for:

  • DevOps engineers
  • system administrators
  • process analysts and architects

Why it is needed

AI in Cabinee is used for:

  • automatic classification of incoming requests
  • extraction of structured data from text
  • preparation of data for decision-making in BPMN
  • generation of customer replies
  • preparation of internal comments
  • generation of task descriptions
  • creation of text documents and templates
  • reducing the load on operators

Example:

“Please issue an invoice for the license payment” → classification = PAYMENT_REQUEST


Architecture

BPMN Process ↓ External Task (ai.extract / ai.generate) ↓ unibpm-integration-runtime ↓ unibpm-external-task-ai ↓ unibpm-ai-core ↓ LLM Provider ↓ OpenAI | YandexGPT


Main components

BPMN

  • defines the business process
  • calls AI through a Service Task

unibpm-integration-runtime

  • executes External Tasks
  • manages workers

unibpm-external-task-ai

  • implements AI handlers
  • supports the following actions:
    • ai.extract
    • ai.generate
    • (in the future) ai.decide

unibpm-ai-core

  • interaction with the LLM
  • prompt handling
  • a unified result format

LLM Provider

Cabinee supports connecting different LLM providers.

Currently supported:

  • OpenAI
  • YandexGPT

The provider is selected in the application settings.

Each provider requires its own connection parameters (API key, model, and so on).


How it works

  1. BPMN calls a Service Task (ai.extract or ai.generate)
  2. The External Task Worker receives the job
  3. The prompt is loaded (inline or by promptKey)
  4. A request to the LLM is built
  5. A response is received
  6. The result is stored in process variables

Execution context (AI Context)

Why context is needed

In some scenarios, AI must analyze not only the input text but also related business data:

  • ticket data (Ticket)
  • comments (Comment)
  • attachments (Attachment)

This makes it possible to:

  • improve classification accuracy
  • take the request history into account
  • analyze documents (resumes, contracts, and so on)

How to enable context

Context is enabled through Extension Properties in BPMN:

uni.context=true
uni.context.comments.limit=0
uni.context.attachments.limit=3

What happens at runtime

If uni.context=true, the runtime:

  1. Resolves ticketId from the External Task
  2. Loads ticket data (Ticket)
  3. Loads ticket comments
  4. Loads attachments (metadata)
  5. Passes the context to the AI handler

Limits

  • uni.context.comments.limit — number of comments (default: 0)
  • uni.context.attachments.limit — number of attachments (default: 0)
  • a value of 0 means the corresponding data is not loaded into the context
  • a value of N > 0 means no more than N objects are loaded

Working with attachments

Only attachment metadata is passed into the AI context.

To retrieve the content, use the API:

GET /api/attachment/read/{attachmentId}

In a typical scenario:

  1. relevant attachments are selected (for example, a PDF resume)
  2. the content is extracted
  3. it is converted to plain text
  4. it is added to the prompt

Practical example

Using context to process a ticket:

  • input: request text
  • context:
    • ticket (description, fields)
    • comments (discussion history)
    • attachments (resume, documents)

→ AI can:

  • classify the ticket
  • extract data from attachments
  • prepare a summary

Recommendations

  • enable context only when needed
  • limit the number of attachments
  • limit the number of comments
  • do not pass large files directly
  • use preprocessing (PDF → text)

Patterns

AI Extract

text → structured JSON

AI Generate

input + prompt → generated text

Used for:

  • preparing emails
  • preparing comments
  • generating task descriptions
  • generating documents and templates

The result is text produced by the LLM.


Configuration

application.yaml

unibpm:
  integration:
    connectors:
      ai:
        enabled: true

  ai:
    provider: openai

    openai:
      api-key: ${OPENAI_API_KEY}
      base-url: https://api.openai.com
      model: gpt-5.4-mini
      temperature: 0.2
      max-tokens: 1000
      timeout-seconds: 30

Selecting an LLM provider

Cabinee supports several LLM providers.

The selection is made through the property:

unibpm.ai.provider=openai

Supported values:

  • openai
  • yandex

Example YandexGPT configuration:

unibpm:
  ai:
    provider: yandex

    yandex:
      api-key: ${YANDEX_API_KEY}
      project-id: ${YANDEX_PROJECT_ID}
      base-url: https://ai.api.cloud.yandex.net
      model: yandexgpt-5.1/latest
      temperature: 0.3
      max-tokens: 1000
      timeout-seconds: 30

Usage in BPMN

AI Extract

uni.connector=ai
uni.action=extract
uni.version=v1

AI Generate

uni.connector=ai
uni.action=generate
uni.version=v1

Extension Properties

Required

uni.connector=ai
uni.action=<extract|generate>

Prompt configuration

ai.in.promptKey=inbox-triage

or

ai.in.promptText=Classify incoming request

Optionally, you can also use:

ai.in.promptVersion=v1

Input data source

ai.in.input=${input}

or

uni.context=true

Result schema

ai.in.schema=${schema}

Output variable

ai.out.result=classificationResult

Additional model parameters

ai.in.model=gpt-5.4-mini
ai.in.temperature=0.2
ai.in.maxTokens=1000

These parameters are optional.

If they are not specified, the values from application.yaml are used.

Model parameter details

  • ai.in.model — identifier of the LLM model used to execute the request.

  • ai.in.temperature — how varied the model responses are.

    • 0.0–0.3 — the most predictable and stable responses.
    • 0.4–0.7 — moderate variability.
    • 0.8+ — more creative and less predictable responses.

    For classification and data extraction, values in the 0.0–0.3 range are recommended.

  • ai.in.maxTokens — the maximum number of tokens the model may generate in the response. This limits the result size and helps control request cost.

A token is a conventional unit of text used by LLMs to measure the volume of input and output data.


Input data source (input)

AI operations (extract and generate) can receive input data in two ways.

Option 1. Process variable

ai.in.input=${input}

In this case, the contents of the input process variable are passed to AI.

Option 2. Ticket context

uni.context=true

If the ai.in.input property is missing or empty, the input data is automatically built from the ticket context (provided that uni.context=true is enabled).

Data source priority:

  1. ai.in.input
  2. uni.context=true

If no data source is specified, the task fails with a configuration error.

Context format

When uni.context=true is used, AI receives a structure of the following form:

{
  "ticketId": "...",
  "ticket": { ... },
  "comments": [
    {
      "id": "...",
      "body": "User comment"
    }
  ],
  "attachments": [
    {
      "id": "...",
      "fileName": "resume.pdf",
      "contentType": "application/pdf"
    }
  ]
}

Result schema (schema)

This section applies only to the ai.extract operation.

The ai.in.schema property defines the JSON structure that the model must return.

The ai.in.schema property is used only for the ai.extract operation.

The result schema is not used for the ai.generate operation.

Example:

{
  "type": "object",
  "properties": {
    "classification": {
      "type": "string"
    },
    "summary": {
      "type": "string"
    }
  }
}

Always specify a schema for data extraction operations. This significantly improves the predictability of the model response.


Typical ticket classification scenario

  1. A ticket is created.
  2. The ticket starts a BPMN process.
  3. The process calls the ai.extract Service Task.
  4. AI analyzes the ticket text and the available context.
  5. AI returns:
    • classification
    • summary
  6. BPMN uses classification for further routing through a Gateway.

Example:

ACCESS_RESTORE → access support group

PAYMENT_REQUEST → finance department

VACATION_REQUEST → HR

Full AI Extract example

Process variables

{
  "input": {
    "subject": "I cannot log in to the system",
    "body": "Login stopped working after I changed my password"
  },
  "schema": {
    "type": "object",
    "properties": {
      "classification": {
        "type": "string"
      },
      "summary": {
        "type": "string"
      }
    }
  }
}

Extension Properties

uni.connector=ai
uni.action=extract
uni.version=v1

ai.in.promptKey=aiExtract
ai.in.input=${input}
ai.in.schema=${schema}

ai.out.result=classificationResult

Result

After the Service Task completes, an AiExecutionResult object is stored in the classificationResult variable.


Full AI Generate example

Process variables

{
  "input": {
    "clientMessage": "Hello, I would like to learn more about Cabinee"
  }
}

Extension Properties

uni.connector=ai
uni.action=generate
uni.version=v1

ai.in.promptKey=replyToCustomer
ai.in.input=${input}

ai.out.result=generatedResult

Result

After the Service Task completes, an AiExecutionResult object is stored in the generatedResult variable.

Example:

{
  "success": true,
  "result": {
    "text": "Hello! Thank you for your interest in Cabinee..."
  },
  "model": "gpt-5.4-mini"
}

To get the generated text itself, the following is typically used:

${generatedResult.result.text}

Result

The operation result is stored in the process variable specified in ai.out.result.

Example response:

{
  "success": true,
  "result": {
    "classification": "PAYMENT_REQUEST",
    "summary": "License payment request"
  },
  "model": "gpt-5.4-mini",
  "usage": {
    "inputTokens": 123,
    "outputTokens": 25,
    "totalTokens": 148
  }
}

The result field contains the AI operation result.

For ai.extract:

  • it contains the data extracted according to the schema.

For ai.generate:

  • it contains the generated text;
  • the text is available in the result.text field.

Token usage statistics

The usage field contains token consumption information:

  • inputTokens — the number of tokens sent to the model in the input request (prompt, input, context, result schema).
  • outputTokens — the number of tokens generated by the model in the response.
  • totalTokens — the total number of tokens (inputTokens + outputTokens).

These metrics are useful for:

  • controlling LLM usage cost;
  • analyzing request performance;
  • finding prompts or contexts that are too large.

To get the extracted data itself, the following is typically used:

${classificationResult.result}

For example:

{
  "classification": "ACCESS_RESTORE",
  "summary": "Access restore request"
}

The following fields may also be returned:

  • success — whether the operation completed successfully
  • rawText — the original model response
  • model — the model that was used
  • promptKey — prompt identifier
  • promptVersion — prompt version
  • usage — token usage statistics
  • error — error information when the operation fails

Monitoring

Track:

  • errors
  • timeouts
  • response time

Typical errors

  • apiKey is not set
  • prompt is not found
  • timeout
  • invalid JSON

Recommendations

  • use promptKey
  • specify a schema
  • use a low temperature
  • do not store keys in code

Scaling

  • horizontally through the runtime
  • by increasing the number of workers

Cost

Depends on the number of requests and tokens


Roadmap

  • ai.decide
  • structured generation
  • retry
  • caching
  • audit