Ръководство и прозрение

Multi-Tenant RAG зад OpenAI-съвместим API Gateway

Практическа референтна архитектура за изграждане на разширено за извличане генериране зад многомоделен API шлюз: индекси с обхват на наемател, неутрални по отношение на доставчика адаптери за извличане, нормализирани цитати, контроли на жизнения цикъл и приписване на разходите.

Customer-facing AI assistants need retrieval-augmented generation, but RAG becomes harder when requests flow through an OpenAI-compatible API gateway instead of one model provider's native stack. The gateway must keep tenant data isolated, preserve citations across model providers, delete indexed content on schedule, and attribute embedding, retrieval, and generation costs to the right customer.

The practical answer is to treat retrieval as a first-class gateway subsystem. Не го крийте в интеграцията на един доставчик. Keep retrieval separate from generation, give every request a tenant-scoped retrieval context, normalize citations before returning them, and record each billable step in a ledger.

The Reader Problem

A team building an AI assistant for many customers usually starts with a simple flow: upload documents, embed chunks, retrieve the top matches, put those snippets into the prompt, and ask a модел за отговор. That works until the product needs multiple model providers, customer-level billing, offboarding, and auditability.

The risk is not only inaccurate answers. The larger operational risks are tenant namespace mistakes, unverifiable citations, stale indexes after document deletion, and margins that cannot be explained because retrieval costs disappear into generic infrastructure spend.

This article separates facts, recommendations, and predictions. Фактите са възможности за внедряване, документирани от текущия доставчик и API на векторни бази данни. Препоръките са избор на архитектура за шлюз продукт. The predictions are where this architecture is likely to need flexibility as provider retrieval features keep changing.

Reference Architecture

A gateway-level RAG design should have five components:

  • Tenant resolver: maps the incoming API key, workspace, customer account, or Partner API customer to a canonical tenant_id.
  • Retrieval profile: defines which corpus to search, which embedding model to use, result count, filters, reranking options, citation requirements, and fallback behavior.
  • Retrieval adapter layer: calls native provider retrieval, an external vector database, or a custom search service through one internal interface.
  • Prompt assembly and generation adapter: passes retrieved context to the chosen model provider without exposing vector backend details to callers.
  • Usage and audit ledger: records embedding, indexing, retrieval, prompt tokens, completion tokens, tenant, model, provider, and trace identifiers.

A minimal request contract can stay неутрално спрямо доставчика:

{
  "tenant_id": "tenant_123",
  "модел": "gpt-съвместим-или-claude-съвместим-модел",
  "retrieval_profile": "support_docs_v2",
  "citation_required": вярно,
  "съобщения": [
    {"role": "user", "content": "Каква е нашата политика за възстановяване на средства за годишни планове?"}
  ]
}

Отговорът също трябва да е неутрален по отношение на доставчика:

{
  "answer": "Годишните планове могат да бъдат възстановени в рамките на конфигурирания прозорец на правилата...",
  "цитати": [
    {
      "source_id": "doc_789",
      "title": "Правила за таксуване",
      "url_or_internal_ref": "kb://billing-policy",
      "chunk_id": "chunk_044",
      "отмествания": {"страница": 3},
      "резултат": 0,82,
      "retrieval_provider": "vector_db",
      "model_provider": "openai_compatible",
      "provider_payload": {}
    }
  ],
  "retrieval_trace_id": "rt_456",
  "billable_tenant": "наемател_123",
  "embedding_usage": нула,
  "retrieval_usage": {"заявки": 1, "резултати": 6},
  "model_usage": {"input_tokens": 1920, "output_tokens": 180}}

Факт: Функциите за извличане на доставчика не са идентични

API за векторни хранилища на OpenAI поддържа векторни хранилища, които могат да бъдат създавани, търсени, конфигурирани със стратегии за накъсване, свързвани с файлови метаданни и изтривани. Търсенето в векторни магазини поддържа заявки, филтри, максимален брой резултати, опции за класиране, прагове за резултат и контроли за пренаписване на заявки. Тези контроли дават на авторите на шлюза полезни копчета за забавяне, уместност и цена.

Контролите за данни на платформата OpenAI също правят дизайна на жизнения цикъл важен: клиентското съдържание във векторните магазини се запазва, докато не бъде изтрито. Ако наемател напусне борда или ако временен проект изтече, шлюзът не може да приеме, че доставчикът ще премахне индексираното съдържание автоматично в бизнес графика на продукта.

Anthropic излага различен модел за цитати. Приложенията могат да предоставят блокове със съдържание на резултати от търсене с метаданни за източник и заглавие, а когато цитатите са активирани, моделът може да прикачи препратки към цитати към генерирания текст. Има практически ограничения: настройките за цитиране на резултатите от търсенето са всичко или нищо в рамките на заявка, блоковете с резултати от търсене поддържат текстово съдържание и детайлността на цитирането зависи от това как съдържанието е разделено на блокове.

