ํ”„๋กœํ•„

YuSoeun

๐Ÿข ๋น ๋ฅธ ๊ฑฐ๋ถ์ด๊ฐ€ ๋˜์ž. ๋“œ๋ฌธ๋“œ๋ฌธ ๊พธ์ค€ํžˆ๊ฐ€ ์•„๋‹Œ ์ด˜์ด˜ํžˆ ๊พธ์ค€ํ•˜๊ฒŒ!

[End-Gamers] AWS Bedrock ์—ฐ๋™ ์ค‘ ๋งŒ๋‚œ URL ์ด์ค‘ ์ธ์ฝ”๋”ฉ

2026. 6. 17. 23:34

๋“ค์–ด๊ฐ€๋ฉฐ

fix ์ปค๋ฐ‹์ด 5๊ฐœ ๋‚˜์™”๋‹ค.

incident-autopsy์— AWS Bedrock์„ ๋ถ™์ด๋Š” ์ž‘์—…์ด์—ˆ๋‹ค.
Claude API๋ฅผ ์ง์ ‘ ์“ฐ๋ฉด ํ•œ ๋ฒˆ์— ๋๊ฒ ์ง€๋งŒ,

ํŒ€ ํ™˜๊ฒฝ ํŠน์„ฑ์ƒ Bedrock์„ ํ†ตํ•ด์•ผ ํ–ˆ๋‹ค. ๊ฐ„๋‹จํ•  ์ค„ ์•Œ์•˜๋Š”๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ์˜ค๋ž˜ ๊ฑธ๋ ธ๋‹ค.

 

์ด ๊ธ€์€ ๊ทธ 5๊ฐœ ์ปค๋ฐ‹ ๋™์•ˆ ๋ญ˜ ๋งŒ๋‚ฌ๋Š”์ง€ ๊ธฐ๋ก์ด๋‹ค.

 

 


1. ์„ค๊ณ„ ๊ตฌ์กฐ — AI ์ œ๊ณต์‚ฌ๋ฅผ ๊ฐˆ์•„๋ผ์šธ ์ˆ˜ ์žˆ๊ฒŒ

์ฒ˜์Œ๋ถ€ํ„ฐ AI ์ œ๊ณต์‚ฌ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ–ˆ๋‹ค. ํŒ€๋งˆ๋‹ค ์“ฐ๋Š” ํ™˜๊ฒฝ์ด ๋‹ค๋ฅด๊ณ , Bedrock์ด ์•ˆ ๋˜๋Š” ์ƒํ™ฉ์—์„œ Groq์œผ๋กœ ๋น ๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•  ๋•Œ๋„ ์žˆ์œผ๋‹ˆ๊นŒ.

ai/base.py           ← ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
ai/claude_client.py  ← Anthropic ์ง์ ‘ ํ˜ธ์ถœ
ai/groq_client.py    ← Groq
ai/bedrock_client.py ← AWS Bedrock

AIDispatcher๊ฐ€ ์„ค์ •๊ฐ’์— ๋”ฐ๋ผ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ณจ๋ผ์ฃผ๊ณ , ์„œ๋น„์Šค ๋ ˆ์ด์–ด๋Š” ์–ด๋–ค AI๋ฅผ ์“ฐ๋Š”์ง€ ๋ชฐ๋ผ๋„ ๋œ๋‹ค. ์ด ๊ตฌ์กฐ ๋•๋ถ„์— ๋‚˜์ค‘์— Groq → Bedrock ๊ต์ฒด๊ฐ€ ์„ค์ • ํ•œ ์ค„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ€๋Šฅํ–ˆ๋‹ค.

 


2. invoke_model์ด ๋‚ด๋ฟœ์€ ์ฒซ ๋ฒˆ์งธ ์—๋Ÿฌ

Bedrock ์ฒซ ์—ฐ๋™์€ AnthropicBedrock SDK๋กœ ์‹œ๋„ํ–ˆ๋‹ค.

๊ทผ๋ฐ ํŒ€ AWS ํ™˜๊ฒฝ์—์„œ MFA ์ž๊ฒฉ์ฆ๋ช…์„ ์ œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ–ˆ๋‹ค. ๋ฐ”๋กœ boto3๋กœ ๊ต์ฒดํ–ˆ๋‹ค.

response = boto3_client.invoke_model(
    modelId="anthropic.claude-sonnet-4-6",
    body=json.dumps(payload)
)

 


3. URL ์ด์ค‘ ์ธ์ฝ”๋”ฉ

invoke_model์ด modelId๋ฅผ URL ๊ฒฝ๋กœ์— ์ง์ ‘ ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ์‹์„ ์“ฐ๋Š”๋ฐ,

์ด ๊ณผ์ •์—์„œ botocore๊ฐ€ ํ•œ ๋ฒˆ ๋” ์ธ์ฝ”๋”ฉ์„ ํ•œ๋‹ค.

anthropic.claude-sonnet-4-6
    ↓  invoke_model์ด URL ๊ฒฝ๋กœ์— ์‚ฝ์ž…
