MCP Server 终于能"记住"用户了:AgentCore 有状态会话实战

MCP Server 终于能"记住"用户了:AgentCore 有状态会话实战

搞 MCP 的都知道一个蛋疼的问题:server 不记状态。用户上一轮说了啥,下一轮完全不知道。

上周亚马逊云科技给 Bedrock AgentCore 加了有状态 MCP 支持,我第一时间试了试。三个新能力:Elicitation(主动追问)Sampling(反向调 LLM)Progress(进度通知)。跑通之后确实挺惊喜的。

痛点在哪

想象你在做一个订机票的 MCP tool。用户说"去巴黎",然后你需要知道日期、人数、舱位。

原来的做法?要么让用户一次性传完所有参数,要么自己在外面搞个 Redis 存状态。server 本身就是个无状态函数。

现在不用了。ctx.elicit() 让 server 可以在 tool 执行过程中暂停下来问用户,拿到回答再继续。

核心代码

环境:

bash 复制代码
pip install "fastmcp>=2.10.0" mcp

Server 端关键部分:

python 复制代码
from fastmcp import FastMCP, Context
from enum import Enum

mcp = FastMCP("Travel-Booking-Agent")

class TripType(str, Enum):
    BUSINESS = "business"
    LEISURE = "leisure"
    FAMILY = "family"

DESTINATIONS = {
    "paris": {"name": "Paris, France", "flight": 450, "hotel": 180,
              "highlights": ["Eiffel Tower", "Louvre", "Notre-Dame"]},
    "tokyo": {"name": "Tokyo, Japan", "flight": 900, "hotel": 150,
              "highlights": ["Shibuya", "Senso-ji Temple", "Mt. Fuji day trip"]},
}

@mcp.tool()
async def plan_trip(ctx: Context) -> str:
    # 追问目的地
    dest_result = await ctx.elicit(
        message="去哪儿?可选: Paris, Tokyo",
        response_type=str
    )
    if dest_result.action != "accept":
        return "已取消"
    dest = DESTINATIONS.get(dest_result.data.lower().strip())

    # 追问旅行类型
    type_result = await ctx.elicit(
        message="旅行类型?business / leisure / family",
        response_type=TripType
    )

    # 追问天数
    days_result = await ctx.elicit(
        message="待几天?(3-14)",
        response_type=int
    )
    days = max(3, min(14, days_result.data))

    # 进度通知
    for i in range(1, 6):
        await ctx.report_progress(progress=i, total=5)
        await asyncio.sleep(0.4)

    # 反向调 LLM 生成推荐
    try:
        response = await ctx.sample(
            messages=f"Give 3 tips for {dest['name']}, {days} days",
            max_tokens=150
        )
        tips = response.text
    except Exception:
        tips = f"Visit {dest['highlights'][0]}!"

    return f"Booked: {dest['name']}, {days} days\nTips: {tips}"

启动时记得关无状态模式:

python 复制代码
mcp.run(
    transport="streamable-http",
    host="0.0.0.0",
    port=8000,
    stateless_http=False  # 必须!
)

客户端怎么接

python 复制代码
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
from fastmcp.client.elicitation import ElicitResult
from mcp.types import CreateMessageResult, TextContent

async def elicit_handler(message, response_type, params, ctx):
    print(f"\n>>> {message}")
    response = input("回答: ").strip()
    if response_type == int:
        response = int(response)
    return ElicitResult(action="accept", content={"value": response})

async def sampling_handler(messages, params, ctx):
    return CreateMessageResult(
        role="assistant",
        content=TextContent(type="text", text="试试当地小吃!"),
        model="test-model",
        stopReason="endTurn"
    )

async def progress_handler(progress, total, message):
    pct = int((progress / total) * 100) if total else 0
    print(f"\r  进度: {pct}%", end="", flush=True)
    if progress == total:
        print(" ✅")

transport = StreamableHttpTransport(url="http://localhost:8000/mcp")
client = Client(transport,
    elicitation_handler=elicit_handler,
    sampling_handler=sampling_handler,
    progress_handler=progress_handler)

部署到 AgentCore

bash 复制代码
pip install bedrock-agentcore-starter-toolkit
agentcore configure -e travel_server.py -p MCP -n travel_agent_demo
agentcore deploy

每个 session 跑在独立 microVM 里,通过 Mcp-Session-Id 维持上下文。

踩坑

  1. stateless_http 默认是 True:不改的话 elicit 直接报错,错误信息还很含糊
  2. Session 会超时:过期后客户端收到 404,要重新 initialize
  3. Sampling handler 不能返回空文本:server 端拼字符串会炸

适用场景

  • 多步骤表单 / 配置向导
  • 审批流程(执行到一半等人确认)
  • 交互式调试
  • 个性化推荐(收集偏好 → LLM 推荐 → 确认下单)

14 个区域可用,亚太有孟买、首尔、新加坡、悉尼、东京。

如果你在搞 AI agent 开发,这个功能值得试试。

相关推荐
威联通网络存储3 天前
基于TS-h3087XU-RP的大型成套空分设备DCS历史趋势数据治理
aws
A小辣椒18 天前
AWS Clould Support Engineer就职面试题
aws
亚林瓜子21 天前
AWS WAF中如何放行某个触发了托管规则的接口
aws·waf
悠悠1213823 天前
AWS DevOps Agent 体验一周后,我决定把 oncall 手机调成静音了
云计算·aws·devops
yyuuuzz23 天前
独立站运营的几个技术层面常见问题
大数据·运维·服务器·网络·数据库·aws
yyuuuzz23 天前
游戏云服务器推荐的技术选择思路
大数据·运维·服务器·游戏·云计算·aws
kernelcraft24 天前
Boto3:Python 操作 AWS 的官方 SDK
开发语言·python·其他·aws
普通网友1 个月前
Serverless 框架:多云函数部署(AWS + 阿里云 + 腾讯云)
阿里云·serverless·aws
TG_yunshuguoji1 个月前
亚马逊云代理商:如何用 CloudWatch+Lambda 打造自动化告警系统
大数据·运维·自动化·云计算·aws
yyuuuzz1 个月前
独立站搭建的几个核心技术问题
运维·服务器·网络·数据库·aws