--- title: "组件:Runner" --- Runner 组件用于实现 Agent 的运行逻辑,也可以按事件注册处理函数,供「插件处理器」使用。两种写法共用 `RunnerContext`,插件安装后由用户选择组件并配置。 环境准备见[插件开发教程](/zh/plugin/dev/tutor)。 ## 添加 Runner 组件 单个插件中可以添加多个事件处理器。请在插件目录执行命令 `lbp comp Runner`,名称填写 `welcome`,描述填写 `Welcome new members`。 ```bash lbp comp Runner ``` 生成的 `components/runner/welcome.yaml` 定义组件信息,`welcome.py` 是处理程序。 ## 自定义运行逻辑 需要接入模型或实现自己的执行循环时,声明 `spec.usages: [agent]`,在 `run(ctx)` 中返回结果: ```python from langbot_plugin.api.definition.components.runner import Runner, RunnerContext, RunnerResult from langbot_plugin.api.entities.builtin.provider.message import Message class Echo(Runner): async def run(self, ctx: RunnerContext): yield RunnerResult.run_completed( ctx.run_id, message=Message(role="assistant", content=ctx.input.to_text()), ) ``` ## 清单文件:Runner 将 `welcome.yaml` 修改为: ```yaml apiVersion: langbot/v1 kind: Runner metadata: name: welcome label: en_US: Welcome members zh_Hans: 欢迎新成员 ja_JP: 新しいメンバーを歓迎 description: en_US: Welcome new members and respond to /hello. zh_Hans: 欢迎新成员,并响应 /hello 消息。 ja_JP: 新しいメンバーを歓迎し、/hello に返信します。 spec: usages: [event] events: - group.member_joined - message.received capabilities: tool_calling: true permissions: tools: [detail, call] config: - name: greeting type: string label: en_US: Greeting zh_Hans: 欢迎语 ja_JP: 歓迎メッセージ required: true default: Welcome aboard! - name: reply_enabled type: boolean label: en_US: Send replies zh_Hans: 发送回复 ja_JP: 返信する default: true execution: python: path: ./welcome.py attr: Welcome ``` `spec.events` 指定支持的事件,`spec.config` 定义用户可在处理器详情页修改的配置。本例支持成员入群和收到消息,并提供欢迎语、回复开关两个配置项。回复消息需要上面的 `tool_calling` 和 `permissions.tools` 配置。 `spec.usages` 决定组件可在哪类处理器中选择:`agent` 用于 Agent 和流水线,`event` 用于插件处理器。可同时声明 `[agent, event]`;包含 `event` 时必须填写 `spec.events`。本例使用事件处理函数,也可以在 `run(ctx)` 中按需调用 `await super().run(ctx)`。 ## 插件处理 在 `Welcome` 类的 `initialize` 方法中注册事件处理函数。将 `welcome.py` 修改为: ```python from langbot_plugin.api.definition.components.runner import ( Runner, RunnerContext, ) from langbot_plugin.api.entities.builtin.platform.events import ( MemberJoinedEvent, MessageReceivedEvent, ) from langbot_plugin.api.entities.builtin.platform.message import Plain class Welcome(Runner): async def initialize(self): await super().initialize() @self.handler(MemberJoinedEvent) async def on_join(ctx: RunnerContext): name = ctx.platform_event.member.nickname or str(ctx.platform_event.member.id) await ctx.log(f"Member joined: {name}") if not ctx.config.get("reply_enabled", True): await ctx.log("Replies are disabled for this processor") return greeting = ctx.config.get("greeting", "Welcome aboard!") await ctx.reply(f"{name}, {greeting}") await ctx.log("Welcome action completed") @self.handler(MessageReceivedEvent) async def on_message(ctx: RunnerContext): text = "".join( item.text for item in ctx.platform_event.message_chain if isinstance(item, Plain) ).strip() if text != "/hello": await ctx.log("Message ignored: expected /hello") return if ctx.config.get("reply_enabled", True): await ctx.reply(ctx.config.get("greeting", "Welcome aboard!")) else: await ctx.log("Replies are disabled for this processor") ``` `on_join` 在成员入群时发送欢迎语,`on_message` 回复 `/hello`。关闭「发送回复」后,只记录日志。 处理函数中,`ctx.platform_event` 保存当前事件的数据,`ctx.config` 是当前处理器的配置。调用 `ctx.reply()` 回复消息,`ctx.log()` 记录日志。函数执行完毕,本次处理即结束。 ## 流式回复 使用 `ctx.reply_stream()` 更新同一条回复,`update(text)` 接收当前的完整文本: ```python async with ctx.reply_stream() as reply: await reply.update("正在处理…") await reply.update("处理完成。") ``` 正常退出 `async with` 时完成回复。平台不支持流式、未开启流式回复或当前不是消息事件时,会在结束后发送一条完整消息;发生异常时不发送缓存中的未完成文本。调试模式仅模拟发送。 此接口沿用 `ctx.reply()` 的权限。Runner 可通过 `self.get_run_api(ctx).reply_stream()` 使用同一接口,模型返回文本仍不会自动发送。 ## 事件注册 通过 `@self.handler(事件类)` 注册处理函数,并将对应事件标识加入清单的 `spec.events`。例如,`MemberJoinedEvent` 对应 `group.member_joined`。 | 事件 | 清单中的标识 | SDK 事件类 | | --- | --- | --- | | 收到消息 | `message.received` | `MessageReceivedEvent` | | 消息被编辑 | `message.edited` | `MessageEditedEvent` | | 消息被删除 | `message.deleted` | `MessageDeletedEvent` | | 消息表情回应 | `message.reaction` | `MessageReactionEvent` | | 收到反馈 | `feedback.received` | `FeedbackReceivedEvent` | | 成员加入群组 | `group.member_joined` | `MemberJoinedEvent` | | 成员离开群组 | `group.member_left` | `MemberLeftEvent` | | 成员被禁言 | `group.member_banned` | `MemberBannedEvent` | | 群组信息更新 | `group.info_updated` | `GroupInfoUpdatedEvent` | | 收到好友申请 | `friend.request_received` | `FriendRequestReceivedEvent` | | 添加好友 | `friend.added` | `FriendAddedEvent` | | 删除好友 | `friend.removed` | `FriendRemovedEvent` | | 机器人被邀请入群 | `bot.invited_to_group` | `BotInvitedToGroupEvent` | | 机器人被移出群组 | `bot.removed_from_group` | `BotRemovedFromGroupEvent` | | 机器人被禁言 | `bot.muted` | `BotMutedEvent` | | 机器人被解除禁言 | `bot.unmuted` | `BotUnmutedEvent` | | 平台自定义事件 | `platform.specific` | `PlatformSpecificEvent` | 可用事件及字段见 SDK 的 [events.py](https://github.com/langbot-app/langbot-plugin-sdk/blob/main/src/langbot_plugin/api/entities/builtin/platform/events.py)。各平台支持的事件有所不同。 ## 测试事件处理器 按[插件开发教程](/zh/plugin/dev/tutor)配置调试连接,在插件目录执行 `lbp run`。然后在 LangBot 中: 1. 创建「插件处理器」,在详情页选择「欢迎新成员」组件,填写配置并保存。 2. 在左侧选择「成员加入群组」,填写成员昵称、ID 和群组 ID,点击「运行测试」。 3. 查看回复和日志。也可以选择「收到消息」,输入 `/hello` 测试回复。 调试中的平台回复使用 Mock,不发送真实消息。修改组件 YAML 后,请重启 `lbp run`。 安装插件后,在机器人中将「成员加入群组」和「收到消息」绑定到该处理器,即可处理实际事件。 ## 接下来做什么 - 查看 [RunnerDemo](https://github.com/langbot-app/langbot-plugin-demo/tree/main/RunnerDemo) 中的更多示例。 - 如果要扩展流水线的预处理、模型调用完成等步骤,请使用[事件监听器](/zh/plugin/dev/components/event-listener)。 回复、模型、工具、历史与状态接口见[运行上下文 API](/zh/plugin/dev/apis/agent-run)。