Skip to content

Commit c6ce28d

Browse files
authored
Merge pull request #34 from heungh/feature/bedrock-usage-tracker
2 parents d8153a0 + f54fb2b commit c6ce28d

32 files changed

Lines changed: 13069 additions & 0 deletions

bedrock/bedrock_usage/README.md

Lines changed: 2378 additions & 0 deletions
Large diffs are not rendered by default.

bedrock/bedrock_usage/README_en.md

Lines changed: 1205 additions & 0 deletions
Large diffs are not rendered by default.

bedrock/bedrock_usage/basic/README.md

Lines changed: 874 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Bedrock Application with RequestMetadata for Usage Tracking
4+
이 애플리케이션은 여러 시나리오에서 Bedrock을 호출하며,
5+
각 호출에 requestMetadata를 포함하여 CloudWatch Logs에서 추적 가능합니다.
6+
"""
7+
8+
import boto3
9+
import json
10+
import time
11+
from datetime import datetime
12+
13+
# Bedrock Runtime 클라이언트 생성
14+
client = boto3.client('bedrock-runtime', region_name='us-east-1')
15+
16+
17+
def invoke_bedrock_with_metadata(
18+
prompt: str,
19+
app_name: str,
20+
app_id: str,
21+
environment: str,
22+
team: str,
23+
cost_center: str,
24+
tenant_id: str = None,
25+
user_id: str = None
26+
):
27+
"""
28+
Bedrock Converse API를 호출하고 requestMetadata를 포함합니다.
29+
30+
Args:
31+
prompt: 사용자 프롬프트
32+
app_name: 애플리케이션 이름
33+
app_id: 애플리케이션 ID
34+
environment: 환경 (production, staging, dev)
35+
team: 팀 이름
36+
cost_center: 비용 센터 코드
37+
tenant_id: 테넌트 ID (옵션)
38+
user_id: 사용자 ID (옵션)
39+
40+
Returns:
41+
Bedrock API 응답
42+
"""
43+
44+
# requestMetadata 구성
45+
metadata = {
46+
"application_name": app_name,
47+
"application_id": app_id,
48+
"environment": environment,
49+
"team": team,
50+
"cost_center": cost_center,
51+
"timestamp": datetime.now().isoformat()
52+
}
53+
54+
# 옵션 필드 추가
55+
if tenant_id:
56+
metadata["tenant_id"] = tenant_id
57+
if user_id:
58+
metadata["user_id"] = user_id
59+
60+
print(f"\n{'='*80}")
61+
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Invoking Bedrock")
62+
print(f"Application: {app_name} ({app_id})")
63+
print(f"Environment: {environment}")
64+
print(f"Prompt: {prompt[:50]}...")
65+
print(f"Metadata: {json.dumps(metadata, indent=2)}")
66+
67+
try:
68+
# Bedrock Converse API 호출
69+
response = client.converse(
70+
modelId='anthropic.claude-3-haiku-20240307-v1:0',
71+
messages=[
72+
{
73+
"role": "user",
74+
"content": [{"text": prompt}]
75+
}
76+
],
77+
requestMetadata=metadata
78+
)
79+
80+
# 응답 처리
81+
output_text = response['output']['message']['content'][0]['text']
82+
input_tokens = response['usage']['inputTokens']
83+
output_tokens = response['usage']['outputTokens']
84+
total_tokens = input_tokens + output_tokens
85+
86+
print(f"\n✅ Success!")
87+
print(f"Input Tokens: {input_tokens}")
88+
print(f"Output Tokens: {output_tokens}")
89+
print(f"Total Tokens: {total_tokens}")
90+
print(f"Response (first 200 chars): {output_text[:200]}...")
91+
print(f"{'='*80}\n")
92+
93+
return response
94+
95+
except Exception as e:
96+
print(f"\n❌ Error: {str(e)}")
97+
print(f"{'='*80}\n")
98+
raise
99+
100+
101+
def scenario_customer_service():
102+
"""시나리오 1: 고객 서비스 애플리케이션"""
103+
print("\n" + "="*80)
104+
print("SCENARIO 1: Customer Service Application")
105+
print("="*80)
106+
107+
prompts = [
108+
"How do I reset my password?",
109+
"What is your refund policy?",
110+
"I need help with my order #12345"
111+
]
112+
113+
for i, prompt in enumerate(prompts, 1):
114+
invoke_bedrock_with_metadata(
115+
prompt=prompt,
116+
app_name="CustomerServiceApp",
117+
app_id="app-001",
118+
environment="production",
119+
team="customer-support",
120+
cost_center="CS-123",
121+
tenant_id=f"tenant-{100 + i}",
122+
user_id=f"user-{200 + i}"
123+
)
124+
time.sleep(1) # Rate limiting
125+
126+
127+
def scenario_sales_assistant():
128+
"""시나리오 2: 세일즈 어시스턴트 애플리케이션"""
129+
print("\n" + "="*80)
130+
print("SCENARIO 2: Sales Assistant Application")
131+
print("="*80)
132+
133+
prompts = [
134+
"What are the features of your enterprise plan?",
135+
"Can you compare the basic and premium tiers?"
136+
]
137+
138+
for i, prompt in enumerate(prompts, 1):
139+
invoke_bedrock_with_metadata(
140+
prompt=prompt,
141+
app_name="SalesAssistantApp",
142+
app_id="app-002",
143+
environment="production",
144+
team="sales",
145+
cost_center="SALES-456",
146+
tenant_id=f"prospect-{300 + i}",
147+
user_id=f"sales-rep-{400 + i}"
148+
)
149+
time.sleep(1)
150+
151+
152+
def scenario_internal_tools():
153+
"""시나리오 3: 내부 도구 (개발 환경)"""
154+
print("\n" + "="*80)
155+
print("SCENARIO 3: Internal Tools (Development)")
156+
print("="*80)
157+
158+
prompts = [
159+
"Generate a SQL query to find all users created in the last 30 days",
160+
"Write a Python function to validate email addresses"
161+
]
162+
163+
for i, prompt in enumerate(prompts, 1):
164+
invoke_bedrock_with_metadata(
165+
prompt=prompt,
166+
app_name="DeveloperToolsApp",
167+
app_id="app-003",
168+
environment="development",
169+
team="engineering",
170+
cost_center="ENG-789",
171+
user_id=f"dev-{500 + i}"
172+
)
173+
time.sleep(1)
174+
175+
176+
def scenario_multi_tenant():
177+
"""시나리오 4: 멀티테넌트 SaaS"""
178+
print("\n" + "="*80)
179+
print("SCENARIO 4: Multi-Tenant SaaS Application")
180+
print("="*80)
181+
182+
# 여러 테넌트의 요청 시뮬레이션
183+
tenants = [
184+
{"id": "acme-corp", "name": "ACME Corporation"},
185+
{"id": "globex-inc", "name": "Globex Inc"},
186+
{"id": "initech-llc", "name": "Initech LLC"}
187+
]
188+
189+
prompt = "Summarize the key points from our meeting notes"
190+
191+
for tenant in tenants:
192+
invoke_bedrock_with_metadata(
193+
prompt=prompt,
194+
app_name="DocumentAnalysisApp",
195+
app_id="app-004",
196+
environment="production",
197+
team="product",
198+
cost_center="PROD-999",
199+
tenant_id=tenant["id"],
200+
user_id=f"user-{tenant['id']}-001"
201+
)
202+
time.sleep(1)
203+
204+
205+
def main():
206+
"""메인 함수 - 모든 시나리오 실행"""
207+
print("\n" + "="*80)
208+
print("🚀 Starting Bedrock Application with RequestMetadata")
209+
print("="*80)
210+
print("\nThis application will generate sample requests with different metadata")
211+
print("to demonstrate usage tracking in CloudWatch Logs.\n")
212+
213+
print("⚠️ Prerequisites:")
214+
print(" 1. Bedrock Model Invocation Logging must be enabled")
215+
print(" 2. CloudWatch Logs destination configured")
216+
print(" 3. Appropriate IAM permissions for Bedrock API calls\n")
217+
218+
try:
219+
# 각 시나리오 실행
220+
scenario_customer_service()
221+
scenario_sales_assistant()
222+
scenario_internal_tools()
223+
scenario_multi_tenant()
224+
225+
print("\n" + "="*80)
226+
print("✅ All scenarios completed successfully!")
227+
print("="*80)
228+
print("\n📊 Next Steps:")
229+
print(" 1. Wait 2-3 minutes for logs to appear in CloudWatch")
230+
print(" 2. Go to CloudWatch Logs console")
231+
print(" 3. Select log group: /aws/bedrock/modelinvocations")
232+
print(" 4. Use the CloudWatch Logs Insights queries provided")
233+
print("="*80 + "\n")
234+
235+
except Exception as e:
236+
print(f"\n❌ Error running scenarios: {str(e)}")
237+
raise
238+
239+
240+
if __name__ == "__main__":
241+
main()

0 commit comments

Comments
 (0)