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
import uuid
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 dungeon_adventure_agent_connection import session_id_context
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from strands.session import FileSessionManager, S3SessionManager, SessionManager
from .agent import get_agent
logging.basicConfig(level=logging.INFO)
SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
@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-dev` (`LOCAL_DEV=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("LOCAL_DEV") == "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),
)
class _SessionIdMiddleware(BaseHTTPMiddleware):
"""Bind the session ID for this request so downstream MCP / A2A clients forward it on outbound calls."""
async def dispatch(self, request: Request, call_next):
session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
with session_id_context(session_id):
return await call_next(request)
app = create_strands_app(agui_agent, path="/invocations")
app.add_middleware(_SessionIdMiddleware)

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-dev (LOCAL_DEV=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 lưu trữ các session vào đĩa và giao tiếp với local MCP server, mà không cần triển khai.
  • 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.

Nhiệm vụ 2: Kiểm thử Agent của bạn ở cục bộ

Phần tiêu đề “Nhiệm vụ 2: Kiểm thử Agent của bạn ở cục bộ”

Để build code:

Terminal window
pnpm build

Target agent-chat được tạo ra sẽ mở một REPL tương tác với agent của bạn. Nó chạy độc lập và kết nối với agent đang chạy cục bộ của bạn, vì vậy trước tiên hãy khởi động local server của agent trong một terminal:

Terminal window
pnpm nx agent-dev story

Sau đó, trong terminal thứ hai, khởi động chat:

Terminal window
pnpm nx agent-chat story

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ề.

Chúc mừng. Bạn đã xây dựng và kiểm thử Strands Agent đầu tiên của mình ở cục bộ! 🎉🎉🎉