使用 LlamaIndex 将 Agent 部署到 Amazon Bedrock AgentCore Runtime 并接入沙箱浏览器、代码解释器与持久化记忆
【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index
导读
本文围绕 LlamaIndex 官方集成的llama-index-tools-aws-bedrock-agentcore与llama-index-memory-bedrock-agentcore两个包展开,讲解如何把基于FunctionAgent构建的 LlamaIndex Agent 以一行代码部署到 Amazon Bedrock AgentCore Runtime 托管平台,并为其接入安全沙箱中的浏览器自动化(导航、点击、提取内容)、代码解释器(执行 Python、Shell 命令、文件管理、最长 8 小时会话)以及按用户隔离的持久化记忆(短期聊天事件 + 长期语义记忆)。读完本文,你将掌握 Runtime 的部署方式与 SSE 事件协议、三大 ToolSpec 的完整工具清单与生命周期管理方法,以及 Memory 组件在多租户场景下的配置要点,并能在本地直接复现可运行示例。
概览:AgentCore 为 LlamaIndex Agent 提供什么
Amazon Bedrock AgentCore 是 AWS 提供的托管 Agent 运行时基础设施,负责生产级 AI Agent 的部署与运行。LlamaIndex 的集成在四个方面与之对接:
- Runtime:
AgentCoreRuntime适配器包装bedrock-agentcoreSDK 中的BedrockAgentCoreApp,自动提供 AgentCore 要求的POST /invocations与GET /ping端点,并内置 SSE 流式响应支持,使任何 LlamaIndex Agent 都能被部署到 AgentCore Runtime。 - Browser Tools:
AgentCoreBrowserToolSpec让 Agent 在 AWS 安全沙箱浏览器中导航网页、点击元素、提取文本与超链接。 - Code Interpreter Tools:
AgentCoreCodeInterpreterToolSpec让 Agent 在沙箱中执行代码、运行命令、管理文件、安装包,支持最长 8 小时的会话。 - Memory:
AgentCoreMemory提供由 Bedrock AgentCore 支撑的持久化托管记忆,支持基于事件的短期聊天历史与基于语义检索的长期记忆,并通过actor_id实现按用户隔离,适配多租户应用。
安装与前置条件
安装两个集成包:
pip install llama-index-tools-aws-bedrock-agentcore pip install llama-index-memory-bedrock-agentcore前置条件:
- AWS 凭据已配置:可通过环境变量、AWS CLI profile 或 IAM 角色三种方式之一提供;
- IAM 权限:需要
bedrock-agentcore:*相关操作的权限(详见 AgentCore 官方文档); - Python 3.9+;
- 使用 Memory 前,需要先在 AgentCore 控制台或通过 AWS SDK 创建 memory 资源,以获得
memory_id。
从源码结构看,两个包分别位于本仓库的 tools 集成目录 与 memory 集成目录,入口导出见 工具包__init__.py,它对外公开了AgentCoreBrowserToolSpec、AgentCoreCodeInterpreterToolSpec与AgentCoreRuntime三个核心类。
Runtime:把 Agent 部署到 AgentCore 托管平台
一行代码启动
AgentCoreRuntime负责把任意 LlamaIndex Agent 适配为 AgentCore Runtime 应用。最简单的用法如下,它会直接启动 uvicorn 服务器并监听8080端口:
from llama_index.llms.bedrock_converse import BedrockConverse from llama_index.core.agent.workflow import FunctionAgent from llama_index.tools.aws_bedrock_agentcore import ( AgentCoreBrowserToolSpec, AgentCoreRuntime, ) tool_spec = AgentCoreBrowserToolSpec(region="us-west-2") tools = tool_spec.to_tool_list() llm = BedrockConverse( model="us.anthropic.claude-sonnet-4-6-v1", region_name="us-west-2", ) agent = FunctionAgent(tools=tools, llm=llm) # One-liner -- starts uvicorn on port 8080 AgentCoreRuntime.serve(agent)serve是类方法,其实现就是"创建 runtime 实例并调用run()":先runtime = cls(agent=agent, **kwargs),再runtime.run()。run()内部调用self._app.run(port=self._port, host=self._host, **kwargs)启动 uvicorn(对应源码 runtime/base.py)。
更精细的配置
如果需要更多控制,可以显式构造AgentCoreRuntime实例并手动调用run():
runtime = AgentCoreRuntime( agent=agent, stream=True, # SSE streaming (default) port=8080, # Required port for AgentCore deployment debug=False, # Enable debug logging memory=memory, # Optional AgentCoreMemory instance ) runtime.run()各参数说明(依据 Runtime 构造实现):
| 参数 | 默认值 | 说明 |
|---|---|---|
agent | 必填 | 要部署的 LlamaIndex Agent(如FunctionAgent) |
stream | True | 是否启用 SSE 流式响应;False时走非流式 JSON 响应路径 |
port | 8080 | uvicorn 监听端口,AgentCore 部署要求使用 8080 |
host | None | 监听主机,默认交给 uvicorn 处理 |
debug | False | 是否开启调试日志 |
memory | None | 可选的AgentCoreMemory实例,用于跨请求持久化 |
lifespan/middleware | None | 透传给BedrockAgentCoreApp的 Starlette lifespan 与中间件 |
请求负载与 Session ID 传播
Runtime 在收到POST /invocations请求后,会从 payload 中提取用户输入。_extract_prompt的实现(runtime/base.py#L85-L99)支持三种字段名:prompt、message、input,取值可以是字符串,也可以是包含prompt键的字典;若均缺失或不是字符串,则抛出 400 错误。也就是说,调用方只需保证请求体中包含prompt/message/input三者之一的字符串即可。
当请求携带X-Amzn-Bedrock-AgentCore-Runtime-Session-Id头时,该 Session ID 会自动传播给AgentCoreMemory:_get_memory会基于当前 memory 做浅拷贝,并把context.session_id替换为请求头中的值,从而保证同一会话的对话历史被正确归位(runtime/base.py#L101-L111)。
SSE 流式事件协议
开启stream=True时,Runtime 遍历agent.run(...)的stream_events(),把 LlamaIndex 的 Workflow 事件转换为 SSE 事件下发(实现见 runtime/base.py#L123-L172)。事件类型如下:
| Event | Fields | Description |
|---|---|---|
agent_stream | delta,response,thinking_delta? | Token-by-token LLM output |
tool_call | tool_name,tool_kwargs | Before tool execution |
tool_result | tool_name,tool_output | After tool execution |
done | response | Final agent response |
error | message | Error during streaming |
其中thinking_delta仅在模型返回思考增量时附带;AgentStream、ToolCall、ToolCallResult、AgentOutput这些事件类型来自llama_index.core.agent.workflow.workflow_events。流结束前 Runtime 还会await handler一次,以确保后台任务(如 memory 写入)完成。非流式模式下则直接返回{"response": str(result)}的 JSON。
Browser Tools:沙箱浏览器自动化
AgentCoreBrowserToolSpec让 Agent 能够在 AWS 托管的沙箱浏览器中完成网页交互。构造时region缺省时从环境变量获取(get_aws_region),identifier用于指定 VPC 场景下的自定义浏览器资源标识,默认标识为aws.browser.v1(源码常量见 browser/base.py)。
可用工具(10 个):navigate_browser、click_element、extract_text、extract_hyperlinks、get_elements、navigate_back、current_webpage、generate_live_view_url、take_control、release_control
生命周期方法(程序化调用):list_browsers、create_browser、delete_browser、get_browser
浏览器工具支持多线程会话隔离:每个工具都接受thread_id参数(默认"default"),ToolSpec 内部为每个线程维护独立的浏览器会话(_browser_clients字典),并发场景下互不干扰。navigate_browser会先校验 URL scheme 必须是http或https才执行跳转。generate_live_view_url用于生成可供人类实时观察浏览器会话的预签名 URL(默认 300 秒过期,便于人工监督),take_control/release_control则分别用于禁用/恢复自动化流,让人可以临时接管浏览器。
import asyncio from llama_index.llms.bedrock_converse import BedrockConverse from llama_index.tools.aws_bedrock_agentcore import AgentCoreBrowserToolSpec from llama_index.core.agent.workflow import FunctionAgent async def main(): tool_spec = AgentCoreBrowserToolSpec(region="us-west-2") tools = tool_spec.to_tool_list() llm = BedrockConverse( model="us.anthropic.claude-sonnet-4-6-v1", region_name="us-west-2", ) agent = FunctionAgent(tools=tools, llm=llm) response = await agent.run( "Go to https://news.ycombinator.com/ and tell me the titles of the top 5 posts." ) print(str(response)) await tool_spec.cleanup() asyncio.run(main())注意示例结尾调用了tool_spec.cleanup(),它会停止并清理全部浏览器会话(也可传thread_id只清理指定线程),避免残留远程会话。
VPC 场景下传入自定义identifier:
tool_spec = AgentCoreBrowserToolSpec( region="us-west-2", identifier="my-custom-browser-id", )此外,生命周期方法支持创建自定义浏览器(create_browser),可指定name、execution_role_arn、network_mode("PUBLIC"或"VPC"),VPC 模式下还可传入subnet_ids与security_group_ids(见 browser/base.py#L859-L907)。
Code Interpreter Tools:沙箱代码执行
AgentCoreCodeInterpreterToolSpec让 Agent 在远程沙箱中执行 Python 代码、运行 Shell 命令并管理文件,支持最长 8 小时的会话。默认资源标识为aws.codeinterpreter.v1,默认超时为 900 秒(源码常量见 code_interpreter/base.py)。
可用工具(15 个):execute_code、execute_command、read_files、list_files、delete_files、write_files、start_command、get_task、stop_task、upload_file、upload_files、install_packages、download_file、download_files、clear_context
生命周期方法(程序化调用):list_code_interpreters、create_code_interpreter、delete_code_interpreter、get_code_interpreter
代码解释器同样是惰性初始化 + 按线程隔离:第一次调用工具时才创建会话,之后同一thread_id复用同一沙箱。execute_code支持language参数(默认python)与clear_context参数;start_command/get_task/stop_task组合用于异步启动并跟踪长时间运行的命令;install_packages支持带版本说明符的包名(如'pandas>=2.0');下载文件时二进制内容会以 base64 编码返回。clear_context会重置 Python 执行上下文,清空所有变量、导入与函数定义。
import asyncio from llama_index.llms.bedrock_converse import BedrockConverse from llama_index.tools.aws_bedrock_agentcore import ( AgentCoreCodeInterpreterToolSpec, ) from llama_index.core.agent.workflow import FunctionAgent async def main(): tool_spec = AgentCoreCodeInterpreterToolSpec(region="us-west-2") tools = tool_spec.to_tool_list() llm = BedrockConverse( model="us.anthropic.claude-sonnet-4-6-v1", region_name="us-west-2", ) agent = FunctionAgent(tools=tools, llm=llm) response = await agent.run( "Write a Python function that calculates the factorial of a number and test it." ) print(str(response)) await tool_spec.cleanup() asyncio.run(main())同样支持 VPC 场景的自定义identifier:
tool_spec = AgentCoreCodeInterpreterToolSpec( region="us-west-2", identifier="my-custom-interpreter-id", )从 code_interpreter/base.py 的extract_output_from_stream可以看出,工具结果会从响应流中提取text类型内容,并把resource类型(如file://URI 指向的文件内容)一并格式化返回给 Agent,确保模型能直接读到生成文件的全文。
Memory:持久化托管记忆
AgentCoreMemory提供由 Bedrock AgentCore 支撑的持久化记忆,包含两条路径:
- 短期记忆:通过 events 保存聊天历史(
create_event/list_events); - 长期记忆:通过
list_memory_records/retrieve_memories对 memory records 做语义检索(基于searchQuery的语义搜索),并在注入 prompt 时使用。
记忆通过actor_id按用户隔离,天然适配多租户应用。
注意:必须先创建 memory 资源(AgentCore 控制台或 AWS SDK)获得
memory_id才能使用本组件。
import asyncio from llama_index.llms.bedrock_converse import BedrockConverse from llama_index.core.agent.workflow import FunctionAgent from llama_index.memory.bedrock_agentcore import ( AgentCoreMemory, AgentCoreMemoryContext, ) async def main(): memory = AgentCoreMemory( context=AgentCoreMemoryContext( memory_id="your-memory-id", # from AgentCore console or API actor_id="user-123", session_id="session-456", namespace="/", ), region_name="us-west-2", ) llm = BedrockConverse( model="us.anthropic.claude-sonnet-4-6-v1", region_name="us-west-2", ) agent = FunctionAgent(llm=llm, tools=[]) # Memory persists across agent runs response = await agent.run("My name is Alice.", memory=memory) print(str(response)) response = await agent.run("What is my name?", memory=memory) print(str(response)) asyncio.run(main())AgentCoreMemoryContext 字段
AgentCoreMemoryContext定义于 memory/base.py,字段如下:
| 字段 | 是否必填 | 说明 |
|---|---|---|
actor_id | 必填 | 用户标识,用于按用户隔离记忆 |
memory_id | 必填 | AgentCore 中创建的 memory 资源 ID |
session_id | 必填 | 会话标识,Runtime 部署时会用请求头X-Amzn-Bedrock-AgentCore-Runtime-Session-Id覆盖 |
namespace | 默认"/" | memory records 的命名空间 |
memory_strategy_id | 可选 | 长期记忆策略 ID,配置后检索长期记忆时使用 |
AgentCoreMemory 的检索与注入机制
从 aget 实现 可以看到完整流程:先读取该会话的 events 作为聊天历史,把历史拼接为检索查询(截断前 10000 字符),调用retrieve_memories拿到长期记忆记录,再通过insert_method决定注入方式:
InsertMethod.SYSTEM(默认):把记忆包装成 system message 注入,格式为 "Below are a set of relevant preferences retrieved from potentially several memory sources: ... This is the end of the retrieved preferences."(见 utils.py);InsertMethod.USER:把记忆合并进最新的 user message(源码中有 TODO 注释,当前默认走 SYSTEM 注入)。
底层通过 boto3 创建bedrock-agentcoreclient,并在Config中设置了标准重试模式(默认max_attempts=10)、连接/读取超时(默认 60 秒)以及x-client-framework:llama_index的用户代理标识(见 memory/base.py#L528-L585)。记忆写入事件时,消息角色会被映射为 AgentCore 的USER/ASSISTANT/TOOL/OTHER(OTHER对应 system 消息),工具调用的 kwargs 以blob形式与conversational文本成对存储;由于 AgentCore 不接受空文本 payload,空的 assistant 文本会用PLACEHOLDER FOR EMPTY ASSISTANT占位并在读取时还原为空(utils.py#L46-L77)。
另外,BaseAgentCoreMemory还提供list_sessions、delete_events、delete_memory_records、batch_delete_memory_records(默认批量 25 条)、delete_all_memory_for_session等数据管理方法,方便按会话清理历史。同步方法(get/put/put_messages等)内部通过asyncio_run包装异步实现,便于在同步代码中使用。
示例 Notebook
本仓库提供了两个可直接运行的 Jupyter Notebook 示例:
- Browser Tool Notebook
- Code Interpreter Tool Notebook
对应测试用例也覆盖了浏览器、代码解释器与 Runtime 的同步/异步/端到端路径,例如 test_browser.py、test_code_interpreter.py、test_runtime.py 以及 test_agentcore_memory.py,可作为理解各组件行为与边界的参考。
部署注意事项小结
- 端口:AgentCore 部署要求 Runtime 监听 8080 端口,
AgentCoreRuntime.serve(agent)默认即满足。 - Region 一致性:ToolSpec、LLM 与 Memory 的
region_name/region应保持一致(示例统一使用us-west-2)。 - 凭证与权限:确保运行环境已配置 AWS 凭据,且 IAM 策略覆盖
bedrock-agentcore:*相关操作。 - 资源清理:浏览器与代码解释器会话是远程托管的,示例中通过
tool_spec.cleanup()显式释放;Memory 资源建议按业务需要调用delete_all_memory_for_session等管理方法清理。 - 会话隔离:多线程/多用户场景下,浏览器与代码解释器工具都通过
thread_id隔离会话;Memory 通过actor_id+session_id隔离数据,Runtime 部署时会自动把请求头的 Session ID 注入 memory。
【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考