Skip to content

Реализация

Промпт для сборки для ИИ-агента: что именно реализовать в подсистеме Knowledge, в каком порядке и по каким контрактам. Передай блок ниже агенту; разделы после него — это референс, которому он должен следовать.

Эта страница — промпт для агента

У каждого раздела этих доков есть страница Реализация — точная, копируемая постановка задачи, которую исполняет агент. Сначала прочитай Обзор и LightRAG — они источник истины, на который ссылается этот промпт.

Промпт

text
РОЛЬ: Ты реализуешь подсистему Knowledge в Agentfy.ai 2.0 (NestJS + Prisma + CleanSlice).

ЦЕЛЬ: Дать каждому агенту собственную запрашиваемую базу знаний — каталог магазина, документы и
правила — на бэкенде LightRAG (graph-RAG), запущенном как ОТДЕЛЬНЫЙ Python-сервис. NestJS-слайс
`agent/knowledge` — ТОНКИЙ шлюз: CRUD баз знаний и документов (метаданные в Postgres), подача
документов и проксирование извлечения. Ingestion/graph/query сворачиваются ВНУТРИ LightRAG — это НЕ
наши под-слайсы. Агент достаёт извлечение ЧЕРЕЗ MCP (инструмент мозга), а не как часть мозга.

ПОСТАВКИ
1) Слайс `agent/knowledge` (api, L5) — структура CleanSlice:
   - domain/: IKnowledgeGateway (абстрактный — метаданные KB/Document, на Prisma),
     IRagGateway (абстрактный — контракт LightRAG: insert/query/dropWorkspace),
     knowledge.service.ts (оркестрирует оба), knowledge.types.ts (IKnowledgeBaseData,
     IDocumentData, RetrievalModeTypes = naive|local|global|hybrid, DocumentStatusTypes), errors/.
   - data/: knowledge.gateway.ts (Prisma-реализация IKnowledgeGateway),
     rag.gateway.ts (реализация IRagGateway → делегирует в LightRagRepository + RagMapper),
     lightRag.repository.ts (HTTP-клиент, оборачивающий API сервиса LightRAG — это РЕПОЗИТОРИЙ,
     а не Prisma-шлюз: он оборачивает внешний SDK/API), knowledge.mapper.ts.
   - knowledge.prisma (KnowledgeBase, KnowledgeDocument), knowledge.controller.ts
     (@Controller('knowledge-bases'); Swagger operationId на каждом роуте для генерации SDK), dtos/.
2) Выставление в MCP — извлечение как `@Tool` через `setup/mcp` (напр. knowledge_search). ВЕСЬ доступ
   к знаниям идёт по MCP; `agent/knowledge` — единственный, кто вызывает LightRAG напрямую. ДВА клиента
   запрашивают один эндпоинт: МОЗГ (orchestrator, в процессе, в ходе LLM-цикла) И WORKER (по ходу задачи,
   стучится в MCP-эндпоинт api со своим краткоживущим токеном сессии — без захода через мозг). Оба несут
   один и тот же выведенный на сервере workspace, поэтому изоляция держится для любого клиента.
3) Конвейер загрузки — подача документа ставит бюджетированную задачу `ingestion` в `runtime/task`
   (BullMQ); консьюмер вызывает insert в LightRAG и двигает KnowledgeDocument.status. НИКОГДА не
   индексировать inline на пути запроса. Инкрементально: переиндексировать только изменённые (дельты каталога).
4) Деплой сервиса LightRAG — Helm-values для образа HKUDS `lightrag` на Postgres
   (pgvector + Apache AGE), пул экземпляров по ключу workspace. Взять за основу чарт Ranch (см. референс).

КОНТРАКТЫ: реализуй ровно те строки, енумы, клиент-репозиторий и тип задачи, что в референсе ниже.
Следуй конвенциям CleanSlice (gateway vs repository, абстрактные DI-токены с префиксом `I`, единственные
имена папок слайсов, енумы с суффиксом `Types`, camelCase DTO-файлы, алиасы `#`, без `any` — `unknown` + guards).

БЕЗОПАСНОСТЬ (не обсуждается): workspace ВСЕГДА выводится из аутентифицированной команды/kb на стороне
api — НИКОГДА не принимай workspace от клиента (пустой/подменённый = утечка между тенантами). Workspace
должен быть непустым. `api` — ЕДИНСТВЕННЫЙ вызывающий внутренний сервис LightRAG (сетевая изоляция, без
публичного ingress). Удаление KB сносит его workspace (delete-by-doc + drop графа AGE).

ПРИЁМКА: см. чеклист внизу. Начинай с объёма v0.x MVP.

Референс — контракты для реализации

Строки базы знаний и документа (Prisma, только метаданные)

Сам корпус живёт в LightRAG; Postgres хранит только метаданные + статус:

prisma
model KnowledgeBase {
  id        String   @id            // = `workspace` в LightRAG
  teamId    String                  // тенант; workspace выводится из него + id
  agentId   String?                 // null = база, общая для команды
  name      String
  createdAt DateTime @default(now())
}

