mcpField
C
camunda-ai-agents

camunda-ai-agents

github.com/camundaAgent 工作流26115 次安装1 天前更新
代码仓库

关于 camunda-ai-agents

camunda-ai-agents 是用于在 Camunda 8.8 及更高版本中构建 Agentic AI 流程的技能。它说明如何配置 AI Agent 连接器、定义 BPMN 工具与提示词,以及管理 Agent 上下文和响应。

主要功能

  1. 01在即席子流程中建模 Agent
  2. 02配置 AI Agent 连接器模板
  3. 03用 BPMN 活动定义工具
  4. 04使用 fromAi() 声明工具输入
  5. 05配置提示词和响应处理
  6. 06支持 v1 与 v2 模板迁移

适用场景

  1. 01构建调用 LLM Agent 的流程
  2. 02将 REST 调用建模为 Agent 工具
  3. 03向 BPMN 活动传递生成的参数
  4. 04将 AI Agent 模板从 v1 升级到 v2

安装

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

$npx skills add https://github.com/camunda/skills --skill camunda-ai-agents

安装后在 Claude Code 中输入/camunda-ai-agents确认已加载。

包含的文件

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

portability.json
references/
ai-agent-task.md
fromai.md
tool-modeling.md
v1-to-v2-upgrade.md

详细介绍

Camunda AI Agent

在 Camunda 8.8+ 中构建 Agent 式 AI 流程:将 LLM 驱动器(AI Agent 连接器的 子流程变体)应用于临时子流程,并将工具建模为 BPMN 活动。涵盖形状、提示词、使用 fromAi() 建模工具、子流程工具和多轮 Agent 上下文。

较早的 任务变体(在服务任务上使用 AI Agent 连接器,并搭配外部多实例临时子流程和显式反馈循环)记录在 references/ai-agent-task.md 中,适用于需要审计或拦截每次工具调用的特殊场景。其他情况均推荐使用子流程变体,本技能其余内容也将介绍该变体。

前提条件

  • Camunda 8.8+ 集群(AI Agent 连接器随 8.8+ 提供)
  • 已安装 c8ctl CLI 并配置好配置文件 — 参见 camunda-c8ctl
  • 由用户提供的服务商、确切的模型标识符及其现有连接器密钥名称。将密钥值存储为 Camunda 集群密钥,切勿放入 BPMN 文件。对于本地 c8run,密钥引导流程请参见 camunda-c8ctl。

服务商配置

创建或编辑 BPMN 之前,请确认服务商、确切的模型标识符以及所有必需的现有连接器密钥名称。如果有任何信息缺失,请询问用户,并在确认前停止操作。不要选择默认服务商或模型,不要编造密钥名称,也不要询问密钥值。检查所选模板中与服务商相关的模型和身份验证字段。

对于使用 Camunda 托管连接器的 Camunda SaaS,请在 Console 中配置密钥值。在 BPMN 中使用已确认的密钥名称作为 {{secrets.NAME}} 引用。

交叉引用

  • camunda-bpmn:BPMN 基础知识、临时子流程元素、命名空间、必需的 lint 循环。
  • camunda-connectors:用于应用 AI Agent 模板的底层 c8ctl element-template 工作流(以及常用作工具的 REST 连接器)。
  • camunda-feel:用于提示词的 FEEL 语法、fromAi() 调用、结果表达式、类型强制转换。
  • camunda-process-mgmt:部署流程、启动实例、检查 Agent 调用产生的故障。

权威参考资料

模板代际:v1 和 v2

Camunda 8.10 引入了 v2 AI Agent 元素模板(ID 后缀为 .v2,例如 io.camunda.connectors.agenticai.ai-agent-subprocess.v2)(8.10+),并弃用了 v1(例如 io.camunda.connectors.agenticai.aiagent.jobworker.v1)。它们是不同的模板,使用不同的作业类型。v1 目前仍可使用,但已弃用,且不会新增提供方功能。

