Goals
A goal is a named group of ordered prompt references. When a request includes a content item with type: goal, the system resolves the named goal group, evaluates each entry's filter expression, and injects the matching prompts into the LLM call.
Why goals exist
Prompts cover individual message templates. Goals allow composing multiple prompts into named workflows with conditional logic. For example, a goal named document-analysis might inject a base system prompt plus a document-type-specific prompt based on the value of a documentType variable.
Goal structure
A goal group contains an ordered list of entries. Each entry has:
| Field | Description |
|---|---|
promptId | ID of the prompt to include |
index | Execution order (ascending). Lower index runs first. |
filter | Thymeleaf boolean expression. If the expression evaluates to true, the prompt is included. |
Example from goals.yml:
goals:
globals:
- id: document-analysis
goals:
- promptId: basePrompt
filter: "true"
index: 1
- promptId: arenderContext
filter: "true"
index: 10
- promptId: contractSummary
filter: "[[${documentType == 'contract'}]]"
index: 20
When a request includes { "type": "goal", "value": "document-analysis" }, the system evaluates each entry's filter with the request payload as context. Entries where the filter evaluates to true have their prompts rendered and injected.
Tenant overrides
Like prompts, goals support per-tenant overrides in goals.yml:
goals:
globals:
- id: analyse
goals:
- promptId: genericComparison
filter: "true"
index: 1000
tenants:
- tenantId: tenant-id-1
mergeStrategy: merge
goalGroups:
- id: compare
goals:
- promptId: detailedComparisonForTenant1
filter: "[[${documentType == 'contract'}]]"
index: 125
mergeStrategy: merge updates matching goal groups for the tenant. mergeStrategy: replace replaces the entire tenant goal configuration.
Runtime management
Goals can be created, updated, and deleted via the Admin API (/api/v1/admin/goals) without restarting the application. Changes are persisted in OpenSearch.
Backup
The backup path is configurable via goals.backup.path (or GOALS_BACKUP_PATH environment variable). Defaults to ./goals/.