Обновил readme.md

This commit is contained in:
2026-02-28 09:37:33 +03:00
parent 9f1c67a751
commit 2728c07ba9
2 changed files with 138 additions and 275 deletions

258
README.md
View File

@@ -1,7 +1,109 @@
# Agent Backend MVP
# Агент для работы с проектной документацией
## Run (Local)
## 1. Общее описание
Приложение представляет собой backend агентного режима для работы с документацией и кодом проекта.
Система решает следующие задачи:
- индексирует локальную копию проекта в `rag_session` и использует ее как основной рабочий контекст пользователя;
- принимает webhook коммитов репозитория в `rag_repo` и фиксирует контекст изменений по `story_id`;
- ускоряет построение `rag_session` за счет переиспользования кэша чанков и эмбеддингов из `rag_repo`;
- обрабатывает пользовательские запросы через `chat`, `agent`, оркестратор и специализированные графы;
- сохраняет quality-метрики, Story-контекст и артефакты сессии в PostgreSQL.
Ключевая идея архитектуры:
- `rag_session` отвечает за пользовательскую рабочую сессию и всегда остается основным источником retrieval;
- `rag_repo` не участвует напрямую в пользовательском ответе, а служит фоновым источником кэша и контекста коммитов;
- `story_id` связывает изменения аналитика, документацию и последующую работу тестировщика.
## 2. Архитектура
```mermaid
flowchart LR
User["Пользователь"]
Git["Git репозиторий\n(Gitea / Bitbucket)"]
Chat["Модуль chat"]
Agent["Модуль agent"]
RagSession["Модуль rag_session"]
RagRepo["Модуль rag_repo"]
Shared["Модуль shared"]
DB["PostgreSQL + pgvector"]
Giga["GigaChat API"]
User --> Chat
Chat --> Agent
Agent --> RagSession
Agent --> Shared
RagSession --> Shared
RagRepo --> Shared
Chat --> DB
Agent --> DB
RagSession --> DB
RagRepo --> DB
RagSession --> Giga
Agent --> Giga
Git --> RagRepo
RagRepo -.кэш и контекст коммитов.-> RagSession
```
Кратко по ролям модулей:
- `chat` — внешний API чата, фоновые задачи, SSE события, диалоги.
- `agent` — роутер интентов, оркестратор, графы, tools, генерация ответа и changeset.
- `rag_session` — создание и сопровождение пользовательского RAG индекса по локальным файлам.
- `rag_repo` — прием webhook коммитов, определение `story_id`, фиксация контекста коммита и заполнение repo-cache.
- `shared` — инфраструктурный слой: БД, retry, event bus, GigaChat client, настройки.
## 3. Типичный флоу
```mermaid
sequenceDiagram
actor User as Пользователь
participant Git as Git репозиторий
participant RagRepo as Модуль rag_repo
participant DB as PostgreSQL
participant RagSession as Модуль rag_session
participant Chat as Модуль chat
participant Agent as Модуль agent
Note over User,RagSession: Первая рабочая сессия: кэша репозитория еще нет
User->>RagSession: Создание rag_session и загрузка файлов проекта
RagSession->>DB: Проверка cache hit/miss
DB-->>RagSession: Кэш пуст
RagSession->>RagSession: Чанкинг и расчет embeddings без repo-cache
RagSession->>DB: Сохранение rag_chunks и rag_index_jobs
User->>Chat: Отправка запроса в чат
Chat->>Agent: Передача задачи
Agent->>RagSession: Retrieval контекста
RagSession->>DB: Чтение rag_chunks
DB-->>RagSession: Релевантные чанки
RagSession-->>Agent: Контекст
Agent-->>Chat: Ответ / changeset
Note over User,Git: Пользователь вручную делает commit и push
Git->>RagRepo: Webhook push
RagRepo->>RagRepo: Определение provider, commit_sha, changed_files, story_id
RagRepo->>DB: Запись story_records/story_links/story_artifacts
RagRepo->>DB: Запись rag_blob_cache/rag_chunk_cache/rag_session_chunk_map
Note over User,RagSession: Вторая рабочая сессия: repo-cache уже существует
User->>RagSession: Создание новой rag_session и загрузка файлов проекта
RagSession->>DB: Проверка cache hit/miss
DB-->>RagSession: Найдены cache hit по части файлов
RagSession->>RagSession: Переиспользование чанков из rag_repo cache
RagSession->>RagSession: Пересчет embeddings только для cache miss файлов
RagSession->>DB: Сохранение rag_chunks, rag_session_chunk_map, rag_index_jobs
User->>Chat: Новый запрос
Chat->>Agent: Передача задачи
Agent->>RagSession: Retrieval по новой сессии
RagSession-->>Agent: Контекст из session-RAG
Agent-->>Chat: Ответ / changeset
```
Что важно в этом сценарии:
- первый запуск индексации может быть полностью без кэша;
- после коммита `rag_repo` фиксирует контекст изменений и наполняет cache-таблицы;
- во второй и последующих сессиях `rag_session` использует `cache_hit_files`, чтобы уменьшить объем новых embeddings.
## 4. Инструкции к запуску
### Локальный запуск
```bash
python3 -m venv .venv
source .venv/bin/activate
@@ -9,135 +111,51 @@ pip install -r requirements.txt
uvicorn app.main:app --reload --port 15000
```
## Run (Docker Compose)
1. Fill env values:
### Запуск через Docker Compose
1. Создать `.env` на основе примера:
```bash
cp .env.example .env
```
Set `GIGACHAT_TOKEN` in `.env`.
2. Start:
2. Заполнить как минимум `GIGACHAT_TOKEN`.
3. Запустить сервисы:
```bash
docker compose up --build
docker compose up -d --build
```
- Public API: `http://localhost:15000/api/*`
- PostgreSQL + pgvector runs in `db` service on `localhost:5432`
Stop:
4. Проверить доступность backend:
```bash
docker compose down
curl http://localhost:15000/health
```
## Public API
Ожидаемый ответ:
```json
{"status":"ok"}
```
- `POST /api/rag/sessions`
- `POST /api/rag/sessions/{rag_session_id}/changes`
- `GET /api/rag/sessions/{rag_session_id}/jobs/{index_job_id}`
- `GET /api/rag/sessions/{rag_session_id}/jobs/{index_job_id}/events` (SSE progress)
- `POST /api/chat/dialogs`
- `POST /api/chat/messages`
- `GET /api/tasks/{task_id}`
- `GET /api/events?task_id=...`
- `POST /api/index/snapshot`
- `POST /api/index/changes`
- `GET /api/index/jobs/{index_job_id}`
- `GET /api/index/jobs/{index_job_id}/events` (legacy SSE progress)
### Основные адреса
- Backend API: `http://localhost:15000`
- PostgreSQL + pgvector: `localhost:5432`
- Webhook репозитория: `POST /internal/rag-repo/webhook`
RAG indexing SSE events (`/api/rag/sessions/{rag_session_id}/jobs/{index_job_id}/events`):
- `index_status`: `{"index_job_id","status","total_files",...}`
- `index_progress`: `{"index_job_id","current_file_index","total_files","processed_files","current_file_path","current_file_name"}`
- `terminal`: `{"index_job_id","status":"done|error",...}` (final event; stream closes after this event)
### Базовый сценарий проверки
1. Создать `rag_session` через `POST /api/rag/sessions`.
2. Дождаться завершения index-job через `GET /api/rag/sessions/{rag_session_id}/jobs/{index_job_id}`.
3. Создать диалог через `POST /api/chat/dialogs`.
4. Отправить сообщение через `POST /api/chat/messages`.
5. Настроить webhook репозитория на `POST /internal/rag-repo/webhook`.
6. Сделать commit с `story_id` в сообщении, например `FEAT-1 ...`.
7. Проверить заполнение таблиц:
- `story_records`, `story_links`, `story_artifacts`
- `rag_blob_cache`, `rag_chunk_cache`, `rag_session_chunk_map`
8. Во второй сессии индексации проверить поля job-статуса:
- `indexed_files`
- `cache_hit_files`
- `cache_miss_files`
## Session Model
- `rag_session_id`: identifies indexed project chunks in RAG.
- `dialog_session_id`: identifies one independent dialog context within a `rag_session_id`.
- Multiple dialogs can share one `rag_session_id`.
Recommended flow:
1. call `POST /api/rag/sessions` after project selection;
2. wait for indexing job completion;
3. call `POST /api/chat/dialogs` with `rag_session_id`;
4. call `POST /api/chat/messages` with `dialog_session_id` + `rag_session_id`.
`/api/chat/messages` supports explicit routing hint:
- `mode: "auto" | "project_qa" | "project_edits" | "docs_generation" | "qa"`
- Legacy aliases are still accepted: `code_change`, `analytics_review`.
## Persistence
Persisted in PostgreSQL:
- `rag_sessions`, `rag_chunks`, `rag_index_jobs`
- `dialog_sessions`, `chat_messages`
- `router_context` (agent routing context per dialog session)
- LangGraph checkpoints via `PostgresSaver` (thread id = `dialog_session_id`)
Notes:
- RAG vectors are stored in `pgvector` column (`rag_chunks.embedding`).
- Agent context/history is restored after restart for same `dialog_session_id`.
## Agent Runtime
- Router + context store (`app/modules/agent/engine/router/*`)
- LangGraph flow execution (`app/modules/agent/engine/graphs/*`)
- Route selection:
- `default/general` -> answer flow
- `project/qa` -> answer flow
- `project/edits` -> conservative changeset flow for non-code file updates (hybrid output: `proposed_content` + `hunks`)
- `docs/generation` -> answer and/or changeset flow
- LLM provider: GigaChat (`chat/completions`)
- Prompts for graph LLM nodes: `app/modules/agent/prompts/*.txt`
- `general_answer.txt`
- `project_answer.txt`
- `project_edits_plan.txt`
- `project_edits_hunks.txt`
- `project_edits_self_check.txt`
- `docs_generation.txt`
- `docs_execution_summary.txt`
## Modules Structure
- `app/modules/chat/*`: chat API, tasks, session-scoped orchestration, event streaming.
- `app/modules/agent/*`: intent router, LangGraph flows, confluence integration, changeset validation.
- `app/modules/rag/*`: indexing API/jobs and retrieval service.
- `app/modules/shared/*`: cross-module primitives (event bus, retry, idempotency).
- `app/modules/contracts.py`: fixed inter-module contracts (`AgentRunner`, `RagRetriever`, `RagIndexer`).
## Module Boundaries
- `chat` depends on contract `AgentRunner`, but not on concrete `agent` internals.
- `agent` depends on contract `RagRetriever`, but not on `rag` indexing internals.
- `rag` exposes public/internal API and service implementation.
- wiring is centralized in `app/modules/application.py`.
## Internal API (for integration)
- `POST /internal/rag/index/snapshot`
- `POST /internal/rag/index/changes`
- `GET /internal/rag/index/jobs/{index_job_id}`
- `POST /internal/rag/retrieve`
- `POST /internal/tools/confluence/fetch`
## Environment
- `.env.example` contains full list of parameters.
- `.env` is used by Docker Compose for `db` and `backend`.
- `GIGACHAT_TOKEN`: Basic credentials for OAuth exchange (required for LLM/embeddings).
- `DATABASE_URL`: PostgreSQL DSN, default `postgresql+psycopg://agent:agent@db:5432/agent`.
- `GIGACHAT_AUTH_URL`: default `https://ngw.devices.sberbank.ru:9443/api/v2/oauth`.
- `GIGACHAT_API_URL`: default `https://gigachat.devices.sberbank.ru/api/v1`.
- `GIGACHAT_SCOPE`: default `GIGACHAT_API_PERS`.
- `GIGACHAT_SSL_VERIFY`: `true|false`, default `true`.
- `GIGACHAT_MODEL`: chat model name, default `GigaChat`.
- `GIGACHAT_EMBEDDING_MODEL`: embedding model name, default `Embeddings`.
- `AGENT_PROMPTS_DIR`: optional override path for prompt files.
Troubleshooting:
- If indexing shows `failed_files > 0` and `indexed_files = 0`, check backend logs for TLS/auth errors to GigaChat.
- In corporate environments with custom TLS chain, set `GIGACHAT_SSL_VERIFY=false` (or install proper CA certs in container).
### Полезные замечания
- Текущая chat-модель: `GigaChat`.
- Основной retrieval всегда идет из `rag_session`.
- `rag_repo` используется как фоновый источник кэша и контекста коммитов.
- Если в webhook не найден `story_id`, commit-контекст Story не будет привязан, но cache-таблицы все равно должны наполняться.