Process Contract
Контракт процесса — это формальное описание того, что процесс делает, какие входы принимает, какие выходы производит, и какие гарантии даёт.
Концепция
Каждый процесс в clowbot — это не просто функция, а контракт. Контракт хранится в БД и определяет:
- Что процесс делает (jtbd)
- Какие входы принимает (input_schema)
- Какие выходы даёт (output_schema)
- Какие шаги проходит (steps_expected)
- Какие SLA гарантирует (sla)
- Что делать при ошибках (fallback_policy)
- Как измерять качество (kpi)
- Кто что видит (visibility)
- Какие ограничения безопасности (safety_policy)
Rule: если нет контракта — это не process template.
Таблица process_templates
Контракты хранятся в таблице clowbot.process_templates. Она связана с таблицей processes через process_id.
-- Из db/init/210_process_rules_v1.sql
CREATE TABLE clowbot.process_templates (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
process_key text NOT NULL, -- Уникальный ключ процесса
version text NOT NULL, -- Версия контракта (semver)
process_id uuid REFERENCES processes(id),
name text NOT NULL, -- Человекочитаемое название
jtbd text NOT NULL, -- Job To Be Done описание
-- Схемы данных
input_schema jsonb NOT NULL DEFAULT '{}',
output_schema jsonb NOT NULL DEFAULT '{}',
-- Ожидаемые шаги
steps_expected jsonb NOT NULL DEFAULT '[]',
-- SLA и политики
sla jsonb NOT NULL DEFAULT '{}',
fallback_policy jsonb NOT NULL DEFAULT '{}',
kpi jsonb NOT NULL DEFAULT '{}',
visibility jsonb NOT NULL DEFAULT '{}',
safety_policy jsonb NOT NULL DEFAULT '{}',
metadata jsonb NOT NULL DEFAULT '{}',
status process_status NOT NULL DEFAULT 'active',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (process_key, version)
);Поля контракта
process_key
Уникальный идентификатор процесса. Обычно совпадает с code из таблицы processes.
-- Примеры process_key из БД
'copilot_chat' -- Основной чат с AI
'web_search' -- Веб-поиск
'daily_checkin' -- Ежедневный чекин
'swarm_test' -- Swarm-тестирование
'agent_orchestrator' -- Оркестрация агентовversion
Версия контракта в формате SemVer. Позволяет иметь несколько версий одного процесса.
-- При seed создаётся версия 1.0.0
INSERT INTO process_templates (..., version, ...)
VALUES (..., '1.0.0', ...);
-- Уникальность по паре (process_key, version)
UNIQUE (process_key, version)jtbd (Job To Be Done)
Человекочитаемое описание того, какую задачу решает процесс. Используется для документации и выбора процесса.
-- При seed jtbd берётся из description процесса
COALESCE(NULLIF(btrim(p.description), ''),
'Process contract seeded from active process registry')input_schema
JSON Schema входных данных процесса. Определяет структуру того, что процесс принимает на вход.
-- Из db/init/211_process_template_seed.sql
jsonb_build_object(
'type', 'object',
'properties', jsonb_build_object(
'task', jsonb_build_object('type', 'string'),
'run_id', jsonb_build_object('type', 'string', 'format', 'uuid'),
'chat_id', jsonb_build_object('type', 'integer'),
'user_id', jsonb_build_object('type', 'integer')
),
'required', jsonb_build_array('task', 'run_id'),
'additionalProperties', true
)Обязательные поля: task, run_id
Опциональные: chat_id, user_id
output_schema
JSON Schema выходных данных. Определяет структуру результата выполнения процесса.
-- Берётся из output_schema процесса
COALESCE(p.output_schema, '{}'::jsonb)steps_expected
Массив ожидаемых шагов процесса. Каждый шаг имеет ключ, описание и лимит retries.
-- Стандартные 3 шага для всех процессов
jsonb_build_array(
jsonb_build_object(
'step_key', 'prepare',
'description', 'Normalize input and enforce policies',
'max_retries', 1
),
jsonb_build_object(
'step_key', 'orchestrate',
'description', 'Run n8n or local fallback logic',
'max_retries', 2
),
jsonb_build_object(
'step_key', 'finalize',
'description', 'Render answer and write audit records',
'max_retries', 1
)
)prepare
Нормализация входа, проверка политик
orchestrate
Выполнение через n8n или локально
finalize
Рендер ответа, запись в audit
sla (Service Level Agreement)
Гарантии производительности и лимиты выполнения.
jsonb_build_object(
'latency_ms', jsonb_build_object(
'p50', 4000, -- Медиана: 4 секунды
'p95', 15000 -- 95% за 15 секунд
),
'max_steps', 8, -- Максимум шагов
'max_retries_total', 5 -- Всего retries на run
)fallback_policy
Что делать при недоступности компонентов. Fallback — это first-class behavior.
jsonb_build_object(
'n8n_unavailable', 'local_fallback_or_degraded',
'ollama_unavailable', 'degraded',
'web_timeout', 'partial_results'
)| Ситуация | Действие |
|---|---|
| n8n_unavailable | local_fallback_or_degraded |
| ollama_unavailable | degraded |
| web_timeout | partial_results |
kpi (Key Performance Indicators)
Целевые показатели качества процесса.
jsonb_build_object(
'success_rate_target', 0.95, -- 95% успешных runs
'fallback_rate_target', 0.20, -- До 20% через fallback
'redo_rate_target', 0.15, -- До 15% redo от юзера
'user_score_target', 4.00, -- Средний балл >= 4
'latency_p95_ms_target', 15000 -- p95 latency
)visibility
Кто какие поля видит. Разделение между user-facing и owner-only данными.
jsonb_build_object(
'user_fields', ['status', 'message', 'sources'],
'owner_fields', ['error_text', 'raw_payload', 'events']
)user_fields
- status — статус выполнения
- message — текст ответа
- sources — источники (RAG)
owner_fields
- error_text — детали ошибок
- raw_payload — полный payload
- events — все события
safety_policy
Ограничения безопасности для процесса.
jsonb_build_object(
'ssrf_guard_enabled', true, -- Защита от SSRF
'pii_masking', true, -- Маскирование PII
'financial_actions_require_owner', true -- Финансы требуют owner
)Важно: financial_actions_require_owner = true означает, что LLM не может напрямую выполнять финансовые операции — требуется подтверждение owner.
Связь с таблицей processes
Таблица process_templates связана с processes через внешний ключ.
-- Таблица processes (базовая)
CREATE TABLE clowbot.processes (
id uuid PRIMARY KEY,
code text NOT NULL UNIQUE,
name text NOT NULL,
description text,
prompt_template text NOT NULL,
default_model text NOT NULL DEFAULT 'qwen3:8b',
n8n_workflow_id text,
n8n_webhook_path text,
output_schema jsonb NOT NULL DEFAULT '{}',
auto_run boolean NOT NULL DEFAULT false,
status process_status NOT NULL DEFAULT 'draft',
created_by bigint REFERENCES users(id),
metadata jsonb NOT NULL DEFAULT '{}',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
-- Таблица process_templates (контракт)
CREATE TABLE clowbot.process_templates (
...
process_id uuid REFERENCES processes(id) ON DELETE SET NULL,
...
);Views для работы с контрактами
-- mart.vw_process_templates — удобный view
CREATE OR REPLACE VIEW mart.vw_process_templates AS
SELECT
pt.id,
pt.process_key,
pt.version,
pt.process_id,
p.code AS process_code,
pt.name,
pt.jtbd,
pt.input_schema,
pt.output_schema,
pt.steps_expected,
pt.sla,
pt.fallback_policy,
pt.kpi,
pt.visibility,
pt.safety_policy,
pt.metadata,
pt.status,
pt.created_at,
pt.updated_at
FROM clowbot.process_templates pt
LEFT JOIN clowbot.processes p ON p.id = pt.process_id;Практические запросы
Получить контракт процесса
SELECT *
FROM mart.vw_process_templates
WHERE process_key = 'copilot_chat'
AND status = 'active'
ORDER BY version DESC
LIMIT 1;Все активные контракты с их KPI
SELECT
process_key,
version,
name,
kpi->>'success_rate_target' AS success_target,
kpi->>'latency_p95_ms_target' AS latency_target
FROM clowbot.process_templates
WHERE status = 'active'
ORDER BY process_key;SLA по всем процессам
SELECT
process_key,
sla->'latency_ms'->>'p50' AS p50_ms,
sla->'latency_ms'->>'p95' AS p95_ms,
sla->>'max_steps' AS max_steps,
sla->>'max_retries_total' AS max_retries
FROM clowbot.process_templates
WHERE status = 'active';