anthropic.claude-sonnet-4-6
    ↓  botocore๊ฐ€ ์ถ”๊ฐ€ ์ธ์ฝ”๋”ฉ
anthropic%2Eclaude-sonnet-4-6  ← Bedrock์ด ์ธ์‹ ๋ถˆ๊ฐ€

.์ด %2E๋กœ ๋ฐ”๋€Œ๋ฉด์„œ Bedrock์ด ๋ชจ๋ธ ID๋ฅผ ๋ชป ์ฝ๋Š” ๊ฒƒ์ด๋‹ค.

๋ชจ๋ธ ID ์ž์ฒด๋Š” ๋งž๋Š”๋ฐ ์„œ๋ฒ„๊นŒ์ง€ ๊ฐ€๋Š” ๊ณผ์ •์—์„œ ๋ง๊ฐ€์กŒ๋‹ค.

 


4. ํ•ด๊ฒฐ ๊ณผ์ •

์ฒ˜์Œ์—๋Š” URL ์ธ์ฝ”๋”ฉ์„ ์šฐํšŒํ•˜๋ ค๊ณ  botocore์˜ AWS Signature V4๋ฅผ ์ง์ ‘ ๊บผ๋‚ด์„œ httpx๋กœ Bedrock์„ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์„ ์‹œ๋„ํ–ˆ๋‹ค. ๋™์ž‘์€ ํ–ˆ๋‹ค. ๊ทผ๋ฐ botocore ๋‚ด๋ถ€๋ฅผ ๊ฑด๋“œ๋ฆฌ๋Š” ์ฝ”๋“œ๋Š” ๋ฒ„์ „์ด ๋ฐ”๋€Œ๋ฉด ์–ธ์ œ ํ„ฐ์งˆ์ง€ ๋ชฐ๋ผ์„œ ํฌ๊ธฐํ–ˆ๋‹ค.

 

converse API๋กœ ๊ต์ฒดํ•˜๋Š” ๊ฒŒ ์ •๋‹ต์ด์—ˆ๋‹ค.

response = boto3_client.converse(
    modelId="anthropic.claude-sonnet-4-6",
    messages=[{"role": "user", "content": [{"text": prompt}]}],
    inferenceConfig={"maxTokens": 2048}
)

invoke_model์€ modelId๋ฅผ URL ๊ฒฝ๋กœ์— ๋ฌธ์ž์—ด๋กœ ๋ฐ•์•„ ๋„ฃ์ง€๋งŒ, converse๋Š” ๋‚ด๋ถ€ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ๋‹ฌ๋ผ์„œ ์ด์ค‘ ์ธ์ฝ”๋”ฉ์ด ์ƒ๊ธฐ์ง€ ์•Š๋Š”๋‹ค. ์—๋Ÿฌ๊ฐ€ ์‚ฌ๋ผ์กŒ๋‹ค.

 


5. ์—ฐ๊ฒฐ๋๋”๋‹ˆ JSON ํŒŒ์‹ฑ ์‹คํŒจ

Bedrock ์—ฐ๊ฒฐ์€ ๋๋Š”๋ฐ ์ด๋ฒˆ์—” ๋ถ„์„ ๊ฒฐ๊ณผ๊ฐ€ ํŒŒ์‹ฑ์ด ์•ˆ ๋๋‹ค.

AI์—๊ฒŒ JSON์„ ๋ฑ‰์œผ๋ผ๊ณ  ํ”„๋กฌํ”„ํŠธ๋ฅผ ์คฌ๋Š”๋ฐ, ์‘๋‹ต์— ๋งˆํฌ๋‹ค์šด ์ฝ”๋“œ ๋ธ”๋ก์ด ๊ฐ์‹ธ์ ธ์„œ ์™”๋‹ค.

```json
{
  "severity": "HIGH",
  ...
}

์ด๊ฑธ `json.loads()`์— ๊ทธ๋ƒฅ ๋„ฃ์œผ๋ฉด ํ„ฐ์ง„๋‹ค. 

ํ”„๋กฌํ”„ํŠธ ๋ฌธ์ œ์ธ๊ฐ€ ์‹ถ์–ด์„œ ๊ณ ์ณ๋ดค๋Š”๋ฐ ์ผ๊ด€์„ฑ์ด ์—†์—ˆ๋‹ค. 

 

Claude, Groq, Bedrock์ด ๋งˆํฌ๋‹ค์šด์„ ๋ถ™์ด๋Š” ๊ธฐ์ค€์ด ์ œ๊ฐ๊ฐ์ด์—ˆ๋‹ค. ์ œ

๊ณต์‚ฌ๋งˆ๋‹ค ๋‹ค๋ฅด๊ณ , ๊ฐ™์€ ์ œ๊ณต์‚ฌ์—์„œ๋„ ์š”์ฒญ ๋‚ด์šฉ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์กŒ๋‹ค.

 

6. depth ์นด์šดํ„ฐ๋กœ JSON ์ถ”์ถœ

์ •๊ทœ์‹์œผ๋กœ JSON ๋ถ€๋ถ„๋งŒ ๋ฝ‘๋Š” ๊ฒƒ๋„ ํ•œ๊ณ„๊ฐ€ ์žˆ์—ˆ๋‹ค. ์ค‘์ฒฉ๋œ JSON์—์„œ ๋‹ซํž˜ ๊ด„ํ˜ธ๊ฐ€ ์–ด๋””์ธ์ง€ ์ •ํ™•ํžˆ ๋ชป ์ฐพ๋Š”๋‹ค.
๋”ฐ๋ผ์„œ, `{`์™€ `}`์˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๋Š” depth ์นด์šดํ„ฐ ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.

def extract_json(text: str) -> dict:
    text = re.sub(r'```json\s*', '', text)
    text = re.sub(r'```\s*', '', text)

    start = text.find('{')
    depth = 0
    for i, ch in enumerate(text[start:], start):
        if ch == '{':
            depth += 1
        elif ch == '}':
            depth -= 1
            if depth == 0:
                return json.loads(text[start:i+1])