v2 增加了推理/思考设置、提示词缓存、彼此独立的提供方与后端选择(例如,在 AWS Bedrock Mantle 或 Foundry 上使用 Anthropic),以及自定义聊天模型提供方。

  • 新建 Agent,集群为 8.10+:使用 v2。
  • 集群低于 8.10,或 Desktop Modeler 低于 5.51.0:使用 v1——v2 需要 8.10 引擎,在较旧的 Modeler 中会显示为 Not found。
  • 现有 v1 元素,集群为 8.10+:升级到 v2——v1 已弃用。v1 仍可使用,因此升级可以稍后进行;在 v1 中更新(不带 --to)仅是权宜之计,请参阅参考文档。

切换会在每次重新部署时生效:正在运行的实例会继续由 v1 作业工作器执行。

c8ctl element-template search "ai agent" 会返回两个代际的模板。下方应用示例中的提供方 --set 路径采用 v1 格式;v2 会将凭据嵌套在 backend.<type> 下(例如 provider.anthropic.backend.anthropic.apiKey)——请运行 c8ctl element-template get-properties <id> 查看所选模板。

要将 v1 迁移到 v2,请阅读 references/v1-to-v2-upgrade.md。

应用 AI Agent Connector

仅有临时子流程并不构成 AI Agent。请对其应用 AI Agent 子流程 Connector 模板;不要用通用子流程或服务任务代替。

示例——通过 c8ctl 应用模板,而不是手动编写数量众多的提供方/提示词/记忆字段:

# 0. One-time per environment: sync the OOTB catalog. search,
#    get-properties, and OOTB-ID apply need this to have run at
#    least once. Skip on subsequent runs.
c8ctl element-template sync

# 1. Find the current template ID and version — they evolve
c8ctl element-template search "ai agent"

# 2. Inspect the selected provider's model and authentication fields.
c8ctl element-template get-properties <id>
c8ctl element-template get-properties <id> --detailed data.systemPrompt.prompt

# 3. Replace placeholders with user-supplied values and selected-template fields.
c8ctl element-template apply -i <id> AgentTools process.bpmn \
  --set 'provider.type=<provider>' \
  --set 'provider.<provider>.authentication.<field>={{secrets.<secret-name>}}' \
  --set 'provider.<provider>.model.<field>=<model>' \
  --set data.systemPrompt.prompt='="You are a customer support agent. Use the available tools to look up customers and orders, and escalate to a human only when needed."' \
  --set data.userPrompt.prompt='="Customer " + customerId + " reports: " + issue' \
  --set data.limits.maxModelCalls='=10'

该模板会处理 zeebe:taskDefinition、zeebe:adHoc 集合绑定、默认输入映射,以及特定于模型提供方的字段——这些内容会随模板版本变化,请勿手动编写。

支持的提供方:

  • v1 provider.type:anthropic、bedrock、azureOpenAi、google-vertex-ai、openai、openaiCompatible。
  • v2 provider.type:anthropic、bedrock、openai、google-gemini、mistral、custom。Azure/Foundry、Vertex AI 和 OpenAI-compatible 均作为这些提供方的后端。

BPMN 形状

宿主元素是 bpmn:adHocSubProcess——不是服务任务,也不是常规子流程。工具位于其中。

bpmn:adHocSubProcess  (template applied here)
└── <root activities, each one a tool>
    bpmn:serviceTask   — e.g., REST connector call
    bpmn:scriptTask    — FEEL computation
    bpmn:userTask      — human-in-the-loop
    bpmn:subProcess    — multi-step or async tool

