mcpField
A
agentstack-wrapper

agentstack-wrapper

github.com/i-am-beeAgent 工作流1.2k53 次安装30 周前更新
代码仓库

关于 agentstack-wrapper

Agent Stack Wrapper 是一份将 Python Agent 接入 Agent Stack 平台的集成技能指南,面向负责适配现有 Agent 的开发者。它以分步清单、扩展接入规则和安全约束指导包装过程,并要求尽量避免改变原有业务逻辑。

主要功能

  1. 01分步指导 Python Agent 接入
  2. 02涵盖依赖、入口与服务包装
  3. 03映射表单和文件输入
  4. 04配置扩展、变量与机密
  5. 05规定安全及错误处理约束
  6. 06提供验证清单与完成报告

适用场景

  1. 01将现有 Python Agent 适配到 Agent Stack
  2. 02把命令行参数改为平台结构化输入
  3. 03为 Agent 配置 LLM 或服务扩展
  4. 04检查集成改动与安全要求

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/i-am-bee/agentstack --skill agentstack-wrapper

安装后在 Claude Code 中输入/agentstack-wrapper确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
configuration-variables.md
dependencies.md
files.md
forms.md
llm-services.md
platform-extensions.md
trajectory.md
wrapper-entrypoint.md

详细介绍

Agent Stack 封装器

将 Python Agent 封装到 Agent Stack 平台的集成指南。

目录

安全要求

  • 切勿运行远程脚本或不可信代码。
  • 使用可信的软件包元数据、固定版本,并审计已安装的 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 上下文窗口:

  1. 迭代推进:严格按照步骤执行集成工作流清单。使用内置任务/待办跟踪工具逐项对应清单,并在完成每个步骤后将其标记为已完成。这样无需创建额外文件,也能直观地跟踪进度。
  2. 减少终端输出:调试时,避免大量堆栈跟踪污染上下文。只提取 Exception 行及其紧邻的跟踪文件信息,省略庞大的框架日志。
  3. 有针对性地阅读代码:如果 SKILL.md 或大型源代码文件没有变更,不要反复加载。
  4. 不要创建跟踪文件:不要创建 task.md、implementation_plan.md、walkthrough.md 或类似的 Markdown 文件来跟踪进度。内置任务跟踪工具是唯一的进度状态来源。

事实来源优先级(必需)

对于每项封装任务,严格按照以下优先级顺序:

  1. 绝对首要(最高优先级): 对所有导入项、类名和类型,使用已安装的包/运行时内省(references/dependencies.md 中的内联包搜索)。
  2. 首要(必须第二步): 使用 references/ 文件夹中的本地技能文件,了解架构模式、扩展选择和映射逻辑。
  3. 次要: 使用此技能链接的官方文档 URL,了解详细的 API 行为。
  4. 第三优先级: 使用本地项目源代码和仓库文档(README/AGENTS)来映射行为和集成点。
  5. 最后一步: 实现完成后进行运行时验证(导入/服务检查)。

如果使用第 3 步,必须明确记录文档中缺少哪些信息,以及为何需要回退到其他来源。

关键工作流要求: 对于你决定使用的每个扩展(无论来自 LLM/Forms/Error 步骤还是平台扩展),都必须按以下顺序执行这些步骤:

  1. 决定是否应实现该扩展。
  2. 如果是,阅读下方扩展表中提供的文档 URL(例如,使用工具读取网页)。此步骤为必需操作,且必须在任何代码编辑之前完成。
  3. 直接从官方文档中提取正确的导入项、类名、方法名、属性及其准确类型。
  4. 只有阅读文档后,才能开始编写或修改 Agent 代码。切勿猜测导入项或依赖过时的记忆。
  5. 如果文档不完整/含糊不清,则使用本地/运行时内省作为回退,并记录具体缺失之处。

集成工作流清单

将此清单复制到上下文中,并在完成各项后勾选:

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 报告错误。

实现
  1. 标准报告:在 Agent 内直接 raise 异常(例如 ValueError、RuntimeError)。平台会自动捕获并格式化异常。
  2. 高级配置:将 error_ext: Annotated[ErrorExtensionServer, ErrorExtensionSpec(params=ErrorExtensionParams(include_stacktrace=True))] 添加为 Agent 函数参数,以便在 UI 中启用堆栈跟踪。
  3. 添加上下文:引发错误前,可以将诊断数据附加到 error_ext.context(字典)中。此上下文会序列化为 JSON 并显示在 UI 中。
  4. 多个错误:使用 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 服务端。内容包括:

  1. 安装依赖项,使用项目现有的工具(例如 uv pip install -qq -r requirements.txt 或 pip install -qq -r requirements.txt)。确保使用 -qq 标志,以保持终端输出简洁。
  2. 环境配置——如果使用 python-dotenv,请说明所需的 .env 格式。不过,请确保 Agent 仍通过显式方式接收配置,而不是在内部读取环境参数。
  3. 运行服务端,使用适当的命令(例如 uv run server.py 或 python server.py)。
  4. 默认地址——说明服务端默认在 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'。

失败条件

  • 如果无法获取最新文档,请停止并说明:没有当前文档就无法继续执行。
  • 如果文档缺少必要细节,且没有可靠的后备来源,请停止并明确报告阻碍因素。

最终报告(必需)

完成前,请提供以下所有内容:

  1. 映射摘要: 入站映射(A2A Message 到 Agent 输入)、出站映射(Agent 输出到 AgentMessage)以及所选的流式传输路径。
  2. 行为变更列表: 如果行为发生了变化,请列出每项变更、原因和影响。
  3. 业务逻辑声明: 说明业务逻辑是否发生变化;如果有变化,请附上批准和理由。
  4. 旧版端点兼容性结果: 说明已保留、已添加兼容层,或不适用。
  5. Dockerfile 提示: 询问用户是否也想添加 Dockerfile。如果用户回答“是”,请查看示例 https://github.com/i-am-bee/agentstack-starter/blob/main/Dockerfile,并为项目编写 Dockerfile。如果项目未使用 uv,不要强制使用它。
  6. 测试提示: 询问用户是否想测试 Agent 功能。如果用户回答“是”,先在一个终端中启动 Agent,然后在另一个终端中运行 agentstack run AGENT_NAME。不要尝试中断 run 命令,因为它可能需要很长时间才能完成。如果执行失败并出现错误,请尝试修复错误并重新运行测试。重要:不要创建任何新文件或脚本(例如使用 pexpect 编写的 Python 测试脚本)来执行此测试。必须直接与终端交互。 请注意,agentstack run 会触发交互式表单;通过 stdin 以编程方式测试时,请确保发送准确的字面换行符以继续填写提示。
  7. 运行提示: 询问用户是否想运行 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 进行测试(不要使用测试脚本——直接使用终端),并留意错误。如果出现错误,请修复并重新测试,直到成功。简要告知用户,如果出现错误,他们可以让你查看终端输出,而你会尝试修复。

评论

支持 Markdown