{๋ฅผ ๋งŒ๋‚˜๋ฉด depth +1, }๋ฅผ ๋งŒ๋‚˜๋ฉด depth -1. depth๊ฐ€ 0์ด ๋˜๋Š” ์ˆœ๊ฐ„์ด JSON ๋์ด๋‹ค. ๋งˆํฌ๋‹ค์šด์ด ์•ž๋’ค์— ๋ญ˜ ๋ถ™์ด๋“  ์ƒ๊ด€์—†์ด ๋™์ž‘ํ•œ๋‹ค.

์ด๊ฑธ extract_json ์œ ํ‹ธ๋กœ ๋นผ์„œ ๋ชจ๋“  AI ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ™์ด ์“ฐ๊ฒŒ ํ–ˆ๋‹ค.

 


7. Groq์ด Tool Use๋ฅผ ์•ˆ ์“ฐ๋Š” ๋ฌธ์ œ

Bedrock Tool Use ๊ตฌ์กฐ์™€ Groq Tool Use ๊ตฌ์กฐ๊ฐ€ ๋‹ฌ๋ž๋‹ค.

# Bedrock
{"toolUse": {"toolUseId": "...", "name": "analyze", "input": {...}}}

# Groq
{"tool_calls": [{"function": {"name": "analyze", "arguments": "..."}}]}

ํŒŒ์‹ฑ ์ฝ”๋“œ๋ฅผ ํด๋ผ์ด์–ธํŠธ๋ณ„๋กœ ๋”ฐ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Groq์€ Tool Use๋ฅผ ์•ˆ ์“ฐ๊ณ  ๊ทธ๋ƒฅ ํ…์ŠคํŠธ๋กœ ์‘๋‹ตํ•ด๋ฒ„๋ฆฌ๋Š” ์ผ€์ด์Šค๊ฐ€ ์žˆ์—ˆ๋‹ค. ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์— "๋ฐ˜๋“œ์‹œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ผ"๋Š” ์ง€์นจ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ–ˆ๋‹ค.

 


8. ๋งˆ๋ฌด๋ฆฌ

๊ฒฐ๊ตญ Claude, Groq, Bedrock ์„ธ ์ œ๊ณต์‚ฌ๊ฐ€ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋™์ž‘ํ•˜๊ฒŒ ๋๋‹ค. ์ œ๊ณต์‚ฌ๋ฅผ ๋ฐ”๊พธ๋ ค๋ฉด ์„ค์ • ํ•œ ์ค„๋งŒ ๊ณ ์น˜๋ฉด ๋œ๋‹ค. ์ด ์œ ์—ฐ์„ฑ์€ ๋‚˜์ค‘์— Haiku 4.5๋กœ ๋ชจ๋ธ์„ ๊ต์ฒดํ•  ๋•Œ ๋น›์„ ๋ฐœํ–ˆ๋‹ค.

 

Bedrock์€ boto3 ์ค‘์—์„œ๋„ ์–ด๋–ค API๋ฅผ ์“ฐ๋Š”์ง€์— ๋”ฐ๋ผ ๋‚ด๋ถ€ ๋™์ž‘์ด ๋‹ค๋ฅด๋‹ค๋Š” ๊ฑธ ์ด๋ฒˆ์— ์•Œ์•˜๋‹ค. ๊ณต์‹ ๋ฌธ์„œ์— ์ž˜ ๋‚˜์˜ค์ง€ ์•Š๋Š” ์ข…๋ฅ˜์˜ ํ•จ์ •์ด๋‹ค.

 


์—๋Ÿฌ ๋ฉ”์‹œ์ง€๊ฐ€ "invalid model identifier"๋ผ๊ณ  ํ•ด๋„,
๋ชจ๋ธ ID๊ฐ€ ์•„๋‹Œ URL ์ธ์ฝ”๋”ฉ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ๋‹ค.
๊ฐ€์žฅ ์•ˆ์ชฝ์„ ์˜์‹ฌํ•˜๊ธฐ ์ „์— ๊ฐ€์žฅ ๋ฐ”๊นฅ์ชฝ์„ ๋จผ์ € ํ™•์ธํ•˜์ž.

End-Gamers | incident-autopsy

RELATED ARTICLES

more