149 lines
9.7 KiB
Markdown
149 lines
9.7 KiB
Markdown
# 1C Agent (подпроект)
|
||
|
||
Этот подпроект — отдельный сервис-агент для 1С с:
|
||
|
||
- хранением состояния `project -> chat -> messages`;
|
||
- маршрутизацией модели через `registry/index.json` + `runtime_profiles`;
|
||
- вызовом LLM через настраиваемые провайдеры;
|
||
- встроенной RAG-подготовкой контекста по `plugins/1c/datasets/prepared/rag_index.json`;
|
||
- вызовами 1C-адаптера (`/onec-tool` / `adapter_calls`).
|
||
|
||
## API (коротко)
|
||
|
||
- `GET /v1/health` — здоровье сервиса.
|
||
- `GET /v1/projects` — список проектов.
|
||
- `POST /v1/projects` — создать проект.
|
||
- `GET /v1/projects/{project_id}` — получить проект.
|
||
- `GET /v1/projects/{project_id}/chats` — список чатов проекта.
|
||
- `POST /v1/projects/{project_id}/chats` — создать чат.
|
||
- `GET /v1/projects/{project_id}/chats/{chat_id}` — получить чат.
|
||
- `GET /v1/projects/{project_id}/chats/{chat_id}/messages` — история сообщений.
|
||
- `POST /v1/projects/{project_id}/chats/{chat_id}/messages` — добавить message (user/assistant/system/tool).
|
||
- `GET /v1/projects/{project_id}/chats/{chat_id}/runtime` — показать, как в этом чате разрешается запуск модели (provider/model/model_id/base_url/adapter и настройки).
|
||
- `POST /v1/projects/{project_id}/chats/{chat_id}/turn` — сделать turn LLM:
|
||
- принимает `message`
|
||
- может включать `adapter_calls` (список `{method, params}`)
|
||
- может включать `use_rag` и RAG-профиль.
|
||
- `POST /v1/projects/{project_id}/chats/{chat_id}/onec-tool` — прямой вызов адаптера.
|
||
- `PATCH /v1/projects/{project_id}` — обновить проект (название/описание/metadata).
|
||
- `PATCH /v1/projects/{project_id}/chats/{chat_id}` — обновить настройки чата.
|
||
- `DELETE /v1/projects/{project_id}` — удалить проект вместе со всеми чатами/сообщениями.
|
||
- `DELETE /v1/projects/{project_id}/chats/{chat_id}` — удалить чат и его сообщения.
|
||
- `GET /v1/state` — диагностика состояния сервиса (запущен, uptime, счётчики, провайдеры).
|
||
|
||
## Веб-интерфейс
|
||
|
||
- Открой `http://<host>:<port>/` (на тесте: `http://docker-test.cin.su:8090/`), чтобы войти в UI.
|
||
- UI не требует отдельной авторизации в самом сервисе; доступ регулируется только сетевыми правилами/портом.
|
||
- API по-прежнему доступен на `/v1/*` для интеграций и для работы без UI.
|
||
|
||
## Контракт
|
||
|
||
Нормализованный контракт API: [openapi.yaml](openapi.yaml).
|
||
|
||
## Разделение ответственностей
|
||
|
||
### Агент (этот сервис)
|
||
- Определяет сценарий: project/chat/role/memory/tool-call/guardrails.
|
||
- Собирает prompt:
|
||
1) системный prompt проекта/чата,
|
||
2) историю чата,
|
||
3) RAG-подготовленный контекст (если включён),
|
||
4) результаты инструментов.
|
||
- Вызывает LLM через выбранный провайдер.
|
||
- Сохраняет сообщение и служебные метаданные.
|
||
|
||
### Модель
|
||
- Принимает стандартный диалоговый список сообщений.
|
||
- Возвращает только сгенерированный текст.
|
||
- Никакой бизнес-логики 1С в сервисе модели — только reasoning по prompt.
|
||
|
||
### Логика работы с адаптером в prompt
|
||
|
||
Правила выбора маршрута поиска живут в `plugins/1c/prompts/system.md`, а не в REST/MCP-адаптере. Адаптер должен возвращать структурированные факты и статусы, а агент обязан правильно их интерпретировать.
|
||
|
||
Ключевые правила для агента:
|
||
- всегда явно передавать `base_id` для live-запросов;
|
||
- читать известный `module_ref`/read selector напрямую перед глобальным поиском;
|
||
- не считать `not_found` доказательством отсутствия кода в расширениях или `ConfigCAS`;
|
||
- считать `partial`, `truncated=true` и timeout неполным результатом;
|
||
- отделять доказанный факт от гипотезы и показывать конкретный участок кода, если пользователь просит "место".
|
||
|
||
### Адаптер (1С)
|
||
- Отвечает за живые данные 1С (`query`, `metadata`, `modules`, и т.д.).
|
||
- Возвращает строго структурированный JSON.
|
||
- Не должен быть «зашит» в модель: модель может запрашивать только через инструментовое API.
|
||
|
||
### RAG
|
||
- Не является моделью.
|
||
- Превращает вопрос в релевантный контекст + мета-информацию источников.
|
||
- Передаётся в модель как системное сообщение с уже собранным `rag_prompt`.
|
||
|
||
## Что проходит между слоями
|
||
|
||
- `agent -> model`:
|
||
`{"role":"system"/"user"/"assistant", "content": ...}` + опционально `provider/system` настройки.
|
||
- `agent -> adapter`:
|
||
`{"method": "...", "payload": {...}}`.
|
||
- `adapter -> agent`:
|
||
structured JSON-ответ (метаданные/результаты запроса/ошибки).
|
||
- `agent -> клиент`:
|
||
user message + assistant message + RAG-сводка + tool outputs + guardrail info.
|
||
|
||
## Быстрый smoke на развернутом сервисе
|
||
|
||
Для проверки продового/тестового инстанса:
|
||
|
||
- `python scripts/smoke_onec_agent_api.py --base-url http://docker-test.cin.su:8090`
|
||
- По умолчанию скрипт проверяет быстрые роуты (`/health`, `/state`, CRUD, `messages`).
|
||
- Для live-проверки `/turn` добавь `--with-turn-check` и учти, что первый запуск может идти дольше из‑за холодного инференса.
|
||
|
||
- Быстрый авто-проход "deploy + smoke":
|
||
- `powershell -File scripts/deploy_onec_agent_test.ps1 -NoBuild`
|
||
- `powershell -File scripts/deploy_onec_agent_test.ps1`
|
||
- `powershell -File scripts/deploy_onec_agent_test.ps1 -WithTurnCheck`
|
||
|
||
## Обновление на `docker-test` без влияния на остальные проекты
|
||
|
||
Деплой скрипт работает только с сервисом `onec-agent`, поэтому на `docker-test` не затрагиваются другие проекты.
|
||
|
||
- Быстрое обновление (с пересборкой):
|
||
`powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_onec_agent_test.ps1`
|
||
- Обновление только с перезапуском (без сборки):
|
||
`powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_onec_agent_test.ps1 -NoBuild`
|
||
- Если добавляешь скрипт в задачу по расписанию, используй именно этот файл — он делает деплой + health-check + smoke в одном проходе.
|
||
|
||
## Автообновление при изменении кода
|
||
|
||
Если хочешь, чтобы агент всегда был в актуальном состоянии после каждой правки его исходников, запусти:
|
||
|
||
- `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/watch_onec_agent_for_test.ps1`
|
||
|
||
Скрипт мониторит каталоги/файлы:
|
||
- `plugins/1c/agent`
|
||
- `core/deploy/docker/1c-agent/compose.yaml`
|
||
- `scripts/deploy_onec_agent_test.ps1`
|
||
- `scripts/smoke_onec_agent_api.py`
|
||
|
||
При любых изменениях автоматически перезапускает только сервис `onec-agent` на `docker-test`, затем делает health-check и smoke.
|
||
|
||
Для непрерывного режима в фоне:
|
||
|
||
- `Start-Process -FilePath powershell -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-File','scripts/watch_onec_agent_for_test.ps1' -WindowStyle Hidden`
|
||
|
||
## Что хранит агент (сущности)
|
||
|
||
- `Project`: `id`, `name`, `description`, `metadata`, `created_at`, `updated_at`.
|
||
- `Chat`: `id`, `project_id`, `title`, `provider_id`, `base_url`, `served_model_name`, `model_id`, `temperature`, `max_tokens`, `rag_profile`, `rag_limit`, `system_prompt`, `metadata`, `created_at`, `updated_at`.
|
||
- `Message`: `id`, `project_id`, `chat_id`, `role`, `content`, `payload` (операционные поля), `created_at`.
|
||
|
||
## Как подключать другого ИИ в будущем
|
||
|
||
Сервис уже рассчитан на расширение:
|
||
|
||
- в `ONEC_AGENT_PROVIDERS` задаются провайдеры;
|
||
- у каждого провайдера есть `type`.
|
||
- сейчас поддержан `openai-compatible`.
|
||
|
||
Когда нужна другая платформа, добавляется новый `type` в диспетчер провайдеров (и, при необходимости, нормализация ответа в единый формат `{"text": "...", "raw": {...}}`).
|