Глава 16

RAG возвращает доказательства, а не новый prompt

RAG в агенте - это не "подмешать документы в prompt", а tool, который возвращает доказательства с provenance. policy_search фильтрует документы по tenant, locale и сроку действия, каждый фрагмент получает стабильный source id, а текст документа считается недоверенными данными - даже если пришёл из вашей базы.

TypeScript
const policySearchInput = z.object({
  query: z.string().min(3).max(300),
  locale: z.enum(["ru", "en", "uz"])
}).strict();

async function policySearch(raw: unknown, context: TrustedToolContext) {
  const input = policySearchInput.parse(raw);
  const now = new Date();

  const hits = await retrieval.search({
    query: input.query,
    tenantId: context.tenantId,
    locale: input.locale,
    filter: {
      activeAt: now,
      status: "published"
    },
    limit: 5
  });

  return {
    passages: hits.map(function toPassage(hit) {
      return {
        source_id: hit.sourceId,
        title: hit.title,
        effective_at: hit.effectiveAt,
        excerpt: hit.excerpt
      };
    })
  };
}

Одного поиска мало: нужно ещё проверить, что модель сослалась только на реально найденное. Citations сверяются после ответа.

TypeScript
function verifyCitations(
  requested: string[],
  retrieved: Set<string>
) {
  const unknown = requested.filter(function isUnknown(id) {
    return !retrieved.has(id);
  });
  if (unknown.length > 0) throw new Error("unknown_citation");
}

Отсюда важное правило про то, что делать, когда доказательств нет.

Answerability gate. Если поиск не вернул достаточного активного источника, правильный исход - уточнение или handoff. Модель не дополняет политику общими знаниями: лучше честное "не нашёл", чем уверенная выдумка про правила магазина.

Сам retrieval можно построить по-разному, и выбор влияет на весь cross-provider дизайн.

Вариант retrieval · Плюс · Ограничение

  • Свой vector или hybrid search - Одинаковый корпус и eval для трех провайдеров; Вы отвечаете за ingestion, ranking и ACL
  • Provider file search - Меньше инфраструктуры; Разные индексы, фильтры, citations и lifecycle
  • Поиск как отдельный сервис - Четкая граница, кеш и независимое масштабирование; Дополнительная сеть и observability

Свой vector- или hybrid-поиск даёт одинаковый корпус и eval для трёх провайдеров ценой того, что ingestion, ranking и ACL на вас. Provider file search снимает инфраструктуру, но приносит разные индексы, фильтры и citations у каждого API. Поиск как отдельный сервис даёт чёткую границу ценой лишней сети. Для книги важна переносимость, поэтому корпус общий, а не провайдерский.

RAG отвечает за правила. Но агент читает и конкретный заказ - а это персональные данные, и начинается такое чтение с проверки владения.

Ссылки