Bỏ qua để đến nội dung

Triển khai và cấu hình Story agent

Story Agent là một agent Strands được tạo với --protocol=AG-UI trong Module 1, để UI có thể stream từ nó qua Agent-User Interaction protocol thông qua CopilotKit. Nó sử dụng Inventory MCP Server để quản lý các vật phẩm của người chơi, và S3SessionManager tích hợp sẵn của Strands để lưu trữ lịch sử hội thoại vào sessions bucket mà chúng ta đã cung cấp trong Module 2.

Cập nhật các file sau trong packages/story/dungeon_adventure_story/agent:

import logging
import os
from functools import cache
from typing import Any, cast
from ag_ui.core import RunAgentInput
from ag_ui_strands import StrandsAgent, StrandsAgentConfig, create_strands_app
from aws_lambda_powertools.utilities import parameters
from strands.session import FileSessionManager, S3SessionManager, SessionManager
from .agent import get_agent
logging.basicConfig(level=logging.INFO)
@cache
def _resolve_sessions_bucket() -> str:
"""Read the conversation-history bucket name from runtime config.
Resolved lazily (and memoised) so `fastapi dev` can import this module
before ``RUNTIME_CONFIG_APP_ID`` is in the environment.
"""
application = os.environ.get("RUNTIME_CONFIG_APP_ID")
if not application:
raise RuntimeError("RUNTIME_CONFIG_APP_ID is not set — cannot resolve the StorySessions bucket.")
provider = parameters.AppConfigProvider(environment="default", application=application)
buckets = cast(dict[str, Any], provider.get("buckets", transform="json"))
return buckets["StorySessions"]["bucketName"]
def _session_manager_provider(input_data: RunAgentInput) -> SessionManager:
"""Create a session manager keyed by the AG-UI thread_id.
- In AgentCore (and `agent-serve`), persist to the shared ``StorySessions``
S3 bucket — the same bucket the Game API reads from to rebuild
conversation history on revisit.
- In `agent-serve-local` (`SERVE_LOCAL=true`), persist to a temp
directory so the agent can run fully offline against the local MCP
server without any AWS calls.
"""
session_id = input_data.thread_id or "default"
if os.environ.get("SERVE_LOCAL") == "true":
return FileSessionManager(session_id=session_id, storage_dir="/tmp/strands-sessions")
return S3SessionManager(session_id=session_id, bucket=_resolve_sessions_bucket())
# The template Agent is cloned per thread_id by ``StrandsAgent`` — we plug in
# a ``session_manager_provider`` so each thread gets its own session manager
# and conversation history is replayed on subsequent turns and survives agent
# restarts.
_agent_ctx = get_agent()
_agent = _agent_ctx.__enter__()
agui_agent = StrandsAgent(
agent=_agent,
name="StoryAgent",
description="A Strands Agent exposed via the AG-UI protocol.",
config=StrandsAgentConfig(session_manager_provider=_session_manager_provider),
)
app = create_strands_app(agui_agent, path="/invocations")

Các thay đổi là:

  • main.py thêm một session_manager_provider tạo ra một S3SessionManager cho mỗi thread_id khi được triển khai, và quay về sử dụng FileSessionManager trên đĩa tại /tmp/strands-sessions khi chạy dưới agent-serve-local (SERVE_LOCAL=true). Khi triển khai, S3 bucket là cùng một bucket mà queryActions của Game API đọc từ đó, do đó trình duyệt có thể xây dựng lại bản ghi khi truy cập lại; ở cục bộ, agent chạy hoàn toàn offline với local MCP server mà không có bất kỳ lời gọi AWS nào.
  • agent.py loại bỏ sample tool subtract và thay thế system prompt bằng một prompt dungeon-master mời tin nhắn đầu tiên của người dùng nêu tên người chơi và thể loại, đồng thời sử dụng các tool của Inventory MCP Server.

Để build code:

Terminal window
pnpm build

Để triển khai ứng dụng của bạn, chạy lệnh sau:

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

Quá trình triển khai này sẽ mất khoảng 2 phút để hoàn thành.

Khi quá trình triển khai hoàn tất, bạn sẽ thấy các output tương tự như sau (một số giá trị đã được ẩn):

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.RuntimeConfigApplicationId = xxxx
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

Bạn có thể kiểm thử Agent của mình bằng một trong hai cách:

  • Khởi động một instance cục bộ của Agent server và trò chuyện với nó thông qua target agent-chat được tạo ra, hoặc
  • Gọi API đã triển khai bằng curl với JWT token.

Mở một REPL tương tác với bản sao được phục vụ cục bộ của AG-UI agent bằng cách sử dụng target agent-chat được tạo ra:

Terminal window
pnpm nx agent-chat story

agent-chatdependsOn: ['agent-serve-local'], do đó không cần khởi động agent server riêng biệt — Nx sẽ spawn agent-serve-local (lần lượt khởi động Inventory MCP server cục bộ), sau đó khởi chạy agent-chat-cli AG-UI REPL với http://localhost:8081/invocations. Tin nhắn đầu tiên của bạn nên cho agent biết tên anh hùng của bạn và thể loại (ví dụ: My name is Alice. Start my zombie adventure.) và câu chuyện sẽ được stream trả về.

Nếu lệnh chạy thành công, bạn sẽ bắt đầu thấy câu chuyện được stream trả về dưới dạng một AG-UI event stream (Server-Sent Events) — các chunk RUN_STARTED / TEXT_MESSAGE_START / TEXT_MESSAGE_CONTENT bao bọc các token câu chuyện thực tế:

data: {"type":"RUN_STARTED","threadId":"Alice-zombie00000000000000000000000",...}
data: {"type":"TEXT_MESSAGE_START","messageId":"...","role":"assistant"}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"...","delta":"Greetings, Alice. "}
data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"...","delta":"The moans grow louder beyond the barricaded door..."}

Chúc mừng. Bạn đã xây dựng và triển khai Strands Agent đầu tiên của mình trên Bedrock AgentCore Runtime! 🎉🎉🎉