Enterprise RAG на AWS: интеграция Confluence и SharePoint с чат-ботом | AiManual
AiManual Logo Ai / Manual.
01 Фев 2026 Гайд

Корпоративная RAG-система PDI на AWS: как объединить Confluence, SharePoint и чат-интерфейс

Пошаговое руководство по созданию корпоративной RAG-системы на AWS для объединения Confluence, SharePoint и чат-интерфейса. Архитектура, код, ошибки.

Почему ваша RAG-система в корпорации обречена на провал

Представьте: у вас есть Confluence с 5000 страниц техдокументации. SharePoint с договорами и отчетами. Slack-архивы, базы знаний в S3, PDF-ки на общих дисках. И все это нужно объединить в одну систему, где любой сотрудник задает вопрос на естественном языке и получает точный ответ с ссылкой на источник.

Звучит как мечта? Большинство команд начинают с выбора модели или векторной базы. И это первая ошибка, которая гарантирует провал через 3 месяца.

В корпоративной среде архитектура определяется не технологиями, а политиками доступа. Кто может видеть финансовые отчеты? Кто — техдокументацию? Если вы сначала выбрали Pinecone, а потом узнали, что данные должны быть в регионе ЕС — готовьтесь переписывать половину системы.

Мы строили PDIQ — внутреннего ассистента для PDI Technologies. Компания работает с топливным и коммерческим транспортом, где ошибка в документации стоит реальных денег. Вот что мы поняли за год разработки.

Архитектура, которая не сломается при первом же аудите

Современная RAG-система в 2026 году — это не просто векторный поиск + LLM. Это многоуровневая система с контролем доступа, аудитом и обновлением данных в реальном времени.

Слой Технология Зачем нужен
Ingestion Pipeline AWS Step Functions + Lambda Забирает данные из Confluence API, SharePoint, S3
Processing Layer Python + Unstructured.io Чистит HTML, разбивает PDF на чанки
Vector Store Amazon OpenSearch Хранит векторы + метаданные (источник, права)
Query Engine AWS Lambda + Bedrock Ищет чанки, генерирует ответы
Access Control Cognito + Custom Lambda Проверяет права на каждый чанк

Почему именно такая структура? Потому что каждый слой можно масштабировать независимо. Когда Confluence API ложится (а он ложится регулярно), ingestion pipeline просто ретраит запросы. Когда нужно добавить новый источник данных — не переписываешь всю систему.

1 Начинаем с инвентаризации, а не с кода

Прежде чем писать первую строчку кода, ответьте на вопросы:

  • Какие источники данных критичны? Confluence, SharePoint, что-то еще?
  • Кто имеет доступ к каждому источнику? Нужна ли разная видимость для отделов?
  • Как часто обновляются данные? Реальное время или раз в сутки достаточно?
  • Где должны храниться данные по compliance? AWS регион имеет значение.

Мы использовали Confluence2md для быстрого прототипирования. Но в production перешли на полноценный пайплайн.

2 Ingestion Pipeline: как не сломать Confluence API

Самая частая ошибка — написать скрипт, который одним запросом пытается выкачать все страницы Confluence. Через 10 минут вас забанят, а админы Confluence будут вас ненавидеть.

Вот как делать правильно:

import boto3
from atlassian import Confluence
import json

# Не храните credentials в коде!
# Используйте Secrets Manager
secrets_client = boto3.client('secretsmanager')
secret = secrets_client.get_secret_value(SecretId='confluence-creds')
creds = json.loads(secret['SecretString'])

confluence = Confluence(
    url=creds['url'],
    username=creds['username'],
    password=creds['password'],
    cloud=True
)

def get_spaces_with_backoff():
    """Получаем пространства с экспоненциальной backoff задержкой"""
    spaces = []
    start = 0
    limit = 50
    
    while True:
        try:
            batch = confluence.get_all_spaces(
                start=start,
                limit=limit,
                type='global'
            )['results']
            
            if not batch:
                break
                
            spaces.extend(batch)
            start += limit
            
            # Уважаем rate limits
            time.sleep(0.5)
            
        except Exception as e:
            if 'rate limit' in str(e).lower():
                time.sleep(60)  # Ждем минуту при rate limit
                continue
            raise
    
    return spaces
💡
Используйте AWS Step Functions для orchestration пайплайна. Когда Confluence API возвращает 429 (Too Many Requests), Step Functions автоматически ретраит с экспоненциальной backoff задержкой. Не изобретайте велосипед.

