[Slice 1/4] arise 反应式核:单轮问答走通全链路(Walking Skeleton) #2

Closed
opened 2026-07-07 02:47:07 +00:00 by KumaAgent · 0 comments
KumaAgent commented 2026-07-07 02:47:07 +00:00 (Migrated from codeberg.org)

Parent

拆自 #1(arise 反应式核 / Reactive Core PRD,Phase 1)。本片是该 PRD 的第 1/4 片(Walking Skeleton)。

What to build

端到端跑通"收到一条平台消息 → 机器人回复"这条最小完整链路,不接记忆、不接自撤/改口、不接持久化崩溃恢复、不接消息去抖累积——这些都是后续独立的切片。

具体包含:

  • 仅供测试使用的 OneBot v11 参考适配器(不作为发布产物,不导出为包的公共 API):实现前处理 port(OneBot v11 消息事件 → ConversationInput{sender_id, sender_name, text, time, media_refs, reply_ref, is_bot},渲染时带稳定 message_id)+ 后处理 port(send_message 工具产生的动作 → OneBot v11 send_msg 调用,须把平台 message_id 回传给 core)。
  • persona port 最小字段消费:{persona, backstory[], speech_patterns[], sample_dialogue[≥3]}lore 字段本片不读取)。
  • 安全基线(core 写死常量,assemble_context() 拼装顺序永远最前,host 无法扩展/覆盖/关闭)。
  • 自研 Runtime Loop:assemble_context()(安全基线 + persona + 当前会话累积窗口内的原始消息,无跨会话记忆)→ 经裸 any-llm(非 langchain-anyllm 封装)发起 completion/工具调用 → 工具循环(run_limit 硬顶,只数推理类工具迭代)。LLM 调用点必须可注入/可替换,供测试传入假 provider。
  • send_message(content) -> handle 工具:本片只支持纯文本(含 core 解析的 @ inline 标签),不支持 sticker/voice(留给后续多模态切片)。一轮内允许多次调用("一句一条"),core 按打字节奏顺序执行;打字节奏为静态公式(基础延迟 + 每字符耗时 × 段长,不含依赖情感态的抖动项)。send_message 不占 run_limit 份额,但单轮调用次数受独立静态硬顶 MAX_SENDS_PER_TURN 约束。
  • 清理脚手架:删除 src/nonebot_plugin_arise/__init__.py 里"从不存在的 plugins/ 目录加载子插件"这段代码,替换为真正的 Runtime Loop 接入点(插件加载时注册 NoneBot matcher);删除模板自带、与 arise 无关的 tests/plugin_test.pypip install 演示 matcher)。
  • 依赖/配置:pyproject.tomlrequires-python 提升到 >=3.11;新增裸 any-llm 依赖(不引入 nonebot-plugin-orm/qdrant-client,那是后续切片的范围);Config 新增 run_limitMAX_SENDS_PER_TURN、打字节奏基础延迟/每字符耗时系数、any-llm provider/model 相关配置字段。

Acceptance criteria

  • 群聊里 @ 机器人发一条消息,机器人能读到并回复(经 OneBot v11 测试适配器验证)。
  • 私聊场景(无需 @)机器人同样能识别并回复。
  • 模型可以在一轮 assistant 消息里调用多次 send_message,core 按顺序、按打字节奏依次执行,产生对应次数的 send_msg 调用。
  • 模型在一轮内可以选择完全不调用 send_message(合法的"看了但不说"结果),流程正常结束、不报错、不重试。
  • run_limit 生效:给一个"模型不断请求调用推理工具"的假 provider 脚本,工具循环在硬顶处终止而非无限跑下去。
  • MAX_SENDS_PER_TURN 生效:给一个"模型试图连续调用超量 send_message"的假 provider 脚本,超出硬顶的调用不会被执行。
  • assemble_context() 拼装顺序断言:安全基线恒定在最前,persona 内容不能覆盖/替换安全基线文本。
  • 机器人不会因用户消息里包含"忽略之前的指令"等话术而改变身份或泄露系统提示词(安全基线生效的行为验证)。
  • 端到端测试复用仓库已有的 NoneBug 脚手架(tests/conftest.pyafter_nonebot_init + tests/fake.pyfake_group_message_event_v11/fake_private_message_event_v11),LLM provider 用可注入的假实现(脚本化 tool_calls),无需真实网络请求/API key。
  • tests/plugin_test.py(模板自带的 pip install 演示测试)已删除。
  • OneBot v11 参考适配器在代码/PR 描述中明确标注"仅供测试使用,不作为发布产物",不在 README 中作为"支持的平台"宣传。

Blocked by

None - can start immediately