Lint 循环无法检测以下硬性规则——请通过阅读 BPMN 进行核验:

  • 元素类型必须是 bpmn:adHocSubProcess。常规的 bpmn:subProcess 或服务任务无法承载该 Connector。
  • 工具的根节点是 LLM 选择的入口活动。根节点没有入向顺序流,且不能是边界事件。入向流会使该节点变成常规流程步骤,Agent 将无法看到它。
  • 临时子流程必须至少包含一个活动——这是 BPMN 语义要求;空 Agent 会被拒绝。
  • 工具的执行流中必须在某处设置变量 toolCallResult——对于单活动工具,设置它的就是该活动本身;对于子流程工具,可以是子流程中的任意活动。

定义工具

对于包含多个部分的审核,请将每项独立检查建模为一个专用的根工具,而不是一个包罗万象的任务。

有 3 项因素决定大模型能否正确选择工具:

  1. 工具名称 — 即临时子流程中的活动 ID(例如 LookupCustomer、GetCurrentWeather)。连接器使用 BPMN id,而非面向用户的 name 属性,作为传递给大模型的工具名称。请选择描述性 ID。

  2. 工具描述 — 活动上的 <bpmn:documentation> 值。如果缺少文档,连接器会回退到活动的 name 属性,但务必显式设置文档。优秀的描述会说明工具的用途、适用场景、不适用场景以及返回内容:

    “按 ID 查找客户。返回客户的姓名、等级和账户状态。当用户提到客户 ID 或姓名时调用。不要用于匿名查询。”

    大模型会逐字看到该描述,因此其中不要包含供应商名称、内部 URL,或任何你不希望它原样引用的内容。c8ctl element-template apply 不会写入 <bpmn:documentation>;应用工具连接器模板后,请手动编辑并添加。

  3. 输入架构 — 根据活动输入映射中的 fromAi() 调用自动生成。没有 fromAi() 调用 → 架构为空 → 大模型无法传入参数。

工具可以是单个活动(服务任务、脚本任务、用户任务),也可以是以 bpmn:subProcess 为根节点、包含更多活动的子流程。这两种情况下,大模型都只能看到根节点——描述、输入和架构均从根节点读取。内部子流程步骤对大模型不可见;它们按常规 BPMN 语义依次执行,并在子流程完成时向上传递变量。

对于子流程工具,这一点是字面意义上的:将 fromAi() 调用放在 bpmn:subProcess 根节点自身的 zeebe:ioMapping 上,而不是后代活动上——子任务上的 fromAi() 会生成空架构,因此大模型调用工具时不会传入参数,所有下游值(包括表单字段)都会变成 null。

references/tool-modeling.md 中提供了 4 种类型(REST、脚本、用户任务、子流程)的完整 XML 示例。

fromAi() — 声明 AI 生成的参数

fromAi() 会将一个值标记为“由大模型在运行时提供”。第一个参数必须是对 toolCall.<paramName> 的引用——最后一个片段会成为大模型可见的参数名称。该函数还可接受可选的描述、类型(默认值为 "string",另有 "number"、"boolean"、"array"、"object")、JSON Schema 片段,以及用于 {required: false} 等选项的上下文。

<zeebe:input
  source='="https://api.example.com/customers/" + fromAi(toolCall.id, "Customer ID", "string")'
  target="url" />

完整签名以及全部 6 种调用方式(位置参数、命名参数、枚举架构、可选参数、多次调用的 JSON 请求体),请参阅 references/fromai.md。

toolCallResult — 将输出返回给 Agent

工具完成后,连接器会从工具的作用域中读取名为 toolCallResult 的变量,并将其转发给 LLM,作为工具调用响应。规则针对的是作用域,而不是由哪个活动设置该变量:

  • 单活动工具 — 活动本身设置 toolCallResult(通过结果表达式/结果变量/输出映射/脚本结果变量)。
  • 子流程工具 — 子流程中的任何活动都可以设置 toolCallResult;BPMN 变量作用域会在子流程完成时将该值传递到子流程作用域。