Изводът е директен: шлюзът не трябва да излага формата за извличане на един доставчик като свой обществен договор, освен ако не възнамерява да направи този доставчик постоянен орган за извличане.

Препоръка: Използвайте Адаптери за извличане, а не блокиране на извличане

Създайте вътрешен интерфейс на адаптер за извличане. Шлюзът може да поддържа няколко бекенда зад себе си:

  • Извличане на собствен доставчик:полезно, когато клиент иска най-бързия път до функцията за търсене на файлове или векторно хранилище на един доставчик.
  • Външна векторна база данни:полезно, когато продуктът трябва да поддържа много доставчици на модели с последователна изолация на наемател и контроли на жизнения цикъл.
  • Предварително извлечени блокове с резултати от търсене:полезно когато шлюзът сглобява извлечен текст и го предава на доставчик, който поддържа изричен контекст, съобразен с цитиране.

Адаптерът трябва да върне същата вътрешна структура, независимо от бекенда:

interface RetrievalResult {
  retrievalTraceId: string;
  tenantId: низ;
  corpusId: низ;
  парчета: масив<{
    sourceId: низ;
    заглавие: низ;
    текст: низ;
    urlOrInternalRef?: string;
    chunkId: низ;
    offsets?: { page?: number; byteStart?: число; byteEnd?: число; tokenStart?: номер; tokenEnd?: номер};
    резултат?: число;
    metadata: Record;
    providerPayload?: unknown;
  }>;
  retrievalUsage: {
    доставчик: низ;
    queryCount: число;
    resultCount: число;
    billableUnits?: брой;
  };}

Това позволява на слоя за генериране да получава контекст, без да знае дали е дошъл от векторни хранилища на OpenAI, Pinecone, Weaviate, индекс за търсене в пълен текст на база данни или вътрешен хибриден ретривър.

Изолирането на клиента започва преди векторната заявка

Изолирането на клиента не трябва да зависи от бързи инструкции. Той трябва да бъде приложен преди извличане, на границата на хранилището и границата на заявката.

За системи в стил Pinecone, документираният модел за мултинаемност е едно пространство от имена на клиент в индекси без сървър. Операциите с равнина на данни са насочени към пространство от имена, което опростява изолирането на наемателя и изключване, тъй като изтриването на пространството от имена премахва записите на този наемател. Pinecone също така документира компромисите между пространствата от имена и филтрирането на метаданни: филтрирането в голямо споделено пространство от имена може да сканира повече данни, да струва повече и да изпълнява по-бавно от заявки с обхват от пространство от имена.

За системи в стил Weaviate мултитенантът съхранява всеки клиент на отделен шард, така че данните на един клиент не са видими за друг клиент. Изтриването на клиент изтрива свързания шард. Weaviate също така поддържа състояния на наематели, като активни, неактивни и разтоварени, което създава опция за жизнен цикъл за рядко използвани наематели.

Контролен списък за внедряване

  • Разрешете tenant_id от удостоверената самоличност на шлюза, а не само от предоставено от потребителя поле за тяло.
  • Съпоставете tenant_id към векторно пространство от имена, шард или векторно хранилище на доставчик идентификатор чрез регистър от страна на сървъра.
  • Отхвърляне на заявки, когато клиентът на ключа на API и исканият клиент на корпуса не съвпадат.
  • Съхранявайте споделените публични корпуси отделно от частните корпуси на клиентите.
  • Използвайте филтриране на метаданни за тип документ, език, продуктова област или период от време, след като границата на клиента вече е избрана.
  • Пространство от имена на регистрационни файлове, shard, corpus_id, retrieval_profile и retrieval_trace_id за проверка.

Запазете търсене между клиенти за изрични административни работни потоци с отделно разрешение, отделни индекси или контролирани пътища за агрегиране. Не превръщайте търсенето между наематели в случаен страничен ефект от филтрите за метаданни.

Нормализиране на цитатите като шлюзови обекти

Цитатите са продуктов договор, а не просто украса. Асистент за поддръжка на клиенти, инструмент за изготвяне на правни документи или вътрешен асистент за знания трябва да покаже защо е създаден отговор и откъде идва подкрепящият текст.

Шлюзът трябва да нормализира данните за цитиране в своя собствена схема:

{
  "source_id": "doc_123",
  "title": "Условия за възстановяване",
  "url_or_internal_ref": "kb://условия за възстановяване",
  "chunk_id": "chunk_006",
  "offsets": {"page": 2, "byte_start": 4410, "byte_end": 5020},
  "резултат": 0,79,
  "retrieval_provider": "превъртане",
  "model_provider": "антропичен",
  "model_provider_citation_payload": {}
}

