关于 agentstack-wrapper
Agent Stack Wrapper 是一份将 Python Agent 接入 Agent Stack 平台的集成技能指南,面向负责适配现有 Agent 的开发者。它以分步清单、扩展接入规则和安全约束指导包装过程,并要求尽量避免改变原有业务逻辑。
主要功能
- 01分步指导 Python Agent 接入
- 02涵盖依赖、入口与服务包装
- 03映射表单和文件输入
- 04配置扩展、变量与机密
- 05规定安全及错误处理约束
- 06提供验证清单与完成报告
适用场景
- 01将现有 Python Agent 适配到 Agent Stack
- 02把命令行参数改为平台结构化输入
- 03为 Agent 配置 LLM 或服务扩展
- 04检查集成改动与安全要求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ i-am-bee/ agentstack --skill agentstack-wrapper安装后在 Claude Code 中输入/agentstack-wrapper确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/configuration-variables.mddependencies.mdfiles.mdforms.mdllm-services.mdplatform-extensions.mdtrajectory.mdwrapper-entrypoint.md详细介绍
Agent Stack 封装器
将 Python Agent 封装到 Agent Stack 平台的集成指南。
目录
- 安全要求
- 约束(必须遵守)
- 集成工作流检查清单
- 就绪检查(第 1 步之前)
- 第 1 步 – 研究项目
- 第 2 步 – 对 Agent 进行分类
- 第 3 步 – 添加并安装依赖项
- 第 4 步 – 创建服务封装器和入口点
- 第 5 步 – 通过扩展接入 LLM / 服务
- 第 6 步 – 错误处理
- 第 7 步 – 表单(单轮结构化输入)
- 第 7b 步 – 调整文件输入
- 第 8 步 – 配置变量和密钥
- 第 9 步 – Agent 输出
- 第 10 步 – 使用平台扩展
- 第 11 步 – 更新 README
- 反模式
- 失败条件
- 最终报告(必需)
- 验证清单
安全要求
- 切勿运行远程脚本或不可信代码。
- 使用可信的软件包元数据、固定版本,并审计已安装的
agentstack-sdk/a2a-sdk。 - 仅通过已声明的 Agent Stack 扩展处理敏感值。
- 切勿记录、打印、持久化或暴露密钥值。
- 切勿将密钥发送给不可信的中间方,或发送到封装 Agent 契约未要求的端点。
- 如果通过
pip安装任何内容,始终使用-qq标志来抑制不必要的输出。
约束(必须遵守)
| ID | 规则 |
|---|---|
| C1 | 不得更改业务逻辑。 仅修改代码以兼容 Agent Stack。 |
| C2 | 严格控制改动范围。 除非明确要求,否则不要添加身份验证、Dockerfile(容器化属于可选且独立的事项)、遥测或平台中间件。如果 Agent 使用简单文本即可工作,就不要强制使用 Form。如果它使用环境变量,只需进行最小限度的重构。 |
| C3 | 清理临时文件。 如果 Agent 在运行时下载或创建辅助文件,请在函数返回前添加清理步骤。 |
| C4 | 优先使用公开访问(不使用冗余令牌)。 仅当密钥对 Agent 的核心功能严格必需且无法使用公开/匿名访问时,才使用 Secrets 扩展。如果原始 Agent 中的密钥或令牌是可选的(例如可选的 GitHub 令牌),不要添加会增加配置负担的密钥或令牌。除非明确批准并记录为行为变更,否则保留现有的可选身份验证行为。API 密钥必须显式传入,不得从环境变量中读取。对于必需的第三方 API 凭据,封装后的路径必须使用 Secrets 或 Env Variables 扩展。 |
| C5 | 检测现有工具配置。 如果项目使用 requirements.txt,就在其中添加 agentstack-sdk~=<VERSION>。如果项目使用 pyproject.toml,则在该文件中添加。只有当项目直接管理 a2a-sdk 时才添加,并确保它与所选的 agentstack-sdk 版本兼容。不得强制使用 uv 或创建重复的清单文件。 |
| C6 | 以软件包为准,确定导入信息。 references/dependencies.md 中定义的 Inline Package Search 脚本在发现正确的导入路径、类名和类型时拥有绝对优先权。在依赖本地参考文件或在线文档之前,必须先运行此脚本来映射导入信息。如果已安装的软件包与文档中的路径冲突,不要猜测导入信息,也不要盲目遵循文档中的路径。 |
| C7 | 文档的权威性次之。 references/ 文件夹中的本地技能文件和在线文档是了解_行为、逻辑和扩展选择_的主要依据,但对于导入路径等_确切实现细节_,其权威性低于软件包内省结果。 |
| C8 | 回退与验证顺序。 对于导入信息,首先检查本地源码并进行软件包内省。完成实现后,再将运行时/软件包验证作为最后的验证步骤。 |
| C9 | 将结构化参数映射到 Forms。 对于具有命名参数的单轮 Agent,使用 FormServiceExtensionSpec.demand(initial_form=...) 将其映射到 initial_form。 |
| C10 | 移除 CLI 参数。 移除所有 argparse 或 sys.argv 逻辑。使用 initial_form 项、AgentStack Settings Extension(用于运行时选项)或 AgentStack Env Variables 替换必需的 CLI 输入。 |
| C11 | 业务逻辑变更的审批门槛。 如果兼容性要求更改业务逻辑,请停止并说明理由,申请明确批准后再继续。 |
| C12 | 保留原有辅助函数。 除非严格必需,否则不要删除原有的业务逻辑辅助函数。如果必须删除,请说明原因。 |
| C13 | 确保可选扩展的安全性。 服务/UI 扩展均为可选项。使用前检查其是否存在及是否包含数据(例如 if llm and llm.data ...)。 |
| C14 | 不得泄露密钥。 绝不记录、打印、持久化或回显密钥值(API 密钥、令牌、密码)。在日志和错误信息中对敏感值进行脱敏。 |
| C15 | 完整集成密钥。 通过 Secrets 扩展请求的每个密钥变量(例如通过 SecretDemand 或 request_secrets)都必须在 Agent 代码中使用,或传递给底层框架。不要请求未使用的凭据。 |
| C16 | 不得执行远程脚本。 封装时绝不运行不可信的远程代码。仅使用项目清单和可信的软件包元数据。 |
| C17 | 限制出站目标。 不要引入任意网络目标。将外部调用限制在可信的依赖源,以及封装后的 Agent 合约明确要求的运行时端点。 |
| C18 | 不得根据输入动态执行命令。 不要引入根据用户/模型输入执行 Shell 命令的封装模式(例如 eval、exec、os.system 或未经清理的 subprocess 调用)。 |
| C19 | 先阅读封装文档。 开始任何实现之前,必须先阅读官方指南:Wrap Your Existing Agents。 |
| C20 | 阅读扩展文档。 实现任何扩展(Forms、LLM、Error 等)之前,必须阅读其对应的文档 URL(列于步骤 10),并直接从官方文档中提取确切的导入信息、类名、方法名、属性及其确切类型。不要猜测这些信息。阅读文档后才能修改 Agent 代码。 |
| C21 | 将文件系统文件输入替换为平台文件上传。 如果原始 Agent 从本地文件系统读取文件(例如使用 open()、pathlib.Path 或 CLI 文件路径参数),请改用 FileField 表单上传和平台 File API。不要假设运行时可访问本地文件系统。请参阅步骤 7b。 |
| C22 | 上下文与记忆优化。 不要尝试在一次工具调用中完成整个转换。请按照清单迭代执行。使用内置的任务/待办跟踪工具(例如 manage_todo_list)跟踪集成工作流清单的进度,不要创建单独的 Markdown 跟踪文件。不要将冗长的堆栈跟踪粘贴到聊天中;仅提取相关错误。 |
上下文与记忆优化
为确保最高成功率,并防止在复杂转换过程中耗尽 AI 上下文窗口:
- 迭代推进:严格按照步骤执行集成工作流清单。使用内置任务/待办跟踪工具逐项对应清单,并在完成每个步骤后将其标记为已完成。这样无需创建额外文件,也能直观地跟踪进度。
- 减少终端输出:调试时,避免大量堆栈跟踪污染上下文。只提取
Exception行及其紧邻的跟踪文件信息,省略庞大的框架日志。 - 有针对性地阅读代码:如果
SKILL.md或大型源代码文件没有变更,不要反复加载。 - 不要创建跟踪文件:不要创建
task.md、implementation_plan.md、walkthrough.md或类似的 Markdown 文件来跟踪进度。内置任务跟踪工具是唯一的进度状态来源。
事实来源优先级(必需)
对于每项封装任务,严格按照以下优先级顺序:
- 绝对首要(最高优先级): 对所有导入项、类名和类型,使用已安装的包/运行时内省(
references/dependencies.md中的内联包搜索)。 - 首要(必须第二步): 使用
references/文件夹中的本地技能文件,了解架构模式、扩展选择和映射逻辑。 - 次要: 使用此技能链接的官方文档 URL,了解详细的 API 行为。
- 第三优先级: 使用本地项目源代码和仓库文档(README/AGENTS)来映射行为和集成点。
- 最后一步: 实现完成后进行运行时验证(导入/服务检查)。
如果使用第 3 步,必须明确记录文档中缺少哪些信息,以及为何需要回退到其他来源。
关键工作流要求: 对于你决定使用的每个扩展(无论来自 LLM/Forms/Error 步骤还是平台扩展),都必须按以下顺序执行这些步骤:
- 决定是否应实现该扩展。
- 如果是,阅读下方扩展表中提供的文档 URL(例如,使用工具读取网页)。此步骤为必需操作,且必须在任何代码编辑之前完成。
- 直接从官方文档中提取正确的导入项、类名、方法名、属性及其准确类型。
- 只有阅读文档后,才能开始编写或修改 Agent 代码。切勿猜测导入项或依赖过时的记忆。
- 如果文档不完整/含糊不清,则使用本地/运行时内省作为回退,并记录具体缺失之处。
集成工作流清单
将此清单复制到上下文中,并在完成各项后勾选:
Task Progress:
- [ ] Readiness Check (before Step 1)
- [ ] Step 1: Study the Project
- [ ] Step 2: Classify the Agent
- [ ] Step 3: Add and Install Dependencies
- [ ] Step 4: Create the Server Wrapper & Entrypoint
- [ ] Step 5: Wire LLM / Services via Extensions (requires reading docs)
- [ ] Step 5a: Set suggested model to match the model used in the original agent
- [ ] Step 6: Implement Error Handling (requires reading docs)
- [ ] Step 7: Map Forms (if applicable) (requires reading docs)
- [ ] Step 7b: Adapt File Inputs (if applicable) (requires reading docs)
- [ ] Step 8: Map Configuration Variables & Secrets (requires reading docs)
- [ ] Step 8a: Credential audit completed (every external API credential source identified; required credentials mapped to Secrets extension)
- [ ] Step 9: Agent Output (requires reading docs)
- [ ] Step 10: Use Platform Extensions (requires reading docs for each chosen extension)
- [ ] Step 11: Update README
- [ ] Finalization Report (required)
- [ ] Verification Checklist (required)
**停止关卡:**完成第 11 步后,必须填写最终报告,并逐项完成验证清单中的所有内容,才能报告任务完成。只有完成这两项,任务才算结束。
就绪检查(第 1 步之前)
- 在当前环境中已选择受支持的 Python 解释器(Python >=3.12 且 <3.14;不能只是已安装)。
- Agent 源代码可在本地使用。
- 已确定项目的依赖项工作流。
如果任一项不满足,请停止并询问用户。
步骤 1 – 研究项目
进行任何更改之前,必须彻底研究现有项目,了解其架构和要求。
如果存在 README.md 或 AGENTS.md 文件,请先阅读,以便更好地了解 Agent 的结构和用途。
评估并记录以下内容:
- 核心功能:Agent 的作用是什么?它的主要输入和输出是什么?
- 依赖项:Agent 依赖哪些外部系统、API 或数据库?
- 配置:如何配置 Agent(例如环境变量、配置文件、CLI 参数)?
- 工具与库:它使用哪些主要库与大模型交互(例如 LangChain、原生 OpenAI SDK)?
步骤 2 – 对 Agent 进行分类
阅读 Agent 的代码并对其进行分类。这决定了 interaction_mode 的值:
| interaction_mode | 模式 | 指标 |
|---|---|---|
| single-turn | 一个请求 → 一个响应 | CLI 入口点、argparse(必须移除)、主要为无状态的业务逻辑,仍建议持久化上下文 |
| multi-turn | 带记忆的对话 | 聊天循环、消息历史、会话状态、记忆对象 |
此分类决定:
- 如何使用
context.store()和context.load_history():默认情况下,为所有 Agent 持久化输入/响应;multi-turn 必须使用context.load_history(),single-turn 可选(仅在先前上下文有意作为行为的一部分时使用) - 是否为结构化输入定义
initial_form(带命名参数的 single-turn)
步骤 3 – 添加并安装依赖项
阅读 references/dependencies.md,并完整遵循其中的步骤 3 指引。
步骤 4 – 创建服务端包装器和入口点
阅读 references/wrapper-entrypoint.md,并完整遵循其中的步骤 4 指引。
步骤 5 – 通过扩展接入大模型/服务
阅读 references/llm-services.md,并完整遵循其中的步骤 5 指引。
在 LLMServiceExtensionSpec.single_demand() 中,将 suggested 模型设为与原始 Agent 使用的模型相同。
步骤 6 – 错误处理
对于用户可见的失败,请使用 Error 扩展。不要通过普通的 AgentMessage 报告错误。
实现
- 标准报告:在 Agent 内直接
raise异常(例如ValueError、RuntimeError)。平台会自动捕获并格式化异常。 - 高级配置:将
error_ext: Annotated[ErrorExtensionServer, ErrorExtensionSpec(params=ErrorExtensionParams(include_stacktrace=True))]添加为 Agent 函数参数,以便在 UI 中启用堆栈跟踪。 - 添加上下文:引发错误前,可以将诊断数据附加到
error_ext.context(字典)中。此上下文会序列化为 JSON 并显示在 UI 中。 - 多个错误:使用
ExceptionGroup(Python 3.11+)同时报告多个失败。扩展会在 UI 中将它们显示为一个组。
示例
有关实际实现示例,请参阅官方错误指南和聊天 Agent 示例。
第 7 步 – 表单(单轮结构化输入)
如果原始 Agent 接受命名参数(而不只是自由文本),请使用 Forms 扩展将这些参数映射到 initial_form。对于自由文本 Agent,普通消息输入已足够——跳过此步骤。
请阅读 references/forms.md,了解完整的实现指南(字段类型、Pydantic 模型、对话中的输入)。
第 7b 步 – 适配文件输入
如果原始 Agent 会从本地文件系统读取文件,或接受作为 CLI/函数参数传入的文件路径,则必须将这些输入替换为平台文件上传。运行时无法访问本地文件系统。即使文件包含纯文本,也仍须使用 FileField 上传——不要将文件输入合并到消息文本中。
请阅读 references/files.md,了解检测模式、替换步骤、文本提取和对话中的上传。
第 8 步 – 配置变量与机密
请阅读 references/configuration-variables.md,并完整遵循其中关于配置映射、机密处理和反模式的说明。
第 9 步 – Agent 输出
轨迹输出规则与实现
请阅读 references/trajectory.md,并完整遵循其中关于轨迹决策规则和实现的说明。
最终输出规则
Agent 或 LLM 返回给用户的主要最终输出,必须始终作为普通的 AgentMessage 或 AgentArtifact 发出。
轨迹只能包含最终答案背后的中间上下文、推理和步骤,不能替代最终回复。
如果回调仅支持同步操作,请捕获回调数据,并在之后由主 Agent 处理程序发出。
文件产物输出规则
如果原始 Agent 在执行过程中会生成、处理或输出文件(例如 CSV、PDF、图像或结构化数据转储),则必须将这些文件作为 AgentArtifact 返回给调用方。不要只将文件写入本地磁盘,然后发出“文件已生成”之类的文本消息,因为本地文件系统的更改不会返回到平台 UI。
使用平台的 API 构造一个指向生成内容的 AgentArtifact。具体实现细节请参阅 AgentArtifact Documentation。
第 10 步 – 使用平台扩展
通过 Annotated 函数参数注入扩展,增强 Agent 的平台级功能。
请阅读 references/platform-extensions.md,了解扩展选择和文档链接。
在第 10 步的决策与实现中,必须将此参考文档作为必需输入。
第 11 步 – 更新 README
更新项目的 README.md(如果缺失则创建一个),说明如何运行封装后的 Agent 服务端。内容包括:
- 安装依赖项,使用项目现有的工具(例如
uv pip install -qq -r requirements.txt或pip install -qq -r requirements.txt)。确保使用-qq标志,以保持终端输出简洁。 - 环境配置——如果使用
python-dotenv,请说明所需的.env格式。不过,请确保 Agent 仍通过显式方式接收配置,而不是在内部读取环境参数。 - 运行服务端,使用适当的命令(例如
uv run server.py或python server.py)。 - 默认地址——说明服务端默认在
http://127.0.0.1:8000启动,并且可以通过HOST和PORT环境变量进行配置。
删除或替换已过时、不再适用于封装后的 CLI 用法示例(例如基于 argparse 的命令)。
反模式
构建和测试封装器时,请确保避免以下常见问题:
- 切勿直接访问
Message对象的.text。 消息内容是多部分的。请始终使用get_message_text(input)(需要from a2a.utils.message import get_message_text)。 - 切勿将文件保存到本地磁盘。 AgentStack 环境是临时的。所有生成的文件都应直接在内存中实例化,并作为
AgentArtifact(parts=[file.to_file_part()])生成。有关正确的File.create()API 用法,请参阅管理文件。 - 切勿为 Agent 处理器使用同步函数。 Agent 函数必须是使用
yield的async def生成器。 - 切勿将平台接线隐藏在抽象层后面。 请在主入口点中保留可见的
@server.agent(...)、扩展参数和集成约定,以便审查行为。 - 切勿将运行时检查作为首选信息来源。
agentstack_sdk和a2a的详情必须首先来自提供的文档;只有在文档说明的后备情况下,才能检查已安装环境,并在最后验证导入。 - 切勿假设历史记录会自动保存。 请显式调用
await context.store(input)和await context.store(response)。 - 切勿在没有
PlatformContextStore的情况下假设历史记录会持久保存。 没有它,上下文存储在内存中,重启后会丢失。 - 切勿忘记筛选历史记录。
context.load_history()会返回 Messages 和 Artifacts。请使用isinstance(message, Message)进行筛选。 - 切勿存储单个流式传输片段。 请累积完整响应,并只存储一次。
- 切勿将扩展数据视为字典。 请使用点表示法(例如
config.api_key,而不是config.get("api_key"))。 - 切勿将
llm_config.identifier用作模型名称。 请改用llm_config.api_model。 - 切勿假设所有扩展规范都有
.demand()。 有些使用.single_demand()或直接实例化。请务必核实。 - 切勿假设密钥已预先配置或会立即出现在
secret_fulfillments中。 即使通过single_demand()请求了密钥,如果它们在运行时缺失,也必须使用await secrets.request_secrets(params=SecretsServiceExtensionParams(...))显式轮询获取。 - 切勿在轨迹扩展上同步调用
emit()。TrajectoryExtensionServer不支持.emit()。必须通过生成轨迹步骤显式输出:yield trajectory.trajectory_metadata(title="...", content="...")。 - 切勿悄悄移除现有的可选身份验证路径。 如果源 Agent 支持可选令牌/密钥,除非已明确记录经批准的行为变更,否则请保留这种可选行为。
- 单个开放式后续问题切勿使用 Forms。 对于仅包含一个问题的自由文本提示,请使用 A2A
input-required;Forms 应用于结构化的多字段输入。 - 切勿让表单字段 ID 与模型字段不匹配。 ID 不匹配会导致解析静默失败。
- 切勿使用
context.session_id。RunContext对象使用context.context_id标识会话。 - 切勿猜测平台对象的属性。
FormRender使用fields(而不是items),TextField使用label(而不是title)。 - 切勿跳过表单的空路径处理。 请处理表单已取消或未提交时的
None。 - 在多轮 Agent 中,切勿使用
parse_initial_form(...)的真假值来路由轮次。 请根据context.load_history()中是否存在已持久化的会话状态来进行路由。 - 切勿假设上传文件的 URI 是 HTTP URL。 请使用
PlatformFileUrl解析agentstack://URI。 - 切勿跳过提取轮询。
create_extraction()是异步的;请轮询get_extraction(),直到status == 'completed'。
失败条件
- 如果无法获取最新文档,请停止并说明:没有当前文档就无法继续执行。
- 如果文档缺少必要细节,且没有可靠的后备来源,请停止并明确报告阻碍因素。
最终报告(必需)
完成前,请提供以下所有内容:
- 映射摘要: 入站映射(A2A Message 到 Agent 输入)、出站映射(Agent 输出到
AgentMessage)以及所选的流式传输路径。 - 行为变更列表: 如果行为发生了变化,请列出每项变更、原因和影响。
- 业务逻辑声明: 说明业务逻辑是否发生变化;如果有变化,请附上批准和理由。
- 旧版端点兼容性结果: 说明已保留、已添加兼容层,或不适用。
- Dockerfile 提示: 询问用户是否也想添加
Dockerfile。如果用户回答“是”,请查看示例https://github.com/i-am-bee/agentstack-starter/blob/main/Dockerfile,并为项目编写Dockerfile。如果项目未使用uv,不要强制使用它。 - 测试提示: 询问用户是否想测试 Agent 功能。如果用户回答“是”,先在一个终端中启动 Agent,然后在另一个终端中运行
agentstack run AGENT_NAME。不要尝试中断run命令,因为它可能需要很长时间才能完成。如果执行失败并出现错误,请尝试修复错误并重新运行测试。重要:不要创建任何新文件或脚本(例如使用 pexpect 编写的 Python 测试脚本)来执行此测试。必须直接与终端交互。 请注意,agentstack run会触发交互式表单;通过 stdin 以编程方式测试时,请确保发送准确的字面换行符以继续填写提示。 - 运行提示: 询问用户是否想运行 Agent 并跳转到 Web UI。如果用户同意,请启动 Agent 并监控终端是否出现错误。如果发生错误,请尝试修复并重启 Agent。
验证清单(必需)
完成后,请确认:
代码质量
- 每个
import都能解析到真实且已安装的模块(运行导入验证) - Agent 函数有含义明确的文档字符串(会显示在 UI 中)
- Agent 处理函数为
async def,并使用yield返回响应 - 不再包含
argparse或sys.argv - 未更改业务逻辑,除非已明确获批(C1/C11)
- 运行时创建的临时文件会被清理(C3)
扩展与配置
- 所有面向用户的响应都使用
yield AgentMessage(text=...) - 不使用环境变量配置 API 密钥或模型,而是使用扩展
- 所需的外部 API 工具(例如 Tavily)通过 Secrets 扩展获取凭据,并将其显式传递给构造函数或客户端
- 通过 Secrets 扩展请求的每个密钥都确实在代码中使用,或传递给底层服务(C15)
- 显式传递来自扩展的大模型配置,不使用回退链
- 使用前检查可选扩展是否存在及其数据是否可用(C13)
- 错误应抛出异常(Error 扩展),而不是作为
AgentMessage返回 - 不记录、打印或持久化任何密钥(C14)
上下文与历史记录
- 通过
context.store()存储input和response - 如果持久化或读取上下文,则包含
context_store=PlatformContextStore() - 多轮对话使用
context.load_history();只有在有意需要时,单轮对话才使用它
表单与文件
- 带有结构化参数的单轮交互已定义
initial_form(C9) - 将文件系统文件输入替换为
FileField表单上传(C21) - 文本处理 Agent 使用广泛的 MIME 类型,并根据内容类型进行分支和提取
- 不从本地文件系统读取用户提供的文件
依赖项
- 将
agentstack-sdk~=<VERSION>添加到项目现有的依赖文件中(C5) - 除非用户明确要求,否则不添加 Dockerfile(C2)
验证(必须实时执行)
- 启动服务,获取
/.well-known/agent-card.json——确认 HTTP 200 且 JSON 有效。向用户展示完整输出。 - 询问用户是否需要
Dockerfile - 询问用户是否要通过
agentstack run AGENT_NAME进行测试(不要使用测试脚本——直接使用终端),并留意错误。如果出现错误,请修复并重新测试,直到成功。简要告知用户,如果出现错误,他们可以让你查看终端输出,而你会尝试修复。