model KnowledgeDocument {
  id        String   @id
  baseId    String                  // → KnowledgeBase.id
  source    String                  // catalog | upload | url
  externalId String?                // напр. id товара OpenCart (для инкрементальной дельты)
  checksum  String?                 // пропустить переиндексацию, если не менялось
  status    String                  // pending | indexing | indexed | failed
  error     String?
  updatedAt DateTime @updatedAt
}

Режимы извлечения

RetrievalModeTypes = naive | local | global | hybrid. Вызывающий (агент) выбирает под вопрос; дефолт hybrid. Дешёвые вопросы идут naive (чистый вектор) — экономный путь из Обзора → масштабирование.

MCP-клиенты — мозг и worker

Извлечение доступно только по MCP (agent/knowledge выставляет @Tool через setup/mcp; api хостит эндпоинт). И мозг, и worker — клиенты:

КлиентАутентификацияПуть
Мозг (orchestrator)в процессевызывает MCP-инструмент напрямую в ходе LLM-цикла
Worker (руки)краткоживущий токен сессиистучится в MCP-эндпоинт api по ходу задачи; без захода через мозг

Токен worker'а ограничивает его его (agent, session), и api выводит workspace из него — worker сам его не передаёт. Поэтому worker, запрашивая знания, получает ту же изоляцию, что и мозг. (Это заменяет прежнюю заметку «извлечение только для мозга» из tool-split — извлечение по MCP открыто обоим; только для мозга остаётся материал секретов/KEK, который никогда не попадает в worker.)

Репозиторий LightRAG (клиент внешнего сервиса)

lightRag.repository.ts оборачивает HTTP API LightRAG — у него свои типы, он ничего не знает о домене и конвертируется в доменные типы через RagMapper:

ts
interface ILightRagRepository {
  insert(workspace: string, docs: RagDoc[]): Promise<void>;          // POST /insert
  query(workspace: string, q: string, mode: string): Promise<RagHit[]>; // POST /query
  dropWorkspace(workspace: string): Promise<void>;                   // снос KB
}

IRagGateway (domain) — абстрактный контракт; rag.gateway.ts (data) ловит ошибки репозитория/HTTP и конвертирует их в доменные ошибки. workspace передаёт сервис — выведенный из аутентифицированной KB, никогда от клиента.

Задача загрузки

ingestion (BullMQ, бюджетированная): { baseId, documentIds[] } → консьюмер грузит документы, вызывает rag.insert(workspace, ...), двигает KnowledgeDocument.status, соблюдает бюджет токенов на базу + лимит скорости. Живёт в runtime/task; та же подсистема очередей, что у Worker.

Сервис LightRAG (деплой)

HKUDS ghcr.io/hkuds/lightrag на Postgres pgvector + AGE, LIGHTRAG_{KV,VECTOR,GRAPH,DOC_STATUS}_STORAGE=PG*, зафиксированная версия, фиксированный EMBEDDING_DIM. Пул экземпляров по ключу workspace (ленивая инициализация + вытеснение по простою). Референс: cleanslice/ranch/k8s/platform/lightrag/* ~рабочий — адаптируй его Helm-чарт/values. См. LightRAG и GitOps.

Порядок задач

  1. v0.x MVP — слайс agent/knowledge (CRUD KB/Document на Prisma) · LightRagRepository + IRagGateway (insert + query, hybrid) · MCP-инструмент knowledge_search · один workspace на KB. Задеплой сервис LightRAG из чарта Ranch. Доказывает создать базу → подать документ → агент запрашивает через MCP → заземлённый ответ.
  2. + Асинхронная загрузка — перенести insert на задачу ingestion в BullMQ со статусами; никогда не inline.
  3. + Инкрементально и бюджет — пропуск по checksum/externalId; бюджет токенов на базу + лимит скорости.
  4. + Режимы и дешёвый путь — выставить naive|local|global|hybrid; по умолчанию дёшево, граф где окупается.
  5. + Жизненный цикл — удаление KB → dropWorkspace (delete-by-doc + drop графа AGE); прогрев/кэш при cold-start.

Критерии приёмки

  • [ ] Агент достаёт заземлённые факты из своей базы через MCP (knowledge_search), не выдумывая.
  • [ ] И мозг (в процессе), и запущенный worker (через токен сессии) могут запрашивать базу по MCP с одной и той же изоляцией workspace.
  • [ ] workspace выводится на сервере из аутентифицированной команды/kb; клиент не может его задать.
  • [ ] Один сервис LightRAG обслуживает много баз через экземпляры по workspace; без утечки между тенантами.
  • [ ] Подача документа ставит задачу загрузки; путь запроса не блокируется на индексации.
  • [ ] Неизменённые документы (совпал checksum) пропускаются; переиндексируются только дельты каталога.
  • [ ] LightRAG обёрнут как Репозиторий (внешний API); agent/knowledge остаётся тонким шлюзом.
  • [ ] Удаление KB сносит его workspace (drop графа AGE); без осиротевших векторов/графа.

Смотрите также