콘텐츠로 이동

Story 에이전트 구현 및 구성

스토리 에이전트는 Strands 에이전트로, Game과 컨텍스트용 Action 목록을 입력받아 스토리를 진행합니다. 이 에이전트를 인벤토리 MCP 서버와 연동하도록 구성하여 플레이어의 사용 가능한 아이템을 관리할 수 있게 합니다.

에이전트를 구현하려면 packages/story/dungeon_adventure_story/agent 내 다음 파일들을 업데이트하세요:

import uuid
import uvicorn
from bedrock_agentcore.runtime.models import PingStatus
from fastapi.responses import PlainTextResponse, StreamingResponse
from pydantic import BaseModel
from .agent import get_agent
from .init import app
class Action(BaseModel):
role: str
content: str
class InvokeInput(BaseModel):
playerName: str
genre: str
actions: list[Action]
async def handle_invoke(input: InvokeInput):
"""Streaming handler for agent invocation"""
messages = [{"role": "user", "content": [{"text": "Continue or create a new story..."}]}]
for action in input.actions:
messages.append({"role": action.role, "content": [{"text": action.content}]})
with get_agent(input.playerName, input.genre, session_id=str(uuid.uuid4())) as agent:
stream = agent.stream_async(messages)
async for event in stream:
print(event)
content = event.get("event", {}).get("contentBlockDelta", {}).get("delta", {}).get("text")
if content is not None:
yield content
elif event.get("event", {}).get("messageStop") is not None:
yield "\n"
@app.post("/invocations", openapi_extra={"x-streaming": True}, response_class=PlainTextResponse)
async def invoke(input: InvokeInput) -> str:
"""Entry point for agent invocation"""
return StreamingResponse(handle_invoke(input), media_type="text/event-stream")
@app.get("/ping")
def ping() -> str:
# TODO: if running an async task, return PingStatus.HEALTHY_BUSY
return PingStatus.HEALTHY
if __name__ == "__main__":
uvicorn.run("dungeon_adventure_story.agent.main:app", port=8080)

이 구성은 다음을 설정합니다:

  • 에이전트 페이로드에서 플레이어, 장르, 액션 추출,
  • SigV4 인증으로 MCP 서버를 호출할 수 있는 클라이언트 구성, 그리고
  • 시스템 프롬프트와 MCP 서버 도구를 포함한 에이전트 구성.

코드를 빌드하려면:

Terminal window
pnpm nx run-many --target build --all

애플리케이션을 배포하려면 다음 명령어를 실행하세요:

Terminal window
pnpm nx deploy infra dungeon-adventure-infra-sandbox/*

배포는 약 2분 정도 소요됩니다.

배포가 완료되면 다음과 유사한 출력이 표시됩니다 (일부 값은 편집됨):

Terminal window
dungeon-adventure-infra-sandbox-Application
dungeon-adventure-infra-sandbox-Application: deploying... [2/2]
dungeon-adventure-infra-sandbox-Application
Deployment time: 354s
Outputs:
dungeon-adventure-infra-sandbox-Application.ElectroDbTableTableNameXXX = dungeon-adventure-infra-sandbox-Application-ElectroDbTableXXX-YYY
dungeon-adventure-infra-sandbox-Application.GameApiEndpointXXX = https://xxx.execute-api.region.amazonaws.com/prod/
dungeon-adventure-infra-sandbox-Application.GameUIDistributionDomainNameXXX = xxx.cloudfront.net
dungeon-adventure-infra-sandbox-Application.InventoryMcpArn = arn:aws:bedrock-agentcore:region:xxxxxxx:runtime/dungeonadventureventoryMcpServerXXXX-YYYY
dungeon-adventure-infra-sandbox-Application.StoryAgentArn = arn:aws:bedrock-agentcore:region:xxxxxxx:runtime/dungeonadventurecationStoryAgentXXXX-YYYY
dungeon-adventure-infra-sandbox-Application.UserIdentityUserIdentityIdentityPoolIdXXX = region:xxx
dungeon-adventure-infra-sandbox-Application.UserIdentityUserIdentityUserPoolIdXXX = region_xxx

다음 방법 중 하나로 API를 테스트할 수 있습니다:

  • 에이전트 서버 로컬 인스턴스를 시작하고 curl로 호출하거나,
  • JWT 토큰을 사용하여 배포된 API를 curl로 호출합니다.

다음 명령어로 로컬 에이전트 서버를 시작하세요:

Terminal window
INVENTORY_MCP_ARN=arn:aws:bedrock-agentcore:region:xxxxxxx:runtime/dungeonadventureventoryMcpServerXXXX-YYYY AWS_REGION=<region> pnpm nx run dungeon_adventure.story:agent-serve

에이전트 서버가 실행되면(콘솔에 출력되지 않음) 다음 명령어로 호출하세요:

Terminal window
curl -N -X POST http://127.0.0.1:8081/invocations \
-d '{"genre":"superhero", "actions":[], "playerName":"UnnamedHero"}' \
-H "Content-Type: application/json"

명령이 성공적으로 실행되면 다음과 유사한 스트리밍 이벤트가 표시됩니다:

data: {"init_event_loop": true}
data: {"start": true}
data: {"start_event_loop": true}
data: {"event": {"messageStart": {"role": "assistant"}}}
data: {"event": {"contentBlockDelta": {"delta": {"text": "Welcome"}, "contentBlockIndex": 0}}}
...

축하합니다. Bedrock AgentCore 런타임에 첫 번째 Strands 에이전트를 구축하고 배포했습니다! 🎉🎉🎉