跳到主要内容

从零创建 Agent

本教程是一个端到端的实践指南,将引导您手动创建并部署一个完整的 Agent 应用。

完成该实践后,您将获得一个拥有 主动搜索能力 的 Agent,能够根据实际情况在 浏览器沙箱中 使用 js 脚本预处理内容 降低 token 消耗。 稍加改造便可成为您的 “舆情分析专家”、“新知识学习小帮手”。

准备工作

开发环境准备

为了存放您的代码,首选需要创建一个文件夹,如 my-agentrun。然后进入项目文件夹(当前,应该是一个空白文件夹)

首先,您需要根据不同的语言选择对应的框架,目前 AgentRun 提供了如下 SDK

我们建议您使用 uv 进行项目管理(使用 uv 需要先安装 Python),参考如下命令进行 uv 的安装与升级

curl -LsSf https://astral.sh/uv/install.sh | sh

由于 AgentRun 需要确保您的 Python 版本在 3.10 及以上,我们可以通过 uv 配置 3.10 的虚拟环境

uv venv -p 3.10

完成后,执行如下命令检查您的 Python 版本

uv run python --version

依赖安装

为了后续的代码可以正确执行,我们需要进行依赖安装

在项目目录创建如下文件

requirements.txt
agentrun-sdk[server,langchain]==0.0.9
备注

由于是基于 langchain 完成代码开发,并且会使用 AgentRun Server 启动 http server,因此增加了可选依赖的安装

AgentRun SDK 采用模块化设计,将不同的功能特性作为可选依赖项提供。这样可以避免安装不必要的依赖包,减小环境体积。根据您的实际需求,可以选择安装以下可选依赖:

  • server: 依赖用于启用 HTTP 服务器功能。如果您需要使用 AgentRunServer 将 Agent 封装为 HTTP API,需要安装此依赖。该依赖包含 FastAPI 和 Uvicorn 等 Web 框架组件。
  • playwright: 依赖用于支持浏览器沙箱功能。当您需要让 Agent 进行网页自动化操作时,需要安装此依赖。安装后还需要运行 Playwright 的初始化命令来下载浏览器驱动。
  • mcp: 依赖用于支持 MCP(Model Context Protocol)工具集。如果您的 Agent 需要调用基于 MCP 协议的工具服务,需要安装此依赖。
  • 框架集成依赖: 包括 langchainagentscopegoogle-adkcrewaipydantic-ai 等。这些依赖分别对应不同的 AI 开发框架。如果您使用某个框架进行 Agent 开发,需要安装对应的集成依赖。

安装可选依赖时,在包名后用方括号指定依赖项名称,多个依赖项之间用逗号分隔。例如,如果您需要使用 AgentScope 框架,同时需要浏览器沙箱和 MCP 工具支持,可以执行:

pip install agentrun-sdk[playwright,mcp,agentscope]

对于使用 LangChain 框架并需要 HTTP 服务器功能的场景:

pip install agentrun-sdk[server,langchain]

如果您不确定需要哪些依赖,可以先安装基础版本,在遇到功能缺失时再按需补充安装。

注意

目前 AgentRun 还在开发初期,我们会尽量避免不兼容的变更,但为了确保业务稳定性,建议您锁住使用的依赖版本,避免出现非预期的问题。

接下来,使用如下命令执行安装任务

uv pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/
备注

这里我们使用 -i http://mirrors.aliyun.com/pypi/simple/ 参数,通过阿里云 PyPI 镜像加速依赖的安装速度

云上资源准备

AgentRun 提供的是 AI Infra 能力,因此您需要提前创建好需要使用的资源。

友情提示

相关的资源均可通过 AgentRun SDK 创建,但创建资源非当前实践的重点,因此这里通过控制台创建

模型创建

要创建模型服务,需要进入 AgentRun 控制台 - 模型管理

点击创建模型

AgentRun 支持注册第三方的模型,也可以直接在函数计算 FunModel 部署开源/私有大模型 对于注册的第三方模型,需要选择模型的来源(用来确认请求的交互协议以及 BaseURL) 一个模型服务可以配置多个模型,如果通过 SDK 调用且未明确指定模型名时,会使用列表的第一个模型

填写模型信息

创建完成后,您应该可以在模型列表看到您创建的模型

创建结果

Sandbox 创建

要创建 Sandbox,需要进入 AgentRun 控制台 - 运行时与沙箱 - Sandbox 沙箱

点击创建 Sandbox

AgentRun 提供了多种 Sandbox,这里以浏览器沙箱为例

选择 Sandbox 类型

如果仅作测试,除去沙箱名称外的其他信息均不需要修改;当您要将沙箱正式对外使用时,除去配置计算资源规格等参数外,建议您正确配置 “入站:访问凭证配置” 避免被第三方请求您的资源造成非预期的费用

填写沙箱信息

创建完成后,您应该可以在模型列表看到您创建的沙箱

创建结果

配置环境变量

为了使用上一步创建的 AgentRun 资源,我们需要通过环境变量的形式注入这些信息给您的代码,为了方便调试,这里使用 .env 的形式注入。 您也可以参考 全局参数 通过其他方式进行配置

