
Activepieces 集成开发实战Action 编写模式与 AI 元数据规范【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces本文以 Activepieces 仓库中的 piece-builder 技能文档 为骨架结合activepieces/pieces-framework的源码实现与社区真实集成GitHub的 Action 代码系统讲解如何在 Activepieces 中编写一个生产级的 Action动作从目录约定、完整模板、认证接入、props 设计到面向 AI Agent 的元数据audience/aiMetadata/classification规范再到接线、构建与版本管理。读完你将具备为任意第三方 API 编写、注册并验证 Action 的完整实战能力。一、Action 在 Activepieces 中的定位Activepieces 是一个 AI 工作流自动化平台其自动化能力由Pieces集成包承载。一个 Piece 由三类可执行单元组成Action动作用户或 Agent 主动触发的一次操作例如创建 Issue发送邮件查询记录Trigger触发器等待外部事件发生Webhook 轮询 / Webhook 推送后启动流程Auth认证连接第三方服务所需的凭据定义。Action 是 Piece 中被调用最频繁的单元。在框架层面createAction工厂负责把一个配置对象实例化为可执行的IAction其类型定义位于 packages/pieces/framework/src/lib/action/action.tstype CreateActionParamsPieceAuth, ActionProps { name: string; auth?: PieceAuth; displayName: string; description: string; props: ActionProps; propertyGroups?: PropertyGroup[]; run: ActionRunner...; test?: ActionRunner...; requireAuth?: boolean; errorHandlingOptions?: ErrorHandlingOptionsParam; outputSchema?: OutputSchema; audience?: Audience; aiMetadata?: AiMetadata; classification?: ActionClassification; };从源码可见两个容易被忽略的默认行为test ?? params.run不提供test时测试执行器直接复用runrequireAuth ?? trueAction 默认要求已建立连接除非显式传requireAuth: false。代码组织约定每个 Action 放在独立文件中位于 Piece 的src/lib/actions/目录下一个文件对应一个 Actionpackages/pieces/community/name/ src/ index.ts # Piece 定义集中导出 actions/triggers lib/ auth.ts # 认证定义永远不内联在 index.ts 中 actions/ # 每个 Action 一个文件 triggers/ # 每个 Trigger 一个文件 common/ # 共享辅助函数可选该目录骨架与 SKILL.md 中的 SCAFFOLD 步骤一致。二、Action 模板全拆解从零写一个 Create Recordaction-patterns.md 给出了一个完整的 Action 模板。下面逐字段拆解import { createAction, Property } from activepieces/pieces-framework; import { httpClient, HttpMethod, AuthenticationType } from activepieces/pieces-common; import { myAppAuth } from ../auth; export const createRecordAction createAction({ auth: myAppAuth, name: create_record, // 唯一的 snake_case ID —— 发布后永远不要修改 displayName: Create Record, description: Creates a new record in My App, audience: both, // 显式声明 —— 见 ai-metadata.md aiMetadata: { description: Create a new record in My App. Use to add a single entry when you already have its field values. Each call creates a new record, so retries duplicate., idempotent: false, }, props: { name: Property.ShortText({ displayName: Name, description: The name of the record, required: true, }), description: Property.LongText({ displayName: Description, required: false, }), }, async run(context) { const response await httpClient.sendRequest({ method: HttpMethod.POST, url: https://api.example.com/v1/records, authentication: { type: AuthenticationType.BEARER_TOKEN, token: context.auth.secret_text, }, body: { name: context.propsValue.name, description: context.propsValue.description, }, }); return response.body; }, });关键字段说明字段含义注意点auth引用的认证定义来自../auth让context.auth获得正确的 TypeScript 类型name唯一 snake_case ID发布后不可修改——流程按 name 存储引用改名会导致存量流程失效displayName构建器界面显示的名称用自然语言如Create Contact而非POST /contactsdescription面向构建器 UI 的人类可读描述回答这个动作是干什么的audience/aiMetadata/classificationAI 就绪元数据新 Action 必填见下文第五节props输入属性定义见第四节run执行逻辑通过context.auth取凭据、context.propsValue取参数run 上下文认证与参数从哪来在run()中context提供两个核心字段context.auth——已解析的连接对象不是扁平字符串context.propsValue—— 用户在构建器里填写的 props 值键名与props定义一一对应。httpClient.sendRequest是 pieces-common 提供的统一 HTTP 客户端支持HttpMethod、AuthenticationType等枚举并会复用 Piece 框架的连接能力。上述模板中的token字段假设myAppAuth是PieceAuth.SecretText()其他认证类型的访问方式见下节。三、认证接入四种认证类型的访问模式Action 内如何读取凭据取决于认证类型。auth-patterns.md 和 SKILL.md 给出了完整对照API 认证方式Activepieces 类型run()中访问方式API Key / Bearer TokenPieceAuth.SecretText()context.auth.secret_textOAuth2PieceAuth.OAuth2()context.auth.access_token额外字段用context.auth.props?.[key]用户名 密码PieceAuth.BasicAuth()context.auth.username、context.auth.password多字段组合PieceAuth.CustomAuth()context.auth.props.field_name无需认证PieceAuth.None()无context.authcreateAction中省略auth字段OAuth2 与 CustomAuth 的进阶读取OAuth2 场景下context.auth还额外暴露context.auth.props?.[key]—— 认证定义里附加的自定义字段如数据中心、区域、子域context.auth.data—— 提供商返回的原始 token 响应refresh token、scope 等。async run(context) { const token context.auth.access_token; const region context.auth.props?.[region] as string; // ... }CustomAuth 的字段挂在props下而非直接挂在auth上async run(context) { const baseUrl context.auth.props.base_url; const apiKey context.auth.props.api_key; // ... }需要特别注意认证自身的validate回调与 Action 的run()收到的auth形状不同。validate收到的是用户原始输入SecretText 是扁平字符串、CustomAuth 是扁平对象而run()收到的是完整连接对象。CustomAuth 支持在 auth-patterns.md 中列出的属性类型ShortText、LongText、SecretText、Number、Checkbox、StaticDropdown、StaticMultiSelectDropdown、MarkDown。对于短时 token 的 API如用户名/密码换 JWTauth-patterns.md 还提供了带refresh字段的 CustomAuth 模式服务端会缓存 token 并在过期前自动续期最多提前 15 分钟短生命周期 token 会按生命周期一半收敛避免每个 Action 都触发一次登录请求导致 429 限流。此时 Action 内通过context.auth.access_token读取服务端缓存的 token。四、props 设计让输入字段既好用又对 Agent 友好props是构建器渲染表单的依据也是 LLM/MCP Agent 判断如何填值的唯一信号。props-patterns.md 强调属性description要写成一段 12 句的规格说明而不是一个标签——包含格式要求与真实样例如cus_abc123xyz、ISO 8601 日期2026-04-17T10:30:00Z因为框架没有单独的 example 字段。常用属性类型速查类型用途Property.ShortText/LongText短文本 / 多行文本Property.Number/Checkbox数字 / 布尔开关Property.DateTime日期时间Property.File文件上传Property.Json/Object任意 JSON / 键值对Property.Array数组可带结构化子属性Property.StaticDropdown/StaticMultiSelectDropdown预定义选项Property.Dropdown/MultiSelectDropdown运行时从 API 拉取选项Property.DynamicProperties运行时动态生成表单字段Property.MarkDown只读说明设置指引、警告、Webhook 地址动态下拉永远不要让用户手输 ID对选择某条记录类输入用Property.Dropdown从 API 拉取并按名称展示用户点选即可不必复制粘贴cus_abc123这类 IDProperty.Dropdown({ displayName: Project, auth: myAppAuth, // 必须传 auth否则回调里 auth 是 undefined refreshers: [], // 依赖的其他 prop 名数组 required: true, options: async ({ auth }) { if (!auth) { return { disabled: true, options: [], placeholder: Please connect your account first }; } const response await httpClient.sendRequest{ data: { id: string; name: string }[] }({ method: HttpMethod.GET, url: https://api.example.com/v1/projects, authentication: { type: AuthenticationType.BEARER_TOKEN, token: auth.secret_text }, }); return { disabled: false, options: response.body.data.map((item) ({ label: item.name, value: item.id, })), }; }, })两个容易踩的坑auth: myAppAuth必须显式传入。框架仅用它来做类型推导但如果不传回调中auth就是undefined下拉框永远加载不出来依赖上级选项时用refreshers。例如先选项目、再选该项目下的任务任务下拉的refreshers: [project]会在 project 变化时自动重新请求未选父级时返回{ disabled: true, placeholder: Please select a project first }。五、AI-Ready 元数据面向 Agent 的声明规范这是 action-patterns.md 中新 Action 必须携带的核心要求完整规则见 ai-metadata.md。Pieces 同时服务人类流程构建者与 AI Agent通过 MCP server 与 Agent 工具链三个字段决定了 Action/Trigger 如何呈现在 Agent 面前。它们在 piece-metadata.ts 中有严格的 schema 定义Audience z.enum([human, ai, both])AiMetadata { description?: string; idempotent?: boolean }ActionClassification z.enum([READ, SEARCH, WRITE, DESTRUCTIVE])这三个字段纯粹是元数据不改变执行行为且都是createAction对象上的普通值无需任何额外 import。注意createAction的CreateActionParams见 action.ts已经原生声明了audience、aiMetadata、classification直接书写即可。5.1audience这个 Action 给谁用取值含义适用场景human仅人类流程构建者可见从 Agent 工具面剔除裸 LLM / ask-AI 包装器、通用数据转换、只在可视化构建器里有意义的动作ai仅 AI Agent 可见从人类目录中隐藏以减噪Agent 专属的原子操作both人类与 Agent 都适用几乎全部真实集成 Action 的默认值必须显式写出不能省略。Piece 元数据是从原始 action 对象直接序列化的没有任何默认值注入——audience只有在文件里物理存在时下游过滤器才能看到它。已内置的custom_api_call由共享工厂createCustomApiCallAction内部固定为human裸 HTTP 逃生口不适合作为 Agent 工具只有手写createAction({ name: custom_api_call, ... })时才需要像普通 Action 一样声明自己的audience。5.2aiMetadata写给 LLM 的工具选择指南aiMetadata.description是写给在数百个工具之间做选择的 Agent的与给人看的description不同它要回答我什么时候该选它。写作结构13 句它做什么——不复述人类描述何时选它——如有功能相近的兄弟动作明确指出取舍批量插入请用 batch 动作按邮箱搜索请用 Y关键约束与重试行为——必填搭配、副作用以及用自然语言说明重试安全性safe to retry / each call creates a new record。idempotent的推导依据run()实际发出的 API 调用而非动作名称。完整推导表run()的行为idempotentGET / list / search / lookuptrue基于调用方提供的稳定 ID 的 Upserttrue按 ID 将指定记录更新到给定状态PATCH/PUTtrueCreate / send / append / enqueue每次调用产生新实体falseDelete重试通常会 404 或报错false多步变更如先复制后删除的 movefalse——部分重试会重复或报错Agent 依据该字段推理安全重试它直接映射到 MCP 的idempotentHint。5.3classification对外部状态做了什么classification渲染为构建器 piece 选择器上的徽章READ/SEARCH/WRITE为灰色静音胶囊DESTRUCTIVE为红色。分类依据run()体与其中 API 调用的真实效果名称与描述只是提示、不是证据。优先级顺序先命中者胜值含义典型动词DESTRUCTIVE移除或禁用外部状态重试无法恢复delete, purge, revoke, cancel, archive, 订阅/监视的 stop/teardownWRITE创建或改变外部状态可恢复create, send, post, update, upsert, move, assign, tagSEARCH按查询或枚举读取0 到多个结果无变更list, search, find, queryREAD读取特定已知资源或固定状态get, retrieve, describe, download容易混淆的边界规则所有 Trigger 一律READ——徽章回答的是这一步是否改变什么READ/SEARCH 的区分针对如何寻址数据按 ID 还是按查询对被动等待的事件无意义发送send是WRITE而非DESTRUCTIVE——发送邮件/消息是增加状态不销毁任何东西纯流程内转换文本/数学/日期/JSON/CSV/加密辅助函数→READAI/LLM 推理但不持久化外部工件→READ生成并上传/存储 →WRITE一个动作多操作operationprop 可读可删→ 按可达的最坏情况标记任意操作动作裸 SQL、裸 HTTP、调用方指定方法→WRITE工厂构建的动作在工厂层标记而非每个 piece 单独标记。框架在 piece-metadata.ts 中还定义了READ_ONLY_CLASSIFICATIONS [READ, SEARCH]与isReadOnlyClassification()辅助函数供下游只读过滤使用。5.4 Trigger 的元数据差异Trigger 只接受aiMetadata仅description与classification: READ不接受audience和idempotent——Trigger 是事件而非 Agent 可调用的操作export const newRecordTrigger createTrigger({ name: new_record, classification: READ, displayName: New Record, description: Triggers when a new record is created, aiMetadata: { description: Fires when a new record is created in My App, once per record., }, // ... type, props, sampleData, run, onEnable, onDisable });描述应说明事件何时触发、单次载荷代表什么每条记录每批更新时是否也触发。六、真实案例剖析GitHub Create Issueaction-patterns.md 指向的仓库真实实现是 packages/pieces/community/github/src/lib/actions/create-issue.ts。它在模板基础上展示了几个进阶手法export const githubCreateIssueAction createAction({ auth: githubAuth, name: github_create_issue, classification: WRITE, displayName: Create Issue, description: Create Issue in GitHub Repository, audience: human, aiMetadata: { description: Opens a new issue in a GitHub repository with a title and optional body, labels, and assignees. Use to file a bug, task, or request in a specified repo. Not idempotent: each call creates a separate issue even with identical input., idempotent: false, }, props: { repository: githubCommon.repositoryDropdown, title: Property.ShortText({ ... }), description: Property.LongText({ ... }), labels: githubCommon.labelDropDown(), assignees: githubCommon.assigneeDropDown(), }, outputSchema: issueActionOutputSchema, async run({ auth, propsValue }) { ... }, });从该实现可以提炼的实战要点共享辅助函数repositoryDropdown、labelDropDown()、assigneeDropDown()定义在 github/src/lib/common 中——复用的下拉逻辑收敛到common/符合 SKILL.md 中匹配现有 piece 约定的黄金法则outputSchema通过issueActionOutputSchema声明输出结构让下游表格、Agent明确知道返回形状该类型定义见 piece-metadata / output-schema 相关源码解构式 runasync run({ auth, propsValue })直接从上下文解构代码更简洁按需组装请求体labels、assignees为可选时仅在存在时才写入issueFields避免向 API 发送空数组统一 API 封装githubApiCall把 base URL、认证注入、路径拼接封装在 common 层Action 内只描述业务参数conditional 参数读取const { owner, repo } propsValue.repository!展示动态下拉返回值如何解构使用。另一个值得参考的认证读取例子在 stripe/src/index.tsSecretText 模式而 OAuth2 附加 props 的组合可参考 zoho-campaigns 与 github/src/index.ts。七、接线与验证从单文件到可运行 Piece写完 Action 文件后还需要完成接线、注册、构建三步详见 SKILL.md。1. 在src/index.ts中注册import { createPiece } from activepieces/pieces-framework; import { createCustomApiCallAction } from activepieces/pieces-common; import { myAppAuth } from ./lib/auth; import { createRecordAction } from ./lib/actions/create-record; export const myApp createPiece({ displayName: My App, description: What the app does in one sentence., minimumSupportedRelease: 0.36.1, categories: [PieceCategory.PRODUCTIVITY], auth: myAppAuth, actions: [ createRecordAction, createCustomApiCallAction({ baseUrl: () https://api.example.com/v1, auth: myAppAuth, authMapping: async (auth) ({ Authorization: Bearer ${auth.secret_text}, }), }), ], triggers: [], });接线检查清单每个 Action 在src/index.ts中 import 并加入actions: [...]每个 Trigger 加入triggers: [...]添加createCustomApiCallAction提供免写代码的通用自定义请求入口每个手写 Action 携带audience、aiMetadata、classification每个 Trigger 携带aiMetadata与classification: READ认证对象只 import 不 re-exportauth.ts中的myAppAuth只出现在createAction({ auth })等处绝不能在index.ts的导出里再出现2. 在tsconfig.base.json中注册路径别名在仓库根目录 tsconfig.base.json 中按字母序插入该 piece 的路径映射漏掉会导致构建失败activepieces/piece-name: [packages/pieces/community/name/src/index.ts]3. 构建、lint 与本地验证bun install # 仅新 piece 需要——创建 workspace 符号链接 npx turbo run build --filteractivepieces/piece-name npx turbo run lint --filteractivepieces/piece-name构建与 lint 都必须通过——即便 build 绿了lint 失败未使用的 import、any类型、未使用变量也会阻塞 CI。常见的 TS 报错集中在src/index.ts漏 import、tsconfig.base.json缺条目、Trigger 缺sampleData。本地联调把AP_DEV_PIECESname写入packages/server/api/.envnpm start后打开localhost:4200即可在构建器中试跑。4. 修改既有 piece 的版本号规则对既有 piece 的任何修改都必须在package.json中升版本否则线上流程永远拿不到变更版本段何时升MAJOR删除 Action/Trigger/prop给既有 Action/Trigger 新增必填prop改变既有行为PATCH新增 Action 或 Trigger新增可选prop新增输出属性修复 bug经验法则任何删除都是破坏性的任何新增必填 prop 都是破坏性的其余按 PATCH 处理拿不准时倾向 MAJOR。八、常见陷阱速查name是永久的——发布后不可改流程按 name 存储引用见 SKILL.mdaudience不能省略——元数据序列化无默认值注入省略等于对 Agent 不可见动态下拉必须传auth: myAppAuth——否则回调里auth为undefined选项永远加载不出validate与run中 auth 形状不同——前者是原始输入扁平后者是完整连接对象context.authidempotent依据run()判断——别被动作名误导create 类操作即使输入完全相同也会产生新实体必须标false工厂包装时元数据会丢失——如果 Action 由共享工厂生成工厂的 params 类型必须声明并透传audience/aiMetadata/classification否则字段静默不生效见 ai-metadata.md。延伸阅读AI 元数据完整规范audience 含义、idempotent 推导、classification 判定细则认证模式全解SecretText / OAuth2 / BasicAuth / CustomAuth / 带 refresh 的 CustomAuth / Connection Identifier属性类型参考文本、数字、文件、JSON、数组、静态/动态下拉、动态属性、MarkDownPiece 类型与分类community / core / customUI 组件与展示模式选择指南输出质量面向表格的数据整形规范piece-builder 技能总入口完整五步工作流框架层 Action 工厂实现元数据 schema 定义Audience / AiMetadata / ActionClassification真实示例GitHub Create Issue【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考