Поддържайте нормализираните полета стабилни и позволявайте специфични за доставчика разширения. Някои доставчици ще изложат по-богати подробности за цитиране от други. Някои ще цитират блокове с резултати от търсенето. Някои ще цитират качени файлове. Някои няма да предоставят точния формат на отместване, който вашето приложение иска. Шлюзът трябва да запази това, което съществува, без да се преструва, че всеки доставчик има идентична семантика на цитиране.

Режим на стриктно цитиране

Когато citation_required е true, дефинирайте поведението при отказ предварително. Строгият режим може да изисква всеки фактически абзац да включва поне един цитат или окончателният отговор да съдържа цитати от извлечени части над минималния праг на резултата. Ако избраният модел доставчик не може да удовлетвори договора за цитиране, шлюзът трябва да се повреди бързо, да използва съвместим доставчик или да върне структуриран отказ.

Това е препоръка, а не универсално правило. Режимът на строго цитиране подобрява доверието, но може да увеличи отказите, повторните опити и сложността на резервния вариант. За творчески работни процеси с нисък риск цитатите може да не са задължителни. За поддръжка, насочена към клиента, или регулирани вътрешни работни потоци, citation_required често трябва да бъде част от профила за извличане.

Жизненият цикъл на индекса е характеристика на продукта

RAG системите натрупват данни. Временните качвания стават постоянни случайно. Бивши клиенти оставят след себе си вграждания. Продуктовите екипи променят стратегиите за групиране и забравят да възстановят старите индекси.Шлюзът трябва да прави изрично контролите за жизнения цикъл.

Препоръчителните контроли за жизнения цикъл включват:

  • Временно изтичане на корпуса: документите, качени за краткотрайна сесия, трябва да имат клеймо за изтичане и задание за изтриване.
  • Изтегляне на наемател: изтриването на наемател трябва да постави в опашката изтриване на пространства от имена, сегменти, векторни хранилища на доставчика и свързани файлови обекти.
  • Обработка на студени наематели: където се поддържа, неактивните наематели могат да бъдат маркирани като неактивни или разтоварени, за да се намали използването на ресурсите.
  • Реиндексиране на контрола на версията: съхранявайте модел на вграждане, политика за разделяне, версия на анализатора и indexed_at за всяка част.
  • Състояние на изтриване излагане: Работните потоци на API на партньора трябва да показват дали изтриването на документ, изтриването на вектор и изтриването от страна на доставчика е завършено.

Важният факт е, че част от съдържанието на векторния магазин се запазва, докато не бъде изтрито. Архитектурната препоръка е изтриването да бъде видимо и да може да се тества, вместо да се заравя в асинхронно задание без клиентско състояние.

Проследяване на три счетоводни книги

Една книга с токени не е достатъчна за RAG. Шлюзът се нуждае от поне три регистрационни книги:

  • Разходи за вграждане и индексиране: парсиране на документи, групиране, вграждане на извиквания, съхранение на файлове, записи на индекси и преиндексиране.
  • Разходи за извличане: четения на векторна база данни, търсене в собствен векторен магазин, прекласиране, пренаписване на заявки и резултат разширяване.
  • Разходи за генериране: входни токени от потребителски съобщения и извлечен контекст, изходни токени, извиквания на инструменти, повторни опити и резервни варианти.

Това е особено важно за агенции, доставчици на SaaS и вътрешни екипи на платформи, които препродават или разпределят разходи за AI. Без отделни регистри маржовете на RAG стават трудни за обяснение. Клиент с малко потребление на поколение все още може да бъде скъп, ако постоянно качва документи, преиндексира големи корпуси или изпълнява широки заявки за извличане.

Всяко събитие в книгата трябва да включва tenant_id, customer_id, ако е различен, API ключ ID, retrieval_profile, corpus_id, модел, доставчик, trace_id и таксувани единици. Това позволява на анализите на използването да отговарят на практически въпроси: кои наематели имат скъпи профили за извличане, кои корпуси са остарели, кои модели произвеждат неуспешни цитати и кои клиенти генерират прекалено големи подкани, защото извличането връща твърде много контекст.

Режими на неизправност за тестване

Подсистемата RAG на шлюза трябва да има тестове за режимите на неуспех, които създават видимост за клиента щета:

  • Липсващи цитати: citation_required е вярно, но отговорът на доставчика не съдържа използваеми препратки към цитати.
  • Старели индекси: документ е актуализиран или изтрит, но стари части все още се показват в резултатите от извличане.
  • Несъответствие на наемател: заявката се разрешава на наемател A, докато корпусът или пространството от имена принадлежат към наемател Б.
  • Прекалено широко извличане: профилът връща твърде много части, увеличавайки цената и намалявайки качеството на отговора.
  • Несъответствие в размера на частта: частите са толкова големи, че цитатите са неточни, или толкова малки, че контекстът губи смисъл.
  • Несъответствие на характеристиките на доставчика: един модел може да излъчва цитати в необходимата форма, докато друг не може.
  • Грешка на жизнения цикъл: иска се изтриване, но хранилището от страна на доставчика остава активно или непроверено.