.env
################
# 密钥部分 #
################

AGENTRUN_ACCESS_KEY_ID="LT*************"
AGENTRUN_ACCESS_KEY_SECRET="DU*************"
AGENTRUN_ACCOUNT_ID=143*********149


################
# 业务资源描述 #
################

# 您在云上的模型资源
MODEL_SERVICE=my-agentrun-model
MODEL_NAME=qwen3-max

# 您在云上的 Sandbox 资源
SANDBOX_NAME=my-agentrun-browser

# 开启 DEBUG 日志
AGENTRUN_SDK_DEBUG=1

为了避免将上述包含敏感信息的文件传入 git 仓库导致安全问题,您可以增加 .gitignore 文件忽略 .env 文件

.gitignore
.env
.venv

撰写代码

接下来,您需要编辑您的代码文件。为了简化操作并且尽可能体验更多 AgentRun 的能力,我们选择的场景是 “支持网络搜索的 Agent”。

我们没有直接通过 “百度搜索工具” 等方式进行网络搜索,而是让大模型自己开启一个浏览器(借助 AgentRun 浏览器沙箱能力),大模型需要自己判断如何在页面中提取关键信息,并适当的页面访问操作。

注意

操作浏览器对大模型的能力存在较高要求,强烈建议您使用 qwen3-max 大模型

main.py
from agentrun import AgentRequest
from agentrun.integration.langchain import (
model,
sandbox_toolset,
AgentRunConverter,
)
from agentrun.server import AgentRunServer
from agentrun.sandbox import TemplateType
from langchain.agents import create_agent

import os

MODEL_SERVICE = os.getenv("MODEL_SERVICE", "")
MODEL_NAME = os.getenv("MODEL_NAME", "qwen3-max")

SANDBOX_NAME = os.getenv("SANDBOX_NAME", "")

agent = create_agent(
# 只需要一行代码,即可在您喜爱的框架中使用 AgentRun 注册的模型
model=model(MODEL_SERVICE, model=MODEL_NAME),
system_prompt="""
你是 AgentRun 的 AI 助手,可以通过网络搜索帮助用户解决问题


你的工作流程如下
- 当用户向你提问概念性问题时,不要直接回答,而是先进行网络搜索
- 使用 Browser 工具打开百度搜索。如果要搜索 AgentRun,对应的搜索链接为: `https://www.baidu.com/s?ie=utf-8&wd=agentrun`。为了节省 token 使用,不要使用 `snapshot` 获取完整页面内容,而是通过 `evaluate` 获取你需要的部分
- 获取百度搜索的结果,根据相关性分别打开子页面获取内容
- 如果子页面的相关度较低,则可以直接忽略
- 如果子页面的相关度较高,则将其记录为可参考的资料,记录页面标题和实时的 url
- 当你获得至少 3 条网络信息后,可以结束搜索,并根据搜索到的结果回答用户的问题。
- 如果某一部分回答引用了网络的信息,需要进行标注,并在回答的最后给出跳转链接
""",
# 只需要一行代码,即可在您喜爱的框架中使用 AgentRun 的 Sandbox 及其他工具
tools=[*sandbox_toolset(SANDBOX_NAME, template_type=TemplateType.BROWSER)],
)

async def invoke_agent(req: AgentRequest):
try:
converter = AgentRunConverter()

result = agent.astream_events(
{
"messages": [
{"role": msg.role, "content": msg.content} for msg in req.messages
]
},
config={"recursion_limit": 1000},
)
async for event in result:
for agentrun_event in converter.convert(event):
yield agentrun_event
except Exception as e:
print(e)
raise Exception("Internal Error")

# 只需要一行代码,即可将开放 OpenAI Chat Completions / AG-UI 协议的 HTTP 服务,快速与其他项目集成
AgentRunServer(invoke_agent=invoke_agent).start()

写入上述文件后,您的目录应该为如下形式

my-agentrun-python
┣ .env # 配置的环境变量
┣ .gitignore # 配置需要忽略的文件
┣ .venv # uv 的依赖目录
┣ main.py # 您的代码文件
┗ requirements.txt # 需要的依赖列表

本地执行测试

启动项目后,您可以使用 AG-UI 协议进行调用(使用 AG-UI 可以详细看到工具调用的过程,更加友好)

调用示例

参考如下调用示例,可以看到大模型在网络上搜索,并通过自己的能力删减 tool call 返回值避免 token 爆炸,并最终给出总结

curl 127.0.0.1:9000/ag-ui/agent -H "content-type: application/json" -d '{"messages":[{"role":"user", "content": "什么是 a2a"}]}'

data: {"type":"RUN_STARTED","threadId":"3fcd6aed-bbbb-4cbd-b14c-f43a25f02e27","runId":"9cc1bf23-8289-4df6-a257-dd271b4772de"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_eed285ab6bd64aea980c6a21","toolCallName":"health"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_eed285ab6bd64aea980c6a21","delta":""}

