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
- BPMN calls a Service Task (
ai.extractorai.generate) - The External Task Worker receives the job
- The prompt is loaded (inline or by
promptKey) - A request to the LLM is built
- A response is received
- 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:
- Resolves
ticketIdfrom the External Task - Loads ticket data (Ticket)
- Loads ticket comments
- Loads attachments (metadata)
- 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
0means the corresponding data is not loaded into the context - a value of
N > 0means 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:
- relevant attachments are selected (for example, a PDF resume)
- the content is extracted
- it is converted to plain text
- 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:
openaiyandex
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.3range 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:
ai.in.inputuni.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.extractoperation.
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
- A ticket is created.
- The ticket starts a BPMN process.
- The process calls the
ai.extractService Task. - AI analyzes the ticket text and the available context.
- AI returns:
- classification
- summary
- 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.textfield.
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 successfullyrawText— the original model responsemodel— the model that was usedpromptKey— prompt identifierpromptVersion— prompt versionusage— token usage statisticserror— error information when the operation fails
Monitoring
Track:
- errors
- timeouts
- response time
Typical errors
apiKeyis 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