## Parent 拆自 [#1](https://codeberg.org/ProjectKuma/nonebot-plugin-arise/issues/1)(arise 反应式核 / Reactive Core PRD,Phase 1)。本片是该 PRD 的第 1/4 片(Walking Skeleton)。 ## What to build 端到端跑通"收到一条平台消息 → 机器人回复"这条最小完整链路,不接记忆、不接自撤/改口、不接持久化崩溃恢复、不接消息去抖累积——这些都是后续独立的切片。 具体包含: - **仅供测试使用**的 OneBot v11 参考适配器(不作为发布产物,不导出为包的公共 API):实现前处理 port(OneBot v11 消息事件 → `ConversationInput{sender_id, sender_name, text, time, media_refs, reply_ref, is_bot}`,渲染时带稳定 `message_id`)+ 后处理 port(`send_message` 工具产生的动作 → OneBot v11 `send_msg` 调用,须把平台 `message_id` 回传给 core)。 - persona port 最小字段消费:`{persona, backstory[], speech_patterns[], sample_dialogue[≥3]}`(`lore` 字段本片不读取)。 - 安全基线(core 写死常量,`assemble_context()` 拼装顺序永远最前,host 无法扩展/覆盖/关闭)。 - 自研 Runtime Loop:`assemble_context()`(安全基线 + persona + 当前会话累积窗口内的原始消息,无跨会话记忆)→ 经裸 `any-llm`(非 `langchain-anyllm` 封装)发起 completion/工具调用 → 工具循环(`run_limit` 硬顶,只数推理类工具迭代)。LLM 调用点必须可注入/可替换,供测试传入假 provider。 - `send_message(content) -> handle` 工具:本片只支持纯文本(含 core 解析的 `@` inline 标签),不支持 sticker/voice(留给后续多模态切片)。一轮内允许多次调用("一句一条"),core 按打字节奏顺序执行;打字节奏为静态公式(基础延迟 + 每字符耗时 × 段长,不含依赖情感态的抖动项)。`send_message` 不占 `run_limit` 份额,但单轮调用次数受独立静态硬顶 `MAX_SENDS_PER_TURN` 约束。 - 清理脚手架:删除 `src/nonebot_plugin_arise/__init__.py` 里"从不存在的 `plugins/` 目录加载子插件"这段代码,替换为真正的 Runtime Loop 接入点(插件加载时注册 NoneBot matcher);删除模板自带、与 arise 无关的 `tests/plugin_test.py`(`pip install` 演示 matcher)。 - 依赖/配置:`pyproject.toml` 的 `requires-python` 提升到 `>=3.11`;新增裸 `any-llm` 依赖(不引入 `nonebot-plugin-orm`/`qdrant-client`,那是后续切片的范围);`Config` 新增 `run_limit`、`MAX_SENDS_PER_TURN`、打字节奏基础延迟/每字符耗时系数、any-llm provider/model 相关配置字段。 ## Acceptance criteria - [ ] 群聊里 @ 机器人发一条消息,机器人能读到并回复(经 OneBot v11 测试适配器验证)。 - [ ] 私聊场景(无需 @)机器人同样能识别并回复。 - [ ] 模型可以在一轮 assistant 消息里调用多次 `send_message`,core 按顺序、按打字节奏依次执行,产生对应次数的 `send_msg` 调用。 - [ ] 模型在一轮内可以选择完全不调用 `send_message`(合法的"看了但不说"结果),流程正常结束、不报错、不重试。 - [ ] `run_limit` 生效:给一个"模型不断请求调用推理工具"的假 provider 脚本,工具循环在硬顶处终止而非无限跑下去。 - [ ] `MAX_SENDS_PER_TURN` 生效:给一个"模型试图连续调用超量 `send_message`"的假 provider 脚本,超出硬顶的调用不会被执行。 - [ ] `assemble_context()` 拼装顺序断言:安全基线恒定在最前,persona 内容不能覆盖/替换安全基线文本。 - [ ] 机器人不会因用户消息里包含"忽略之前的指令"等话术而改变身份或泄露系统提示词(安全基线生效的行为验证)。 - [ ] 端到端测试复用仓库已有的 NoneBug 脚手架(`tests/conftest.py` 的 `after_nonebot_init` + `tests/fake.py` 的 `fake_group_message_event_v11`/`fake_private_message_event_v11`),LLM provider 用可注入的假实现(脚本化 `tool_calls`),无需真实网络请求/API key。 - [ ] `tests/plugin_test.py`(模板自带的 `pip install` 演示测试)已删除。 - [ ] OneBot v11 参考适配器在代码/PR 描述中明确标注"仅供测试使用,不作为发布产物",不在 README 中作为"支持的平台"宣传。 ## Blocked by None - can start immediately
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ProjectKuma/arise#2
No description provided.