data: {"type":"TOOL_CALL_END","toolCallId":"call_eed285ab6bd64aea980c6a21"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_eed285ab6bd64aea980c6a21","toolCallId":"call_eed285ab6bd64aea980c6a21","content":"{\"status\": \"ok\", \"services\": {\"cdp_websocket\": {\"status\": \"ok\", \"message\": \"CDP WebSocket service ready, 0 active connections\"}, \"vnc_websocket\": {\"status\": \"ok\", \"message\": \"VNC server accessible\"}}}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_51e1dc38f8544d0c83b6c803","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_51e1dc38f8544d0c83b6c803","delta":"{\"url\": \"https://www.baidu.com/s?ie=utf-8&wd=a2a\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_51e1dc38f8544d0c83b6c803"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_51e1dc38f8544d0c83b6c803","toolCallId":"call_51e1dc38f8544d0c83b6c803","content":"{\"url\": \"https://www.baidu.com/s?ie=utf-8&wd=a2a\", \"success\": true, \"status\": 200}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_aea14c318731430485a10e82","toolCallName":"evaluate"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_aea14c318731430485a10e82","delta":"{\"expression\": \"Array.from(document.querySelectorAll('.c-container')).slice(0, 5).map(item => { const titleEl = item.querySelector('h3') || item.querySelector('.content-title'); const linkEl = item.querySelector('a'); return { title: titleEl?.innerText.trim() || '', url: linkEl?.href || '' }; }).filter(item => item.title && item.url)\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_aea14c318731430485a10e82"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_aea14c318731430485a10e82","toolCallId":"call_aea14c318731430485a10e82","content":"{\"result\": [{\"title\": \"a2a\\n\\n - 百度图片\", \"url\": \"https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=utf8&sa=vs_ala_img&fr=ala&ala=1&alatpl=normal&pos=3&dyTabStr=MCwzLDEsMiwxMyw3LDYsNSwxMiw5&word=a2a&lid=a70b2bb30048809a&topic=a2a\"}, {\"title\": \"A2A超话—新浪微博超话社区\", \"url\": \"http://www.baidu.com/link?url=KceEJNAvs0xT2nDqwfaJlTC2szI4FTGxuKRCjUERJyAcp-ccEUNOa6upVrtMx9vM6q571tysS-pLHn8XArHYtHgngUFGPf6JpusP54k_fv3\"}, {\"title\": \"A2A - 百度百科\", \"url\": \"http://www.baidu.com/link?url=2byj0MG4tI7XgwYRIrqxIZkMTFQZhYL6GrJtfyli-5tjVLL7qtZTziZMA_PBi7Vx2-hb28hNDv_1Qmpk2kDGJ_\"}, {\"title\": \"a2a - 视频大全 - 高清在线观看\", \"url\": \"https://www.baidu.com/sf/vsearch?pd=video&wd=a2a&tn=vsearch&lid=a70b2bb30048809a&ie=utf-8&rsv_pq=a70b2bb30048809a&rsv_spt=5&rsv_bp=1&f=8&atn=index\"}]}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_303cb2010c03435d8a2aca1a","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_303cb2010c03435d8a2aca1a","delta":"{\"url\": \"http://www.baidu.com/link?url=2byj0MG4tI7XgwYRIrqxIZkMTFQZhYL6GrJtfyli-5tjVLL7qtZTziZMA_PBi7Vx2-hb28hNDv_1Qmpk2kDGJ_\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_303cb2010c03435d8a2aca1a"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_303cb2010c03435d8a2aca1a","toolCallId":"call_303cb2010c03435d8a2aca1a","content":"{\"url\": \"http://www.baidu.com/link?url=2byj0MG4tI7XgwYRIrqxIZkMTFQZhYL6GrJtfyli-5tjVLL7qtZTziZMA_PBi7Vx2-hb28hNDv_1Qmpk2kDGJ_\", \"success\": true, \"status\": 200}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_683ef02efe1a439893210e6c","toolCallName":"evaluate"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_683ef02efe1a439893210e6c","delta":"{\"expression\": \"({ title: document.title, content: Array.from(document.querySelectorAll('meta[name=\\\"description\\\"], .lemma-summary, .content')).map(el => el.content || el.innerText).join(' ') })\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_683ef02efe1a439893210e6c"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_683ef02efe1a439893210e6c","toolCallId":"call_683ef02efe1a439893210e6c","content":"{\"result\": {\"title\": \"A2A_百度百科\", \"content\": \"A2A是区域对区域(area to area)的英文缩写,中文亦称“中心对中心”,指两个区域性社区(如小区、校园等)之间建立的联系与关系。该概念区别于B2B(企业对企业)、B2C(商家对客户)、C2C(个人对个人)等电子商务模式。A2A通常与A2B(区域对企业)、A2C(区域对个人)共同构成区域导向的商务分类体系。其应用场景聚焦于需实地体验的线下实体服务场所,例如酒吧、KTV、餐馆等业态,强调消费者必须到线下场所才能完成服务消费的特性。该术语的提出拓展了传统电子商务模式的分类维度,通过与O2O(线上对线下)模式的对比,突出了区域性单元在商务活动中的地理属性。\"}}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_0d17b293922a4b6e9c1e08f3","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_0d17b293922a4b6e9c1e08f3","delta":"{\"url\": \"https://www.baidu.com/s?ie=utf-8&wd=a2a%20人工智能\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_0d17b293922a4b6e9c1e08f3"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_0d17b293922a4b6e9c1e08f3","toolCallId":"call_0d17b293922a4b6e9c1e08f3","content":"{\"url\": \"https://www.baidu.com/s?ie=utf-8&wd=a2a%20人工智能\", \"success\": true, \"status\": 200}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_71cfe08ae62f44bba42db04b","toolCallName":"evaluate"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_71cfe08ae62f44bba42db04b","delta":"{\"expression\": \"Array.from(document.querySelectorAll('.c-container')).slice(0, 5).map(item => { const titleEl = item.querySelector('h3') || item.querySelector('.content-title'); const linkEl = item.querySelector('a'); return { title: titleEl?.innerText.trim() || '', url: linkEl?.href || '' }; }).filter(item => item.title && item.url)\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_71cfe08ae62f44bba42db04b"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_71cfe08ae62f44bba42db04b","toolCallId":"call_71cfe08ae62f44bba42db04b","content":"{\"result\": [{\"title\": \"MCP 与 A2A 协议比较:人工智能系统互联与协作的技术基础架构\", \"url\": \"http://www.baidu.com/link?url=cBDuVw8UrsyD2IhhRNX6TppDcPvP9P3SKoWXxcN9RoM3xcAPOyVzUxpQ4brCTCov\"}, {\"title\": \"A2A技术深度解析:让AI智能体像人类一样协作_a2as 框架-CSDN博客\", \"url\": \"http://www.baidu.com/link?url=jnVSHNqRN_dOSSCxnF90Of4S-xc9fiBEj0ETLhNTHNeB4NGw3q8mxf6kLGrYTaoNoWZSuO4A3EtVOVDVYYDfLPqHPMzW1TDb1t8LCmBd9PW\"}, {\"title\": \"A2A+MCP构建智能体协作生态:下一代分布式人工智能架构解析_a2a框架...\", \"url\": \"http://www.baidu.com/link?url=GR0rQp41J1dU5vOQmbao_l9SrDWNPAJRIApwA_YxiKjIVrlIbTUMV-B33FULtanQmuzzANw8A_8i4nebsJu1NCE9mexqg3v9JgSVuEwr1iW\"}]}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_673c4e12d07f47c88af9a94e","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_673c4e12d07f47c88af9a94e","delta":"{\"url\": \"http://www.baidu.com/link?url=cBDuVw8UrsyD2IhhRNX6TppDcPvP9P3SKoWXxcN9RoM3xcAPOyVzUxpQ4brCTCov\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_673c4e12d07f47c88af9a94e"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_673c4e12d07f47c88af9a94e","toolCallId":"call_673c4e12d07f47c88af9a94e","content":"{\"url\": \"http://www.baidu.com/link?url=cBDuVw8UrsyD2IhhRNX6TppDcPvP9P3SKoWXxcN9RoM3xcAPOyVzUxpQ4brCTCov\", \"success\": true, \"status\": 200}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_ab12e47e057b4ce3b2d2bc74","toolCallName":"evaluate"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_ab12e47e057b4ce3b2d2bc74","delta":"{\"expression\": \"({ title: document.title, content: Array.from(document.querySelectorAll('meta[name=\\\"description\\\"], p, .content')).map(el => el.content || el.innerText).join(' ').substring(0, 500) })\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_ab12e47e057b4ce3b2d2bc74"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_ab12e47e057b4ce3b2d2bc74","toolCallId":"call_ab12e47e057b4ce3b2d2bc74","content":"{\"result\": {\"title\": \"MCP 与 A2A 协议比较:人工智能系统互联与协作的技术基础架构 - 极术社区 - 连接开发者与智能计算生态\", \"content\": \"在人工智能领域的快速迭代发展中,两种协议已成为构建新一代 AI 系统的关键基础设施:模型上下文协议(Model Context Protocol,MCP)和代理对代理协议(Agent-to-Agent Protocol,A2A)。表面上这两种协议可能存在相似之处,但它们在设计目标和应用场景上有着明确区分,并正在根本性地重塑 AI 系统与环境及相互之间的交... 在人工智能领域的快速迭代发展中,两种协议已成为构建新一代 AI 系统的关键基础设施:模型上下文协议(Model Context Protocol,MCP)和代理对代理协议(Agent-to-Agent Protocol,A2A)。表面上这两种协议可能存在相似之处,但它们在设计目标和应用场景上有着明确区分,并正在根本性地重塑 AI 系统与环境及相互之间的交互方式。 模型上下文协议由 Anthropic 开发,其核心功能是作为 AI 模型与外部工具、数据源和系统间的标准化接口。MCP 可视为一种通用适配层,使 AI 应用能够连接到多种外部资源,无需针对每一种资源单独开发定制化集成方案。 从技术架构角度看,MCP 有效地将传统的\\\"M\"}}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_ea49e7ef7aec4390a47f3697","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_ea49e7ef7aec4390a47f3697","delta":"{\"url\": \"http://www.baidu.com/link?url=jnVSHNqRN_dOSSCxnF90Of4S-xc9fiBEj0ETLhNTHNeB4NGw3q8mxf6kLGrYTaoNoWZSuO4A3EtVOVDVYYDfLPqHPMzW1TDb1t8LCmBd9PW\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_ea49e7ef7aec4390a47f3697"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_ea49e7ef7aec4390a47f3697","toolCallId":"call_ea49e7ef7aec4390a47f3697","content":"{\"error\": \"Page.goto: Timeout 30000ms exceeded.\\nCall log:\\n - navigating to \\\"http://www.baidu.com/link?url=jnVSHNqRN_dOSSCxnF90Of4S-xc9fiBEj0ETLhNTHNeB4NGw3q8mxf6kLGrYTaoNoWZSuO4A3EtVOVDVYYDfLPqHPMzW1TDb1t8LCmBd9PW\\\", waiting until \\\"load\\\"\\n\"}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_0b3f2ad0f92f4adda22a28ba","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_0b3f2ad0f92f4adda22a28ba","delta":"{\"url\": \"https://www.baidu.com/s?ie=utf-8&wd=a2a%20Agent-to-Agent\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_0b3f2ad0f92f4adda22a28ba"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_0b3f2ad0f92f4adda22a28ba","toolCallId":"call_0b3f2ad0f92f4adda22a28ba","content":"{\"url\": \"https://www.baidu.com/s?ie=utf-8&wd=a2a%20Agent-to-Agent\", \"success\": true, \"status\": 200}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_799dba0d4fb84b9e8531a1e7","toolCallName":"evaluate"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_799dba0d4fb84b9e8531a1e7","delta":"{\"expression\": \"Array.from(document.querySelectorAll('.c-container')).slice(0, 5).map(item => { const titleEl = item.querySelector('h3') || item.querySelector('.content-title'); const linkEl = item.querySelector('a'); return { title: titleEl?.innerText.trim() || '', url: linkEl?.href || '' }; }).filter(item => item.title && item.url)\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_799dba0d4fb84b9e8531a1e7"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_799dba0d4fb84b9e8531a1e7","toolCallId":"call_799dba0d4fb84b9e8531a1e7","content":"{\"result\": [{\"title\": \"Agent-to-Agent(A2A)协议:基础教程 - 知乎\", \"url\": \"http://www.baidu.com/link?url=Hd7npHiqNL5qNdKtSxBmyW2g-SYhYFwhDQ1Y1Td0_6mvzMdWfQ8etM0Lq9q0KkHYSe63qJTOMcSfBEn5Rj9C_a\"}, {\"title\": \"Agent-to-Agent (A2A) 协议 | Technology Radar | Thoughtworks...\", \"url\": \"http://www.baidu.com/link?url=-VkpnaBwIG8JH5td8RfXC3KXNVqOm7A5O79AXyW_5ybyL5avYZNQLsIlxeVlI4AR4Kfh2yaz-Z4CRdDqhjSLhkzEtXqs1ei9ZnB2dGphotMfOxqMSZ_3np0HHJ_Hvdga\"}, {\"title\": \"多Agent协作入门:基于A2A协议的Agent通信(中) - ExplorerMan...\", \"url\": \"http://www.baidu.com/link?url=jLUnMCuC7_w5Zny-oOm9_lh5HOR8BaljRufeWOPhEFQGFrCDKpm3TjdxKTpDhSVTsbNS3giuZ0P9EVtSZGjumK\"}]}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_4c52fae9c82a4953a31e47ae","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_4c52fae9c82a4953a31e47ae","delta":"{\"url\": \"http://www.baidu.com/link?url=Hd7npHiqNL5qNdKtSxBmyW2g-SYhYFwhDQ1Y1Td0_6mvzMdWfQ8etM0Lq9q0KkHYSe63qJTOMcSfBEn5Rj9C_a\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_4c52fae9c82a4953a31e47ae"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_4c52fae9c82a4953a31e47ae","toolCallId":"call_4c52fae9c82a4953a31e47ae","content":"{\"url\": \"http://www.baidu.com/link?url=Hd7npHiqNL5qNdKtSxBmyW2g-SYhYFwhDQ1Y1Td0_6mvzMdWfQ8etM0Lq9q0KkHYSe63qJTOMcSfBEn5Rj9C_a\", \"success\": true, \"status\": 403}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_0a11b10f87eb4cf08d62c943","toolCallName":"goto"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_0a11b10f87eb4cf08d62c943","delta":"{\"url\": \"http://www.baidu.com/link?url=-VkpnaBwIG8JH5td8RfXC3KXNVqOm7A5O79AXyW_5ybyL5avYZNQLsIlxeVlI4AR4Kfh2yaz-Z4CRdDqhjSLhkzEtXqs1ei9ZnB2dGphotMfOxqMSZ_3np0HHJ_Hvdga\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_0a11b10f87eb4cf08d62c943"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_0a11b10f87eb4cf08d62c943","toolCallId":"call_0a11b10f87eb4cf08d62c943","content":"{\"url\": \"http://www.baidu.com/link?url=-VkpnaBwIG8JH5td8RfXC3KXNVqOm7A5O79AXyW_5ybyL5avYZNQLsIlxeVlI4AR4Kfh2yaz-Z4CRdDqhjSLhkzEtXqs1ei9ZnB2dGphotMfOxqMSZ_3np0HHJ_Hvdga\", \"success\": true, \"status\": 200}","role":"tool"}

data: {"type":"TOOL_CALL_START","toolCallId":"call_b9151c91db0642279b823553","toolCallName":"evaluate"}

data: {"type":"TOOL_CALL_ARGS","toolCallId":"call_b9151c91db0642279b823553","delta":"{\"expression\": \"({ title: document.title, content: Array.from(document.querySelectorAll('meta[name=\\\"description\\\"], p, .content')).map(el => el.content || el.innerText).join(' ').substring(0, 500) })\"}"}

data: {"type":"TOOL_CALL_END","toolCallId":"call_b9151c91db0642279b823553"}

data: {"type":"TOOL_CALL_RESULT","messageId":"tool-result-call_b9151c91db0642279b823553","toolCallId":"call_b9151c91db0642279b823553","content":"{\"result\": {\"title\": \"Agent-to-Agent (A2A) 协议 | Technology Radar | Thoughtworks China\", \"content\": \"Agent2Agent (A2A) 是一个协议,定义了复杂、多智能体工作流中智能体之间通信和交互的标准。它使用 Agent Cards 描述智能体间通信的关键元素,包括技能发现和传输及安全方案的规范。A2A 通过专注于智能体间通信,而不暴露内部细节(如智能体状态、记忆或内部),这成为了对 模型上下文协议 (MCP)的一个补充。\\n该协议提倡最佳实践,例如对长时间运行的任务采用异步优先方法,对增量更新采用流式响应,以及使用 HTTPS、身份验证和授权进行安全传输。为了方便快速采用,A2A 提供了 Python、JavaScript、Java 和 C# 的 SDK。尽管 A2A 相对较新,但它使团队能够构建特定领域的代理,这些代理可以协作形成复杂的工作流,使其成为此类场景的理想选择。 [...] 针对当今科技领域发展的前沿指南 服务数字读者的出版物 业务主管的A-Z技术指南 聚焦技术引领的商业变革 助力商业的专业洞见 关于战略、人工智能, 工程、技术生涯等方面的专家建议 浏览更多我们的书籍 分析商业和技术最新趋势的精彩对话 探索最新科技热点,深度分析技术与商业 面试准备 了解作为一名Tho\"}}","role":"tool"}

data: {"type":"TEXT_MESSAGE_START","messageId":"b28f14e6-d3e3-4175-b039-84d8186c129d","role":"assistant"}

data: {"type":"TEXT_MESSAGE_CONTENT","messageId":"b28f14e6-d3e3-4175-b039-84d8186c129d","delta":"A2A 有两种主要含义,具体取决于上下文:\n\n## 1. 区域对区域(Area to Area)\n在传统商务和电子商务领域,A2A 是 \"Area to Area\"(区域对区域)的缩写,也称为\"中心对中心\"。这个概念指的是:\n- 两个区域性社区(如小区、校园等)之间建立的联系与关系\n- 区别于传统的 B2B(企业对企业)、B2C(商家对客户)、C2C(个人对个人)等电子商务模式\n- 通常与 A2B(区域对企业)、A2C(区域对个人)共同构成区域导向的商务分类体系\n- 主要应用于需要实地体验的线下实体服务场所,如酒吧、KTV、餐馆等业态\n\n## 2. 智能体对智能体(Agent-to-Agent)\n在人工智能和新兴技术领域,A2A 指的是 \"Agent-to-Agent\"(智能体对智能体)协议:\n- 这是一个定义复杂、多智能体工作流中智能体之间通信和交互标准的协议\n- 使用 Agent Cards 描述智能体间通信的关键元素,包括技能发现、传输及安全方案规范\n- 专注于智能体间通信,而不暴露内部细节(如智能体状态、记忆或内部结构)\n- 提倡最佳实践,如对长时间运行任务采用异步优先方法,对增量更新采用流式响应\n- 提供 Python、JavaScript、Java 和 C# 的 SDK 以方便快速采用\n- 与模型上下文协议(MCP)形成互补关系\n\n这两种含义分别代表了不同领域的概念,需要根据具体语境来判断所指的内容。\n\n参考资料:\n- [A2A_百度百科](http://www.baidu.com/link?url=2byj0MG4tI7XgwYRIrqxIZkMTFQZhYL6GrJtfyli-5tjVLL7qtZTziZMA_PBi7Vx2-hb28hNDv_1Qmpk2kDGJ_)\n- [MCP 与 A2A 协议比较:人工智能系统互联与协作的技术基础架构](http://www.baidu.com/link?url=cBDuVw8UrsyD2IhhRNX6TppDcPvP9P3SKoWXxcN9RoM3xcAPOyVzUxpQ4brCTCov)\n- [Agent-to-Agent (A2A) 协议 | Technology Radar | Thoughtworks China](http://www.baidu.com/link?url=-VkpnaBwIG8JH5td8RfXC3KXNVqOm7A5O79AXyW_5ybyL5avYZNQLsIlxeVlI4AR4Kfh2yaz-Z4CRdDqhjSLhkzEtXqs1ei9ZnB2dGphotMfOxqMSZ_3np0HHJ_Hvdga)"}

data: {"type":"TEXT_MESSAGE_END","messageId":"b28f14e6-d3e3-4175-b039-84d8186c129d"}

data: {"type":"RUN_FINISHED","threadId":"3fcd6aed-bbbb-4cbd-b14c-f43a25f02e27","runId":"9cc1bf23-8289-4df6-a257-dd271b4772de"}

A2A 有两种主要含义,具体取决于上下文:

1. 区域对区域(Area to Area)

在传统商务和电子商务领域,A2A 是 "Area to Area"(区域对区域)的缩写,也称为"中心对中心"。这个概念指的是:

  • 两个区域性社区(如小区、校园等)之间建立的联系与关系
  • 区别于传统的 B2B(企业对企业)、B2C(商家对客户)、C2C(个人对个人)等电子商务模式
  • 通常与 A2B(区域对企业)、A2C(区域对个人)共同构成区域导向的商务分类体系
  • 主要应用于需要实地体验的线下实体服务场所,如酒吧、KTV、餐馆等业态

2. 智能体对智能体(Agent-to-Agent)

在人工智能和新兴技术领域,A2A 指的是 "Agent-to-Agent"(智能体对智能体)协议:

  • 这是一个定义复杂、多智能体工作流中智能体之间通信和交互标准的协议
  • 使用 Agent Cards 描述智能体间通信的关键元素,包括技能发现、传输及安全方案规范
  • 专注于智能体间通信,而不暴露内部细节(如智能体状态、记忆或内部结构)
  • 提倡最佳实践,如对长时间运行任务采用异步优先方法,对增量更新采用流式响应
  • 提供 Python、JavaScript、Java 和 C# 的 SDK 以方便快速采用
  • 与模型上下文协议(MCP)形成互补关系

这两种含义分别代表了不同领域的概念,需要根据具体语境来判断所指的内容。

参考资料:

注意

Sandbox 的生命周期与业务密切相关,因此我们未对 Sandbox 的生命周期进行管理。

默认情况下 Sandbox 会在 无操作 30 分钟创建 6 小时 后自动销毁。

如果您在本地测试代码,可能会初始化大量的 Sandbox 实例,这将会产生一定的费用,建议您增加 sandbox 的清理逻辑,或手动执行清理。

将 Agent 部署到云上 AgentRun

云上依赖安装

要将 Agent 部署到云上,首先需要解决的问题是依赖兼容问题。云上为 Linux x64 环境,而大部分用户的本地可能是 Windows x64 或 Mac arm64 环境,不同的环境所需要的依赖不完全一致。

为了解决依赖问题,我们有如下建议

  • 通过 s build 在本地下载 Linux x64 依赖(需要安装 Serverless Devs 和 docker)
  • 构建 Docker 镜像,使用自定义镜像部署

在这里,为了简化操作,我们使用 s build 完成任务,这需要您安装 Serverless Devs 和 Docker

安装 Serverless Devs

Serverless Devs 是一个开源开放的 Serverless 开发者平台,致力于为开发者提供强大的工具链体系。通过该平台,开发者不仅可以一键体验多云 Serverless 产品,极速部署 Serverless 项目,还可以在 Serverless 应用全生命周期进行项目的管理,并且非常简单快速的将 Serverless Devs 与其他工具/平台进行结合,进一步提升研发、运维效能。

通过 Serverless Devs,可以快速创建 AgentRun 应用模板、部署代码到 Agent Runtime。

如果您的本地环境已经安装了 NodeJS,可以通过 npm 快速完成安装:

npm install -g @serverless-devs/s

如果您不希望安装 NodeJS 环境,也可以直接下载 Serverless Devs 二进制程序使用。安装完成后,执行 s --version 验证安装是否成功。

Serverless Devs 安装完成后,您还需要配置阿里云密钥,授予 Serverless Devs 权限

# 按照引导输入 Access Key ID 和 Secret,记住密钥对名称(如 agentrun-deploy)
s config add

安装 Docker

依赖安装仅需要使用函数计算官方镜像执行依赖安装行为,因此您可以用任意兼容 docker 命令的容器环境作为替代

配置 s.yaml 并执行安装

执行本地依赖安装需要首先存在 requirements.txtpackages.json,这些文件在前面的步骤中应该已经存在

同时,您还需要写入一个 s.yaml 文件,作为 Serverless Devs 的配置文件

对于 s.yaml 中,存在 vars.role 字段,该字段需要填写您的 RAM 角色,用来获取执行期间的临时阿里云 ACCESS_KEY

快速创建 RAM 角色可以参考:

为了提升安全性,您不需要将阿里云密钥配置到环境变量中,取而代之的是通过角色进行授权。当您为 AgentRun/函数计算 配置了角色后,您的程序在启动时将会自动根据角色权限注入临时密钥到环境变量。及时由于意外问题导致密钥泄漏,该临时密钥也会在固定时间后自动过期,减少损失。

通常,在 AgentRun 场景下,您需要为角色配置如下权限

  • AliyunAgentRunFullAccess: 允许您的代码访问 AgentRuntime、Sandbox、Model、Credential 等能力
  • AliyunDevsFullAccess: 允许您的代码访问 ToolSet

如果您还需要访问其他云产品,则可以按需增加权限。对于特定业务场景,您也可以进行精确授权,如仅授予某个资源的读权限。更多信息可以参考 RAM角色概览

如果您需要快速创建一个拥有 AliyunAgentRunFullAccessAliyunDevsFullAccess 权限的角色,则可以点击 快速授权链接

s.yaml
edition: 3.0.0
name: my-agentrun
# 您需要根据实际情况修改这里的内容
access: 'default' # 修改为您的密钥对名称
vars:
region: 'cn-hangzhou' # 要部署的地域
agent_name: 'my-agentrun-python' # 您的 Agent 名称
role: 'acs:ram::${config("AccountID")}:role/AliyunAgentRunDefaultRole' # 您的 Agent 需要拥有的权限(会用于注入 ACCESS_KEY)
model_service: 'my-agentrun-model' # AgentRun 模型服务名称
model_name: 'qwen3-max' # 要使用的模型名称
sandbox_name: 'my-agentrun-browser' # 浏览器沙箱名称

resources:
agent:
component: agentrun
props:
region: ${vars.region}

agent:
# 基本信息
name: ${vars.agent_name}
description: '我的 AgentRun Agent'
role: ${vars.role}
code:
src: ./
language: python3.12
command:
- python3
- main.py

# 资源配置
cpu: 1.0
memory: 2048

# 端口和并发
port: 9000
instanceConcurrency: 200

# 网络配置 - 仅公网访问
internetAccess: true

# 环境变量
environmentVariables:
PYTHONPATH: /code/python:/opt/python:/code:/code/python

MODEL_SERVICE: '${vars.model_service}'
MODEL_NAME: '${vars.model_name}'
SANDBOX_NAME: '${vars.sandbox_name}'

# 日志配置
logConfig: auto

# 端点配置
endpoints:
- name: prod
version: LATEST
description: '生产环境端点'

此时,执行 s build 则会自动拉取函数计算使用的运行镜像,并在其中安装依赖,依赖会被安装到 python 目录(这也意味着,您的代码需要能够识别 python 目录的依赖,这已经通过 PYTHONPATH 配置)

更多 s build 的细节,可以参考 Serverless Devs Build 命令

部署到云上

部署前,我们还需要排除 .env 文件和不必要的文件,将代码包压缩至最小

.fcignore
.env
.venv

由于前面我们已经写好了 s.yaml 文件,因此您只需要执行部署命令,即可快速将 Agent 部署到 AgentRun 中

s deploy

检查部署的输出内容,可以看到部署结果中存在 url

endpoints:
-
id: 99015cc9-b0d6-454c-a71b-9500d1179d93
arn: acs:agentrun:cn-hangzhou:1431********149:runtime-endpoints/99015cc9-b0d6-454c-a71b-9500d1179d93
name: prod
url: https://1431********149.agentrun-data.cn-hangzhou.aliyuncs.com/agent-runtimes/m**********n/endpoints/prod/invocations
version: LATEST
status: CREATING
description: 生产环境端点

这个地址就是您的 Agent 访问地址,这次我们使用 OpenAI Chat Completions 协议快速执行一次会话

curl https://1431********149.agentrun-data.cn-hangzhou.aliyuncs.com/agent-runtimes/m**********n/endpoints/prod/invocations/openai/v1/chat/completions \
-H "content-type: application/json" \
-d '{"messages": [{"role":"user", "content":"你好,你是谁?"}]}'

如果一切正常,那么返回值应该类似

我是 AgentRun 的 AI 助手,可以通过网络搜索帮助您解决问题。如果您有任何问题需要查询,请告诉我!我是 AgentRun 的 AI 助手,可以通过网络搜索帮助您解决问题。如果您有任何问题需要查询,请告诉我!

🎉 恭喜

您已经在 AgentRun 成功执行了一次端到端的部署,接下来您可以继续改进代码,让 Agent 支持更丰富的功能。

  • 您可以使用 AG-UI 测试云上的浏览器能力
  • 您可以为您的 Agent 增加一个前端页面,让浏览器的执行过程实时渲染给用户
  • 您可以调整提示词,让 Agent 调查更有倾向性(如针对性在 知乎、小红书 进行检索)