3 SharePoint интеграция: боль, которую можно пережить

SharePoint — это особый вид ада. API меняется, аутентификация через Azure AD, структура сайтов непредсказуема.

Мы использовали Microsoft Graph API с managed identity в AWS. Ключевой момент — кэширование токенов:

import msal
import boto3
from botocore.exceptions import ClientError

class SharePointClient:
    def __init__(self):
        self.ssm = boto3.client('ssm')
        self.token_cache = {}
    
    def get_access_token(self, tenant_id, client_id, client_secret):
        """Получаем токен с кэшированием"""
        cache_key = f"{tenant_id}_{client_id}"
        
        if cache_key in self.token_cache:
            token_info = self.token_cache[cache_key]
            # Проверяем, не истек ли токен
            if time.time() < token_info['expires_at'] - 300:  # 5 минут запаса
                return token_info['access_token']
        
        # Получаем новый токен
        app = msal.ConfidentialClientApplication(
            client_id=client_id,
            client_credential=client_secret,
            authority=f"https://login.microsoftonline.com/{tenant_id}"
        )
        
        result = app.acquire_token_for_client(
            scopes=["https://graph.microsoft.com/.default"]
        )
        
        if "access_token" in result:
            self.token_cache[cache_key] = {
                'access_token': result['access_token'],
                'expires_at': time.time() + result['expires_in']
            }
            return result['access_token']
        
        raise Exception(f"Failed to get token: {result.get('error_description')}")

Для извлечения данных из SharePoint используйте подход «сайт → список → элемент». Не пытайтесь скачать все сразу.

Векторный поиск с правами доступа: то, о чем молчат туториалы

Типичный туториал по RAG показывает, как закинуть текст в векторную базу и искать по косинусной близости. В корпорации это не работает.

Почему? Потому что сотрудник из отдела продаж не должен видеть техдокументацию для инженеров. А инженер поддержки не должен видеть финансовые отчеты.

Решаем через фильтрацию на уровне векторного поиска:

# Метаданные для каждого чанка
chunk_metadata = {
    "id": "chunk_123",
    "text": "...текст чанка...",
    "source": "confluence:SPACE-123",
    "source_type": "confluence",
    "permissions": {
        "departments": ["engineering", "support"],
        "roles": ["backend", "devops"],
        "projects": ["project-alpha"]
    },
    "last_updated": "2026-02-01T10:30:00Z"
}

# Поиск с фильтрацией по правам
def search_with_permissions(query, user_context, k=5):
    """Ищем чанки, доступные пользователю"""
    
    # Генерируем эмбеддинг запроса
    query_embedding = generate_embedding(query)
    
    # Строим фильтр на основе контекста пользователя
    permission_filter = {
        "bool": {
            "should": [
                {"terms": {"permissions.departments": user_context.departments}},
                {"terms": {"permissions.roles": user_context.roles}},
                {"terms": {"permissions.projects": user_context.projects}}
            ]
        }
    }
    
    # Ищем в OpenSearch с фильтром
    search_body = {
        "query": {
            "script_score": {
                "query": {
                    "bool": {
                        "must": permission_filter,
                        "filter": {
                            "knn": {
                                "embedding": {
                                    "vector": query_embedding,
                                    "k": k * 3  # Ищем больше, потом фильтруем
                                }
                            }
                        }
                    }
                },
                "script": {
                    "source": "_score * doc['relevance_boost'].value"
                }
            }
        }
    }
    
    # Выполняем поиск
    response = opensearch_client.search(
        index="rag-index",
        body=search_body
    )
    
    return response['hits']['hits'][:k]

Не храните права доступа в отдельной базе! При каждом поиске придется делать join, что убивает производительность. Храните permissions как часть метаданных вектора — фильтрация будет в 100 раз быстрее.

LLM в 2026: Claude 3.7 Sonnet или GPT-4.5 Turbo?

На момент написания (февраль 2026) у нас есть выбор. Мы тестировали:

  • Anthropic Claude 3.7 Sonnet — отличное качество ответов, хороший контекст (200K токенов), но дороже
  • OpenAI GPT-4.5 Turbo — быстрее, дешевле, но иногда «галлюцинирует» больше
  • Amazon Bedrock с Mistral Large 2 — хороший баланс цены и качества, особенно если вся инфраструктура на AWS

