fix: 模板 agent 首次对话即按预置身份作答 - #235
Conversation
从专家模板新建 agent 后,第一次对话问"你是谁"会答"还是一片空白",尽管模板已带身份。 根因:harness 的 BootstrapMiddleware 在无 .bootstrapped 标记时,把首条消息的整条 system prompt 替换为 BOOTSTRAP.md("记忆是空的,一切从零开始"),吞掉模板预置的身份(SOUL.md/IDENTITY.md)。直到第一条回复落盘后 middleware 才补写标记,所以第二条消息才有身份。 修复:_seed_expert_template 改为返回 seed 文件数,create() 在模板 seed 成功(>0)后写入 .bootstrapped 标记,模板 agent 跳过 blank onboarding,首条消息即按所赋身份作答。标记写入失败时只记日志并退回原 bootstrap 流程,不影响 agent 创建。自定义(无模板)agent 仍保留原 onboarding 流程。
|
这个作用是啥?怎么判断是否开启bootstrap? |
|
@jubaoliang 作用是修 bug:从 expert 模板新建的 agent,第一次对话答"我还是一片空白",尽管模板已带身份(SOUL.md 等)。 根因:harness 的 BootstrapMiddleware 在无 .bootstrapped 标记时,会用 BOOTSTRAP.md("记忆是空的,一切从零开始")覆盖整条 system prompt;同时 _build_harness_config 在无标记时也把 system_prompt 置空。于是模板身份首条消息完全进不了上下文,要等第一条回复后才补写标记,身份从第二条消息才生效。 修复:模板 agent 身份是创建时预置的,与"空白 onboarding"冲突,所以在 seed 成功后提前写标记 → 跳过空白仪式,首条消息即按身份作答。无模板 agent 不受影响,仍走原流程。 怎么判断是否开启 bootstrap Octop 的 bootstrap_enabled 硬编码为 True(manager.py:1960),middleware 对所有 agent 都挂,没有用户开关。 |
|
@jubaoliang |

模板 agent 首次对话即按预置身份作答,不再回答"我还是一片空白":此前 bootstrap 仪式会把首条消息的 system prompt 整体替换为 BOOTSTRAP.md,吞掉模板预置的身份;现在模板文件 seed 成功后即写入
.bootstrapped完成标记,agent 从第一条消息起就以所赋身份作答。BootstrapMiddleware在 agent 工作区无.bootstrapped标记时,把整条 system prompt 替换为 BOOTSTRAP.md("记忆是空的,一切从零开始");Octop_build_harness_config在无标记时设system_prompt=None, memory=(),模板预置的 SOUL.md/IDENTITY.md 首条消息不进上下文,直到第一条回复落盘后 middleware 才补写标记create()在模板文件 seed 成功(>0)后即写入.bootstrapped标记,跳过 blank onboarding_seed_expert_template改为返回 seed 文件数;无模板的自定义 agent 仍走原 onboarding 流程,行为不变_build_harness_config正确加载身份Summary
从专家模板新建 agent 后,第一次对话问"你是谁"会回答"我现在还是一片空白",尽管模板早已预置了身份。根因在 harness 的
BootstrapMiddleware(harness_agent/middleware/bootstrap.py):is_bootstrapped()(工作区.bootstrapped标记存在)为 False 时,把首条消息的整条 system prompt 替换为 BOOTSTRAP.md;而 Octop_build_harness_config(src/octop/infra/agents/manager.py)在无标记时设system_prompt=None, memory=(),模板预置的身份文件(SOUL.md 等)首条消息完全不进上下文,直到第一条回复落盘后 middleware 才写.bootstrapped(_has_final_reply对任意非空最终回复都判定完成),于是第二条消息起才有身份。本次改动让模板 agent 在创建时就拿到标记:
_seed_expert_template改为返回 seed 文件数,create()在template_name且 seed 成功(>0)后调用_mark_template_bootstrapped写入.bootstrapped。模板 agent 从此跳过 blank onboarding,首条消息即按所赋身份作答;标记写入失败只记日志、退回原流程,不影响 agent 创建。无模板的自定义 agent 完全不受影响,仍走原 onboarding。修复前(模板 agent 首次对话回答"还是一片空白"):
修复后(模板 agent 首次对话即按预置身份作答):
Target branch
develop(feature / fix — default)main(release/*orhotfix/*only)Type of change
Test plan
后端单测(本次新增 create() 标记正反用例 + build_harness_config 身份加载断言)
uv run pytest tests/unit/agents/test_agent_registry.py tests/unit/agents/test_agent_manager.py -q
agents + api 全量单测(本机 Windows)
uv run pytest tests/unit/agents tests/unit/api -q
结果:411 passed / 14 skipped / 1 failed(test_reasoning_middleware 为与本 PR 无关的既有失败:langchain-anthropic 版本
.effort字段不兼容,已在干净树上复现)静态检查
uv run ruff check src/octop/infra/agents/manager.py tests/unit/agents
说明:手动端到端已验证——从专家模板创建 agent → 首次 WebSocket 对话问"你是谁" → 即按所赋身份作答("我擅长:系统资源诊断 / …"),不再答"还是一片空白"。
make allpasses locallyChecklist
CHANGELOG.md(if user-facing)