Publicação Técnica
RAG na prática: implementando Amazon Bedrock Knowledge Bases com OpenSearch Serverless e Terraform
Large Language Models mudaram radicalmente a forma como empresas enxergam busca, automação e interação com conhecimento corporativo. O…
Large Language Models mudaram radicalmente a forma como empresas enxergam busca, automação e interação com conhecimento corporativo. O problema começa quando essas aplicações saem do ambiente de demonstração e entram em produção. Nesse momento, rapidamente fica evidente que o modelo não conhece a empresa.

O modelo não conhece contratos internos, runbooks operacionais, políticas organizacionais, catálogos privados, procedimentos específicos ou a documentação mais recente do ambiente. Sem acesso a esse contexto, aplicações corporativas passam a produzir respostas genéricas, inconsistentes ou simplesmente incorretas. Em muitos casos, o problema não é apenas qualidade da resposta, mas risco operacional.
É exatamente nesse cenário que Retrieval-Augmented Generation (RAG) se tornou uma das arquiteturas mais relevantes da atual geração de aplicações corporativas de IA.
A ideia é relativamente simples: antes de gerar uma resposta, o sistema recupera informações relevantes de uma base privada de conhecimento e utiliza esse contexto como grounding para o modelo. Na prática, isso transforma o LLM de um sistema puramente estatístico em uma interface contextualizada sobre o conhecimento da organização.
Neste artigo, construiremos uma arquitetura RAG utilizando:
- Amazon Bedrock
- Amazon Bedrock Knowledge Bases
- Amazon OpenSearch Serverless
- Amazon S3
- Terraform
O objetivo não é apenas provisionar recursos, mas discutir os aspectos arquiteturais que normalmente aparecem quando aplicações RAG começam a operar em ambientes reais.
A arquitetura
A arquitetura proposta possui quatro componentes centrais.
Os documentos corporativos são armazenados no S3. O Bedrock Knowledge Bases é responsável pelo processamento documental, chunking, geração de embeddings e orquestração do retrieval. O OpenSearch Serverless atua como vector store. O Terraform provisiona toda a infraestrutura.
O fluxo operacional fica relativamente direto:
Usuário
|
Aplicação / API
|
Bedrock Knowledge Base
|
OpenSearch Serverless
|
Foundation Model
|
Resposta contextualizada
Embora pareça simples conceitualmente, a maior parte da complexidade operacional aparece nos detalhes: chunking, sincronização, IAM, controle de acesso, governança documental e observabilidade.
Estrutura do projeto
A estrutura Terraform utilizada neste artigo é propositalmente simples.
rag-bedrock-terraform/
├── providers.tf
├── variables.tf
├── s3.tf
├── iam.tf
├── opensearch.tf
├── bedrock.tf
└── outputs.tf
O objetivo aqui não é criar um módulo enterprise-ready completo, mas mostrar claramente os componentes envolvidos na construção do pipeline RAG.
Configurando o provider
O provider AWS utilizado precisa suportar os recursos de Bedrock Knowledge Bases.
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.49.0"
}
}
}
provider "aws" {
region = var.aws_region
}
As variáveis do projeto permanecem mínimas:
variable "aws_region" {
default = "us-east-1"
}
variable "project_name" {
default = "rag-demo"
}
Provisionando o bucket documental
O bucket S3 será utilizado como origem documental da Knowledge Base.
data "aws_caller_identity" "current" {}
resource "aws_s3_bucket" "documents" {
bucket = "${var.project_name}-documents-${data.aws_caller_identity.current.account_id}"
}
resource "aws_s3_bucket_versioning" "documents" {
bucket = aws_s3_bucket.documents.id
versioning_configuration {
status = "Enabled"
}
}
O versionamento é importante porque aplicações RAG inevitavelmente enfrentam problemas relacionados a atualização documental, rollback e inconsistência de sincronização. Em ambientes corporativos, o problema raramente é apenas armazenar documentos; normalmente é manter consistência entre múltiplas versões do conhecimento organizacional.
Criando o vector store
O OpenSearch Serverless será utilizado como vector database da aplicação.
Antes da collection, precisamos definir a encryption policy.
resource "aws_opensearchserverless_security_policy" "encryption" {
name = "${var.project_name}-encryption"
type = "encryption"
policy = jsonencode({
Rules = [
{
Resource = [
"collection/${var.project_name}-vectors"
],
ResourceType = "collection"
}
],
AWSOwnedKey = true
})
}
Em seguida, provisionamos a collection vetorial.
resource "aws_opensearchserverless_collection" "vectors" {
name = "${var.project_name}-vectors"
type = "VECTORSEARCH"
depends_on = [
aws_opensearchserverless_security_policy.encryption
]
}
O tipo VECTORSEARCH habilita busca vetorial e nearest neighbor search, que são fundamentais para retrieval semântico.
Aqui já aparece uma diferença importante entre protótipos e ambientes reais. Em laboratório, qualquer vector database parece funcionar bem. Em produção, latência, custo, throughput e governança operacional rapidamente começam a importar.
Permissões do Bedrock
O Bedrock precisará acessar:
- os documentos no S3;
- os modelos de embeddings;
- e o OpenSearch Serverless.
A role base fica assim:
resource "aws_iam_role" "bedrock_role" {
name = "${var.project_name}-bedrock-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "bedrock.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
A policy de acesso ao bucket:
resource "aws_iam_policy" "s3_policy" {
name = "${var.project_name}-s3-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:ListBucket"
]
Resource = [
aws_s3_bucket.documents.arn,
"${aws_s3_bucket.documents.arn}/*"
]
}
]
})
}
E a policy de acesso aos modelos:
resource "aws_iam_policy" "bedrock_policy" {
name = "${var.project_name}-bedrock-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"bedrock:InvokeModel"
]
Resource = "*"
}
]
})
}
As policies são então anexadas à role.
resource "aws_iam_role_policy_attachment" "s3_attach" {
role = aws_iam_role.bedrock_role.name
policy_arn = aws_iam_policy.s3_policy.arn
}
resource "aws_iam_role_policy_attachment" "bedrock_attach" {
role = aws_iam_role.bedrock_role.name
policy_arn = aws_iam_policy.bedrock_policy.arn
}
Em muitos projetos, IAM acaba sendo tratado como detalhe secundário. Em aplicações RAG corporativas, normalmente acontece o oposto. O problema rapidamente passa a ser controle de acesso documental, segregação de conhecimento e permission-aware retrieval.
Criando a Knowledge Base
Agora provisionamos a Knowledge Base.
resource "aws_bedrockagent_knowledge_base" "rag_kb" {
name = "${var.project_name}-kb"
role_arn = aws_iam_role.bedrock_role.arn
knowledge_base_configuration {
type = "VECTOR"
vector_knowledge_base_configuration {
embedding_model_arn = "arn:aws:bedrock:${var.aws_region}::foundation-model/amazon.titan-embed-text-v2:0"
}
}
storage_configuration {
type = "OPENSEARCH_SERVERLESS"
opensearch_serverless_configuration {
collection_arn = aws_opensearchserverless_collection.vectors.arn
vector_index_name = "rag-index"
field_mapping {
vector_field = "vector"
text_field = "text"
metadata_field = "metadata"
}
}
}
}
Aqui o Bedrock passa a gerenciar:
- geração de embeddings;
- chunking;
- sincronização;
- retrieval;
- integração com o vector store.
Isso reduz significativamente a complexidade inicial da implementação, embora não elimine os desafios arquiteturais do RAG.
Conectando a fonte documental
A fonte documental será o bucket S3 provisionado anteriormente.
resource "aws_bedrockagent_data_source" "documents" {
knowledge_base_id = aws_bedrockagent_knowledge_base.rag_kb.id
name = "${var.project_name}-documents"
data_source_configuration {
type = "S3"
s3_configuration {
bucket_arn = aws_s3_bucket.documents.arn
}
}
}
Após o terraform apply, os documentos podem ser enviados normalmente para o bucket.
aws s3 cp ./sample-docs \
s3://SEU_BUCKET/ \
--recursive
Depois disso, basta iniciar a sincronização da Knowledge Base.
Durante esse processo:
- os documentos são processados;
- chunks são criados;
- embeddings são gerados;
- vetores são armazenados no OpenSearch.
O problema que quase sempre aparece: chunking
Poucos aspectos impactam tanto a qualidade do RAG quanto chunking.
Na maioria dos protótipos, chunking é tratado como simples divisão de texto. Em produção, ele se torna um dos principais fatores de qualidade da recuperação semântica.
Chunks muito grandes aumentam custo, degradam precisão e desperdiçam contexto. Chunks muito pequenos quebram significado semântico e reduzem coerência.
O problema piora em documentos corporativos, porque muitos possuem:
- tabelas;
- estruturas hierárquicas;
- referências cruzadas;
- seções dependentes;
- siglas organizacionais;
- nomenclaturas específicas.
Na prática, estratégias puramente baseadas em tamanho frequentemente produzem resultados ruins. Chunking semântico normalmente funciona melhor.
RAG não resolve documentação ruim
Esse talvez seja o principal choque de realidade em projetos corporativos.
Muitas organizações assumem implicitamente que IA resolverá:
- documentação inconsistente;
- conhecimento fragmentado;
- ausência de governança;
- conteúdo duplicado;
- documentação obsoleta.
Na prática, RAG amplifica exatamente a qualidade da informação existente.
Se os documentos são ruins, o sistema também será.
Custos e operação
Aplicações RAG introduzem novos componentes operacionais:
- embeddings;
- vector storage;
- retrieval;
- sincronização;
- inferência;
- reindexação.
Em pequena escala, isso pode parecer irrelevante. Em ambientes corporativos, custo rapidamente começa a importar, especialmente no OpenSearch Serverless e no consumo de tokens.
Além disso, aplicações RAG precisam ser observáveis.
Em produção, perguntas inevitavelmente surgem:
- quais chunks foram recuperados;
- qual foi a relevância;
- qual documento originou a resposta;
- quanto contexto foi enviado;
- qual foi o custo por consulta;
- qual foi a taxa de hallucination.
Sem observabilidade, troubleshooting se torna extremamente difícil.
Conclusão
RAG se consolidou como uma das arquiteturas mais importantes da atual geração de aplicações corporativas de IA. Entretanto, implementar RAG em produção vai muito além de conectar um modelo a uma base vetorial.
Os principais desafios normalmente aparecem em:
- governança documental;
- chunking;
- IAM;
- sincronização;
- observabilidade;
- custo;
- e qualidade do conhecimento organizacional.
O Amazon Bedrock Knowledge Bases reduz significativamente a complexidade operacional inicial, enquanto o Amazon OpenSearch Serverless fornece uma base vetorial gerenciada e escalável.
Com Terraform, toda essa arquitetura pode ser reproduzida de maneira consistente, auditável e alinhada com práticas modernas de infraestrutura como código.
No final, porém, o maior problema do RAG raramente é o modelo.
É a maturidade do conhecimento da própria organização.
Até o próximo post!
Comentários
Todo comentário passa por moderação antes de aparecer aqui. Nada é publicado automaticamente.
Carregando…