根据活动类型,设置方式如下:

  • 带结果表达式的连接器:value="={toolCallResult: response.body}"。
  • 带结果变量的连接器:将结果变量命名为 toolCallResult。
  • 输出映射:<zeebe:output source="=someValue" target="toolCallResult" />。
  • 脚本任务:<zeebe:script expression="..." resultVariable="toolCallResult" />。

该值可以是基本类型(字符串、数字),也可以是复杂的 FEEL 上下文——发送给 LLM 前会将其序列化为 JSON。如果工具完成时 toolCallResult 缺失或为空,连接器会向 LLM 发送一条通用消息:“工具成功执行,但未返回结果”,后续轮次的效果会变差。务必为其设置有意义的值。

提示词

data.systemPrompt.prompt 和 data.userPrompt.prompt 都是 FEEL 字符串——必须以 = 开头。

<zeebe:input
  source='="You are a customer support agent. Use available tools to look up customers and orders. Escalate to a human only when needed."'
  target="data.systemPrompt.prompt" />
<zeebe:input
  source='="Customer " + customerId + " (priority: " + priority + ") reports: " + issue'
  target="data.userPrompt.prompt" />
  • 静态提示词:="You are ..."。即使是纯文本,也必须包含 =。
  • 变量插值:="Customer " + customerId + " reports: " + issue。+ 会将标量强制转换为字符串。
  • 反馈循环提示词:=if (is defined(followUpInput)) then followUpInput else initialUserInput。在用户提供后续输入并返回 Agent 时使用——见下文“响应交互”。

对于较长且结构化的提示词,可在上游脚本任务中构建字符串,并通过变量传入。

工具调用反馈循环

工具反馈循环是内部机制:Agent 作业工作线程会反复调用 LLM、激活其选择的工具、收集结果并重新提示,直到 LLM 生成最终响应,或达到 data.limits.maxModelCalls。无需对循环进行建模——只需建模工具。

读取 Agent 响应

Agent 会将输出写入一个上下文变量,其名称由连接器的结果变量字段指定,默认值为 agent。如果同一流程中有多个 Agent,请为每个 Agent 设置唯一的结果变量名(例如 mySecondAgent),并相应地重新设置 Agent 上下文输入字段(mySecondAgent.context),以避免 Agent 之间互相干扰。

结果上下文包含哪些字段取决于响应设置(以下示例使用默认值 agent):

  • agent.responseText — 当 data.response.format.type=text(默认值)时。
  • agent.responseJson — 当 format=json,或当 format=text 且 data.response.format.parseJson=true 时。
  • agent.context — 当 data.response.includeAgentContext=true 时。下文的响应交互模式需要此字段。

提供商 × format=json 兼容性。 OpenAI 原生支持 data.response.format.type=json(JSON 模式;提供 schema 可生成结构化输出)。Anthropic 和 AWS Bedrock 仅在提供 data.response.format.schema 时支持。对于其他提供商以及 v1 模板,请使用 format=text + data.response.format.parseJson=true,并读取 agent.responseJson。

Schema 是 FEEL 上下文字面量。 当使用 format=json 时,data.response.format.schema 的类型为 feel: required——应将其写成 ={ type: "object", properties: { ... } },而不是带引号的 JSON 字符串。

JSON 解析失败时。 两种路径的行为不同:在 format=text 下设置 parseJson=true 时,会省略 responseJson,但仍会将原始(无法解析的)文本填入 responseText——不会触发事件。原生 format=json 则会因错误代码 FAILED_TO_PARSE_RESPONSE_CONTENT 触发事件;如需优雅回退,请使用错误边界事件处理。

响应交互(用户反馈循环)

Agent 生成最终响应后,你可能希望用户(或另一位担任评审的 Agent)审阅或修改该响应,再将其传回。此模式会从临时子流程转到收集 followUpInput 的用户任务,然后再返回同一个 Agent 临时子流程。用户提示词中的 FEEL 会在初始输入和后续输入之间切换:

data.userPrompt.prompt = =if (is defined(followUpInput)) then followUpInput else initialUserInput

Agent 会在重新进入时保留对话上下文;有关当前的上下文处理字段名称,请参阅子流程文档,因为这些名称在不同模板版本间有所变化。

限制与记忆

  • data.limits.maxModelCalls — 限制每次 Agent 执行的大模型调用次数。务必设置(5–20 是常见的起始范围);如果没有合理的上限,行为异常的提示词可能会造成高额费用。没有基于时间的限制。
  • data.memory.contextWindowSize — 限制 Agent 重放给大模型的历史消息数量(默认值为 20)。数值较小可节省令牌,数值较大则可保留更多上下文。
  • data.memory.storage.type — in-process(默认)、camunda-document(当上下文超过变量大小限制时,将其转存到 Camunda Document 存储),或 custom。请使用带连字符的形式。

故障排查

以下是不明显、无法通过 lint 循环发现的故障模式。

  • 工具有传入的顺序流 — 它会变成常规流程步骤,不再是工具。工具的 ROOT 节点不得有传入流。子流程工具内部的活动可以有传入流(实际也会有)——子流程正是通过这种方式运行的。
  • 工具名称混淆 — 大模型可见的工具名称是 BPMN id,而不是 name 属性。请使用描述性的 PascalCase ID。
  • 裸字符串提示词 — 系统提示词和用户提示词都属于 FEEL。即使是字面值,也必须写成 ="..."。
  • 字符串中的数字 FEEL — 将数字拼接到 URL 或消息中需要使用 string(x);字符串与未强制转换的数字之间使用 + 会失败。类型转换请参阅 camunda-feel §。
  • 带连字符的记忆存储类型 — in-process、camunda-document、custom。不要使用 camelCase。

收尾步骤

在宣布 Agent 流程完成之前,请运行 BPMN lint 循环(参见 camunda-bpmn):

c8ctl bpmn lint process.bpmn

Lint 现在会检测子流程工具中 fromAi() 的错误位置——bpmnlint-plugin-camunda-compat 中的 agent-fromai-contract 规则会标记在后代活动而非工具入口元素上声明的 fromAi() 调用(对于子流程工具,应在 bpmn:subProcess 根节点自身的 zeebe:ioMapping 上声明)。请先运行 lint;如果检查通过,但子流程工具的参数仍返回 null,请重新对照上文的“定义工具”部分进行检查。

Lint 可以发现 BPMN 结构问题,但不会验证连接器模板的输入。Lint 检查通过后,请通过阅读 BPMN 进行验证:

  • 宿主元素是应用了 AI Agent Sub-process 模板的 bpmn:adHocSubProcess,而不是未配置的临时子流程。
  • 每个工具的根节点都没有传入顺序流,并且包含 <bpmn:documentation> 元素(apply 不会写入该元素——请通过直接编辑来设置)。
  • 每个工具的流程结束时,toolCallResult 都已在作用域中设置。
  • 两个提示词都以 = 开头。
  • data.limits.maxModelCalls 已设置。
  • 提供方、模型和 {{secrets.NAME}} 引用均已由用户确认;切勿将密钥值放入 BPMN。

参考资料

如需详细参考资料,请阅读 references/ 中的文件:

  • tool-modeling.md — 四种工具形态(REST 连接器、脚本任务、用户任务、子流程)的 XML 示例,包括异步回调子流程
  • fromai.md — 完整的 fromAi() 签名、所有调用变体(位置参数、命名参数、枚举架构、可选参数、多调用 JSON 请求体)
  • v1-to-v2-upgrade.md — 使用 c8ctl element-template update 将 v1 元素迁移到 v2 模板:ID 对照、试运行/报告工作流、配方与手动提供方映射、升级后步骤
  • ai-agent-task.md — 较早的 Task 变体(审核/拦截每次工具调用),仅适用于小众场景

评论

支持 Markdown