Мы выбрали Bedrock по трем причинам:

  1. Данные не уходят за пределы AWS (compliance!)
  2. Интеграция с IAM для контроля доступа
  3. Predictable pricing без сюрпризов

Промпт-инжиниринг в корпоративной RAG — это отдельная наука. Базовый промпт:

RAG_PROMPT_TEMPLATE = """Ты — ассистент компании {company_name}. 
Отвечай ТОЛЬКО на основе предоставленного контекста. 
Если в контексте нет информации — скажи "Не могу найти информацию в базе знаний".

Контекст:
{context}

Вопрос: {question}

Ответ должен быть:
1. Кратким и по делу
2. С цитатами из контекста [1], [2]
3. Ссылками на исходные документы

Ответ:"""

Но это только начало. Добавьте:

  • Инструкции по формату (маркдаун, списки)
  • Запрет на выдумывание фактов
  • Указание роли (техподдержка, продажи, разработка)

Чат-интерфейс, который не раздражает

Frontend — это не просто текстовое поле. Пользователи хотят:

  • Видеть источники ответа (ссылки на Confluence/SharePoint)
  • Возможность оценить ответ (thumb up/down)
  • Историю диалогов
  • Поиск по предыдущим ответам

Мы использовали React + AWS Amplify. Ключевой компонент — отображение источников:

function SourceBadge({ source, onClick }) {
  const getSourceIcon = (type) => {
    switch(type) {
      case 'confluence': return '📘';
      case 'sharepoint': return '📎';
      case 'pdf': return '📄';
      default: return '🔗';
    }
  };
  
  const formatDate = (dateStr) => {
    const date = new Date(dateStr);
    const now = new Date();
    const diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));
    
    if (diffDays === 0) return 'сегодня';
    if (diffDays === 1) return 'вчера';
    if (diffDays < 7) return `${diffDays} дня назад`;
    if (diffDays < 30) return `${Math.floor(diffDays / 7)} нед. назад`;
    return date.toLocaleDateString('ru-RU');
  };
  
  return (
    
{getSourceIcon(source.type)} {source.title} {formatDate(source.updated)}
); }

Ошибки, которые мы совершили (чтобы вы их не повторили)

  1. Слишком мелкие чанки. Разбили все на куски по 256 токенов. Результат — контекст терялся. Оптимально — 512-1024 токена с перекрытием.
  2. Игнорировали таблицы и изображения. В Confluence полно таблиц с данными. Нужно было извлекать их структурированно, а не как plain text.
  3. Забыли про инкрементальное обновление. Первая версия переиндексировала все каждый день. Исправили на отслеживание изменений через webhooks.
  4. Не добавили feedback loop. Пользователи не могли сказать «этот ответ неправильный». Добавили через 3 месяца — качество сразу выросло на 40%.

Стоимость: сколько это стоит в реальности

Не верьте статьям «RAG за $10 в месяц». В корпорации:

  • AWS OpenSearch (3 ноды t3.medium): $250/месяц
  • AWS Lambda (10M вызовов): $200/месяц
  • Amazon Bedrock (Claude 3.7 Sonnet, 100K запросов): $500-1000/месяц
  • S3 для хранения исходников: $50/месяц

Итого: $1000-1500/месяц. Но один сэкономленный час инженера стоит $100. Если система экономит 20 часов в месяц — она окупается.

💡
Начните с пилота в одном отделе. Возьмите 50 самых важных документов и сделайте RAG только для них. Измерьте метрики: время поиска информации, удовлетворенность пользователей. Потом масштабируйте.

Что дальше? RAG в 2027

Система работает. Но технологии не стоят на месте. Смотрим на:

  • Мультимодальность. Добавить поиск по скриншотам в документации, схемам, диаграммам.
  • Agents. Не просто отвечать на вопросы, а выполнять действия: «Найди договор с X и вышли мне основные пункты».
  • Real-time RAG. Интеграция с Slack/Microsoft Teams, где бот отвечает в реальном времени на вопросы в чатах.

Самое главное — система должна расти вместе с компанией. Сегодня это Confluence и SharePoint. Завтра — Jira, Salesforce, внутренние базы данных.

Архитектура, которую мы построили, позволяет добавлять новые источники за дни, а не за месяцы. И это ее главное преимущество.

Если хотите глубже погрузиться в тему, посмотрите нашу дорожную карту RAG 2026 — там все этапы от прототипа до production.