Тези тестове трябва да се изпълняват на ниво договор за шлюз, а не само в рамките на един адаптер на доставчик. Целта е да се докаже, че публичното поведение остава стабилно, когато се промени сървърът за извличане или доставчикът на генериране.

Компромиси

Извличането на родния доставчик може да намали кода на приложението и да ускори първата версия. Компромисът е, че жизненият цикъл на съхранението, форматът на цитиране, контролите на заявките и наличността на функциите могат да бъдат обвързани с един доставчик.

Външните векторни бази данни добавят работна площ. Предимството е по-силна преносимост между модели, съвместими с OpenAI, модели Anthropic и бъдещи доставчици. Те също така улесняват обмислянето на пространствата от имена или фрагментите с обхват на клиента относно това кога шлюзът е отговорен за таксуването и изтеглянето.

Фино зърнестите части подобряват прецизността на цитирането и възможността за проверка. Те също така увеличават размера на индекса, обема на извличане и сложността на бързото сглобяване. Грубите части са по-прости, но могат да създадат цитати, които сочат към широка страница или раздел, а не към точния подкрепящ пасаж.

Режимът за строго изискване на цитиране подобрява доверието на потребителите.Той също така принуждава шлюза да обработва модели, които не могат да произведат необходимия формат на цитиране, което може да означава отказ на заявката, промяна на моделите или връщане на отговор с по-ниско състояние на увереност.

Прогноза: Извличането ще стане по-естествено, но шлюзовете все още се нуждаят от собствен договор

Функциите за извличане на собствените доставчици вероятно ще станат по-способни. Повече модели ще приемат извлечен контекст със структурирани изходни метаданни. Още API ще разкрият контроли за класиране, пренаписване на заявки и настройки за цитиране. Това не премахва необходимостта от договор за шлюз.

Шлюзът все още притежава идентичност на наемател, управление на ключове, лимити на разходите, анализ на използването, работни потоци на API на партньора и обещания за изтриване, обърнати към клиента. Функциите на доставчика могат да се използват зад адаптерния слой, но продуктът не трябва да принуждава всеки наемател, модел и работен поток за таксуване в абстракцията за извличане на един доставчик.

Приложимо заключение

Изградете RAG с множество клиенти като подсистема на шлюз с изрични граници. Разрешете самоличността на наемателя преди извличане. Използвайте пространства от имена, фрагменти или векторни хранилища с обхват на клиента. Поддържайте извличането зад адаптери. Нормализирайте цитатите в схема, притежавана от портал. Добавете състояния на жизнения цикъл и проверка на изтриването. Проследявайте отделно разходите за вграждане, извличане и генериране.

Тази архитектура поддържа RAG заземен, без да заключва продукта към един доставчик на извличане. Освен това дава на екипите оперативните контроли, от които се нуждаят, когато AI асистент преминава от прототип към система, насочена към клиента: изолация, цитати, преносимост, управление на жизнения цикъл и приписване на разходите.

Свързано четене

FAQ

Често задавани въпроси

Трябва ли многомоделен шлюз да използва извличане на родния доставчик или външна векторна база данни?
Използвайте собствено извличане на доставчик, когато скоростта на внедряване има значение и жизненият цикъл на един доставчик и поведението на цитиране са приемливи. Използвайте външна векторна база данни, когато преносимостта, изолацията на наемателя, преместването на борда и последователното таксуване между доставчиците са по-важни.
Достатъчно ли е филтрирането на метаданни за изолиране на наемател в RAG?
Филтрирането на метаданни е полезно, след като вече е избрана граница на наемател, но не трябва да бъде основният изолиращ механизъм за частни данни на наемател. Предпочитайте по подразбиране векторни хранилища с пространство от имена на клиент, сегмент на клиент или векторни хранилища с обхват на клиент.
Какво трябва да включва нормализираният обект на цитиране?
Включете source_id, заглавие, URL или вътрешна препратка, chunk_id, налични отмествания, резултат за извличане, доставчик на извличане, доставчик на модел и поле за разширение за специфични за доставчика полезни данни за цитиране.
Защо отделни регистри за вграждане, извличане и генериране?
Цената на RAG не идва само от жетони за изход на модела. Качванията, вграждането, преиндексирането, векторното търсене, прекласирането и бързото разширяване могат да променят цената на клиента. Отделните счетоводни книги правят маржовете и фактурирането на клиентите обясними.