AWS Bedrock ve CDK ile RAG Agent Kurmak
AWS Bedrock + Knowledge Bases + OpenSearch Serverless üstüne CDK ile TypeScript kullanarak RAG agent kurmak — mimari, IAM bağlantısı, otomatik ingestion ve chat UI.
AWS, Bedrock Agent ile Knowledge Bases ve OpenSearch Serverless üçlüsünü yönetilen RAG yolu olarak konumlandırıyor: retrieval kodunu kendin yazmadan, belgeye dayalı sohbet uygulaması çıkarıyorsun. DigitalOcean rag-assistant şablonunun şeklini AWS-native servislere TypeScript ile CDK üzerinde taşıdım, uçtan uca dağıttım ve ilk koşunun düştüğünü gördüm. AWS Bedrock yönetilen RAG yığını CDK ile çalışıyor, ancak belge boşluğundan doğan iki açık ilk dağıtımını düşürecek: bölgeler arası inference profile için IAM açığı ve dağıtım anında otomatik ingestion job'un olmaması.
Mimari eşleme
Şekil, DO şablonu ile bire bir aynı. DO tarafında tek bir GenAI Agent yönetilen inference kümesi üzerinde, KBaaS de yönetilen bir vektör deposu ile birlikte geliyor. AWS tarafında aynı parçalar isimli servislere bölünmüş ve aralarını IaC ile sen kuruyorsun. Yedi servis, tek CDK yığını, 51 kaynak.
Tüm yığın us-east-1'de temiz şekilde yaklaşık 757 saniyede dağıtıldı. Aşağıdaki iki açık ilk koşuda sırasıyla yüzeye çıktı.
Yığın nasıl bağlanıyor
CDK kodu üç küçük özel construct'tan oluşuyor — VectorStore, KnowledgeBase, Agent — her biri aws-cdk-lib/aws-bedrock L1 primitive'leri (CfnKnowledgeBase, CfnDataSource, CfnAgent, CfnGuardrail) ile standart S3 ve IAM üzerine kurulu. Üçüncü taraf bir CDK kütüphanesi yok. Trap'lerden önce üç somut şekil görmeye değer.
S3 bucket + seed corpus. Belge bucket'i standart bir s3.Bucket; stack destroy edilince auto-delete oluyor. BucketDeployment yerel docs-sample/ dizinindeki seed corpus'u synth anında bucket'a yüklüyor, böylece ilk dağıtım elle yükleme adımı olmadan uçtan uca çalışıyor.
Knowledge Base + S3 data source. CfnKnowledgeBase, OpenSearch Serverless collection'a işaret ediyor ve Bedrock'un beklediği field mapping'i veriyor. CfnDataSource S3 bucket'ı bağlıyor ve sabit boyutta chunking stratejisi kuruyor — %20 örtüşmeli, 512 token'lık parçalar yoğun referans materyali için uygun.
Guardrail. CfnGuardrail bir içerik politikası (altı filtre tipi, input/output strength) ve hassas-bilgi politikası (PII varlıkları için anonymise-veya-block aksiyonları) alıyor. Agent'a bağlamak CfnAgent üzerinde bu kaynağın attrGuardrailId'sini referans alan tek bir guardrailConfiguration bloğu.
Her construct'ın tam kaynağı repo'nun lib/constructs/ dizininde. Aşağıdaki trap'lerin hepsi bu şeklin içinde bir yerde duruyor.
Bölgeler arası inference profile için IAM açığı
Yola çıktığım örnek snippet'lar bedrock:InvokeModel iznini arn:aws:bedrock:${region}::foundation-model/* üzerine veriyor. Bu ARN, yığının dağıtıldığı bölgeye sabitlenmiş durumda. Agent'a verdiğim Claude Sonnet 4.5 model kimliği ise bölgeler arası inference profile formunda: us.anthropic.claude-sonnet-4-5-20250929-v1:0. us.* ailesindeki profile'lar, altta yatan çağrıyı kapasitesi olan herhangi bir bölgeye yönlendiriyor — us-east-1'den çağrıldığında havuz us-east-1, us-east-2 ve us-west-2; yönlendirilen hedef küme başka kaynak bölgelerden farklı olabilir, bu yüzden kendi senaryon için Bedrock'un inference-profile belgelerine bak. IAM kontrolünü ise çağıranın bölgesi değil, yönlendirilen bölge belirliyor.
Sonuçta dağıtım başarılı oluyor. Agent Prepare başarılı. Ingestion başarılı (Titan Embed v2 bölgesel olduğu için bu da hatayı maskeliyor). Sonra SPA'dan ilk InvokeAgent çağrısı şu yanıtla dönüyor:
"Access denied when calling Bedrock. Check your request permissions and retry the request."
Servis izi yok, hata mesajında foundation-model ARN'i yok, bölge sabitlemesine işaret eden hiçbir şey yok. AgentRole üzerinde aws iam get-role-policy çalıştırdım, foundation-model satırını taradım ve ${region} değişkeninin tek bir değere pişmiş olduğunu gördüm. Çözüm: foundation model için bölge joker karakteri ve profile'ın kendisi için açık inference-profile/* kaynağı.
Foundation-model ARN'leri tasarım gereği hesap segmenti taşımıyor; bölge yuvasındaki *, politikayı us.* profile'ın yönlendirebileceği tüm bölgelere genişletiyor. Profile ARN'inin kendisi ise hesap segmenti içeriyor.
Bir tur fazladan kaybettiren küçük bir not: cdk deploy --hotswap yalnızca Lambda ve Step Functions kodu için iş gördüğünden, IAM-only diff'lerde "no changes" raporluyor. Politikayı gerçekten itmek için sade cdk deploy gerekiyor.
Dağıtım anında ingestion job yok
CfnKnowledgeBase ile CfnDataSource deklaratif kaynaklar. KB'yi kuruyor, S3 veri kaynağını bağlıyor. Ingestion job başlatmıyor. S3'e seed edilen korpus, biri bedrock-agent start-ingestion-job çağrısı yapana kadar OpenSearch'te sıfır vektör olarak duruyor.
Bu engel IAM açığından daha sinsi, çünkü hata bir retrieval kalitesi sorunu gibi görünüyor. Sohbet her soruya genel bir "bilgim yok" yanıtı veriyor. İlk refleks chunking'i, embedding'i ya da korpusu suçlamak oluyor. Asıl neden yığında belgeleri embed eden hiçbir şeyin tetiklenmemiş olması.
Üç tetikleyiciyi tarttım:
- Dağıtım sonrası
aws bedrock-agent start-ingestion-jobkoşan bir kabuk adımı. Çalışıyor, ama IaC dışında kalıyor ve sonraki dağıtımda unutuluyor. - EventBridge kuralı ve küçük bir Lambda. Her dağıtımda tam olarak bir kez çalışması gereken bir davranış için iki ekstra kaynak ve bir izin sıçraması demek.
- Aynı API'yi doğrudan CloudFormation'dan çağıran bir
AwsCustomResource.
AwsCustomResource'u seçtim. CloudFormation içinde tetikleniyor, izlenecek ayrı bir runtime'ı yok ve PhysicalResourceId'yi her synth'te değiştirince her dağıtımda yeniden tetikleniyor. Politika tek aksiyon ve tek ARN ile dar tutuluyor.
İki ayrıntı önemli. Update tarafındaki PhysicalResourceId içindeki Date.now(), her synth'i CloudFormation'a gerçek bir değişiklik gibi gösterip her dağıtımda yeniden ingestion'u zorluyor. Sonraki koşular incremental: Bedrock yalnızca yeni veya değişen S3 nesnelerini yeniden işliyor. Custom resource ayrıca korpusu seed eden BucketDeployment'a bağımlı, böylece job hiçbir zaman boş bir bucket üzerinde sıraya girmiyor.
Çağrı asenkron. CDK ingestion'un bitmesini beklemiyor; custom resource job sıraya girer girmez dönüyor. Bu testte üç küçük markdown belgesi, cdk deploy döndükten sonra yaklaşık 40 saniyede indekslendi. Bu davranış genellenebilir değil: ingestion süresi nesne sayısına, chunk boyutuna ve Bedrock'un yoğunluğuna bağlı. 40 saniyeyi tahmin değil, sağlık kontrolü olarak kullan.
Bedel
Faturayı OpenSearch Serverless domine ediyor. Collection 2 OCU minimumla çalışıyor ve indeksleme ya da sorgu olmasa bile saatlik ücret işliyor; us-east-1'de bırakılırsa ayda yaklaşık 350 USD'ye geliyor (2 OCU × 0,24 USD/OCU-saat × 730 saat). Bedrock çağrıları, Titan embedding'leri, S3, Lambda ve CloudWatch istek başına ücretlendirildiği için demo ölçekte ihmal edilebilir. Öğrenme projeleri için anlamlı tek akış: dağıt, test et, cdk destroy çalıştır, hepsi aynı saat içinde.
Kapanış
Bedrock yönetilen RAG'i değerlendiriyorsan repoyu klonla, README'yi izle ve iki açığın yukarıdaki sırayla yüzeye çıkmasını bekle: önce IAM, sonra ingestion. Bedrock yönetilen RAG, retrieval'i sıfırdan kurmaya kıyasla gerçek bir kısayol; ancak belgeler her kaynağı izole anlatıyor ve aralarındaki kabloyu sen döşüyorsun.
Bu küçük korpus üzerinde bir öğrenme raporu. Üretim ölçeğinde OCU boyutlandırma, çok kiracılı erişim desenleri ve rerank modeli entegrasyonu kapsam dışı.
Kaynaklar
- rag-agent-cdk reposu - Denemeye konu proje; burada referans verilen iki düzeltme
mainüzerindeki bireysel commit'ler. - DigitalOcean rag-assistant şablonu - AWS portunun şekil olarak yansıttığı şablon.
- AWS Bedrock Agents kullanıcı kılavuzu - Agent yapılandırması ve
InvokeAgentsemantikleri için birincil kaynak. - AWS Bedrock Knowledge Bases kullanıcı kılavuzu - KB, veri kaynağı ve ingestion job semantikleri için birincil kaynak.
- Bedrock cross-region inference profiles - Trap #1 arkasındaki
us.*havuz-bölge yönlendirme modeli. - Anthropic Claude on Bedrock model kimlikleri -
anthropic.claude-sonnet-4-5-20250929-v1:0veus.*cross-region profile ailesini doğrular. - AWS CDK aws_bedrock modülü -
CfnKnowledgeBase,CfnDataSource,CfnAgentreferansı. - AWS CDK custom_resources modülü - Trap #2 düzeltmesinin dayandığı construct.
- CloudFormation
AWS::Bedrock::DataSource- Kaynağın ingestion job lifecycle hook'u olmadığını doğrular. - Amazon OpenSearch Serverless fiyatlandırma - 2 OCU taban rakamının kaynağı.
- Vercel AI Elements - SPA'da kullanılan
Conversation,Message,PromptInputveSourcesbileşenleri. - Streamdown - AI Elements
Message'in sardığı markdown render edici; AI Elements geçişinde v2 plugin API'si belirleyici. - shadcn/ui CLI - AI Elements kurulumunun kullandığı
initbayrakları.