Skip to content

[Feature]: 自定义智能体创建:工具选择交互、工具不可自定义与定义文件一致性问题汇总 #3822

Open

Description

@Raing5Days

环境

OpenBitFun 1.0.9(D:/OpenBitFun 安装版),Windows 11 家庭版。代码看的是 main@cf4a5443b。

怎么用上的、卡在哪

自定义智能体现在是"一个 md 文件就是一份定义":放 %APPDATA%/openbitfun/agents/(用户级,mode 和 subagent 都行),或者 <workspace>/.openbitfun/agents/(项目级,只能放 subagent)。正文写提示词,front matter 写 kind / id / tools / readonly / review / model / user_context_policy。建的时候要么走智能体页面那个三步向导,要么直接在对话里说需求,让内置的 create-agent 帮你落文件。

我两条路都试了。提示词那步挺顺,卡在工具上:想给一个子代理配"读文件 + 搜网页"这么一组,得在一屏平铺的按钮里一个个找,中途改主意还得退出向导重进。下面按交互、能不能自定义、文件和运行时谁说了算、文件加载的边角分四块,代码位置都贴了。

一、工具选择这块太绕

  1. 向导里的工具面板把分组弄丢了。CreateAgentPage.tsx:822-832 传了 grouped={false},组件就走 flattenToolGroups(ToolGroupPicker.tsx:91-95、:458-466),分组标题、组内计数、"本组全选 / 清空组"全没了,剩一屏 pill 让你一个个点。同一个组件在详情面板里 grouped 默认是 true(AgentsScene.tsx:1151),两处体验不一样。

  2. 没有搜索。ToolGroupPicker.tsx 整个文件里没有搜索框,组的编辑器 GroupManagerModal(:147-440)也是全量平铺一遍;SkillGroupPicker.tsx 同样没有。工具一多只能滚。

  3. **子代理的工具只能回编辑页改。**详情面板的工具区被 isPrimaryAgent 挡着(AgentsScene.tsx:1145-1168),而它只认 agentKind 是 harness / agent(agentVisibility.ts:22-24)。所以子代理在详情里只能看摘要,动一个工具就得退回三步向导。

  4. **用户工具组是全局一份。**存在 app.user_tool_groups(toolGroups.ts:6),所有 agent 共用同一套组和同一顺序(useUserToolGroups.ts:49-54)。想给某个 agent 单独存一套组合做不到,也没法把现有 agent 的工具集"另存为组",只能在新建组里重新勾一遍。

  5. 建不出"一个工具都不给"的 agent。CreateAgentPage.tsx:476 空选择时发 tools: undefined,后端 create_custom_agent 又 unwrap_or_else(default_custom_agent_tools)(custom_agent_api.rs:216-230)。代码里自己也写了(CreateAgentPage.tsx:457):空选择会走宿主默认,可能带上可写工具。可 schema 明明是支持 tools: [] 的(custom_agent.rs:64、:176-177)。

  6. 默认 id 跟名字没关系。createSuggestedAgentId 给的是 agent-<uuid8>(suggestAgentId.ts:2-7),而文件名就是 id(custom_agent_api.rs:210),一般都得手动改;create-agent 的 SKILL.md 里要求的反倒是从名字派生 kebab-case。

二、工具其实没法自定义

  1. MCP 工具进不了 agent 的工具范围。agentToolVisibility.ts:4-6 是 isUserSelectableToolName(name) && !isMcpToolName(name),创建页(CreateAgentPage.tsx:358-362、:374-385)和详情面板(AgentsScene.tsx:341-343)都用它过滤。MCP / 插件是现在唯一的"自定义工具"入口,结果自定义 agent 和子代理一个都挂不上,只能在会话里全局开。希望能按 agent 选 mcp__server__tool,默认折叠或者要显式打开都行,至少让子代理能拿到只读的那几个。

  2. **定义里没法声明自定义工具。**挂不了脚本 / HTTP / 组合工具,也没有 per-agent 的参数、别名、权限预设。想让 agent 干一件现成工具没有的事,只能写进提示词让它自己拼 ExecCommand。

  3. Skills 不在定义文件里。create-agent/SKILL.md:55 写得很明确,Skill 选择不是文件字段,实际存在 replaceModeSkillSelection(useAgentsList.ts:490-506)。结果一份 md 搬不走:提示词和工具能带走,Skills 留在配置里。

三、文件和运行时各说各话

  1. **工具存了两处,界面改的是配置那处。**界面里改工具走 saveModeConfig → setAgentProfileConfig({ enabled_tools })(useAgentsList.ts:437-457),读的时候是 enabled_tools ?? agent.defaultTools(AgentsScene.tsx:332-336、useAgentsList.ts:404-425)。只要在界面动过一次,md 里的 tools 就不生效了,只有点"重置"(AgentsScene.tsx:1052 → resetAgentProfileConfig)才回落。UI 上没一个字提示,我一开始以为改的就是文件。要么回写 md,要么在工具区标一句"已覆盖文件里的设置"。

  2. **三处默认工具集对不上。**后端 custom_agent.rs:11-33 是 21 个;前端 CreateAgentPage.tsx:44-64 是 19 个,少了 AgentList 和 ListModels;create-agent/SKILL.md:61 是 20 个,少了 AgentList。不只是少一个工具的问题:tools_are_default 要求跟后端默认集逐项相等(custom_agent.rs:323-330),所以向导建出来的每个 mode 都会显式写一份 tools,以后默认集变了它也吃不到;反倒是手写、或者干脆省略 tools 的 mode 能拿到含 AgentList 的那套。

  3. **模型没有统一入口。**创建 / 编辑页压根没有模型字段,i18n 里 agentsOverview.form.model、.modelPlaceholder、.modelRequired 三个键没人引用;子代理的模型只能在详情面板改(AgentsScene.tsx:1129-1143,还限定 agentKind === 'subagent');自定义 mode 的 model 在 UI 里没有任何入口,只能去改文件。

  4. memory_summary 后端支持、界面上没有。VISIBLE_CONTEXT_SECTIONS 只有 workspace_context / workspace_instructions / project_layout(CreateAgentPage.tsx:66-70),但解析和保存都支持 memory_summary(custom_agent.rs:688-698、:762-786)。

  5. **工具名写错会被静默丢掉。**加载时 validate_custom_agent_definition 直接把不认识的名字过滤掉(custom_agent.rs:440-459),只留一条 warn!(registry/custom.rs:263-268)。手写文件错一个字母,agent 就悄悄少一个能力,界面上看不出来。

  6. 加载侧不校验 id 格式。from_front_matter_fields 只做 trim 判空(custom_agent.rs:169-174),创建接口却要求 ^[a-zA-Z][a-zA-Z0-9_-]*$(custom_agent_api.rs:13、:31-43);文件名和 id 也不强制一致,会出现文件叫 a.md、注册成 b 的情况。

四、文件加载的边角

  1. **agents/ 下的子目录不加载,但监听是递归的。**加载用 read_dir 只取直接文件(custom_agent.rs:493-506),监听却是 watch_config(true) 加父目录浅监听(custom_watch.rs:71、:118-127)。把 agent 按用途分文件夹放,就永远不出现,也没有任何提示,很容易当成 bug。

  2. **UTF-8 BOM 会让整个文件解析失败。**front matter 那把正则 (?s)^---\r?\n(.*?)\r?\n--- 从第 0 字节就要 ---(custom_agent.rs:557-562),而 read_to_string 不剥 BOM;记事本、PowerShell 的 Set-Content -Encoding UTF8 默认都写 BOM,于是报 Failed to capture content,整份跳过。读入后 trim 掉 \u{feff} 就行,顺手补个单测。这条我没在界面里实测,是读代码看出来的,可能要确认一下。

五、零碎的

  1. review: true 的子代理要求至少一个只读工具(CreateAgentPage.tsx:458-461),零工具的评审 agent 建不出来。
  2. 项目级不支持自定义 mode(custom_agent_api.rs:177-179),只支持子代理;但界面把类型和级别放同一页,文案又说"用户级可跨项目复用",容易读成 mode 也能项目级。
  3. 删除 agent 只清了 agent_profiles[agent_id](custom_agent_api.rs:425-434),别的 mode profile 的 subagent_overrides 里可能还留着它的 key。
  4. 对话式创建依赖 scripts/validate_agent.py,要 PyYAML;缺依赖时给的提示不够清楚。

希望变成什么样

  • 工具选择:分组 + 搜索 + 组内全选 + "从现有 agent 另存为组",子代理的工具在详情面板就能改。
  • 允许工具集为空,允许挂 MCP 工具(至少只读的)。
  • md 当唯一事实来源,界面编辑回写文件,或者明确标出配置覆盖;三处默认集对齐,把 AgentList / ListModels 补上。
  • 模型、Skills、运行时上下文收到同一张表单里,让一份定义能整体搬走。
  • 加载侧支持子目录、容忍 BOM,非法 id 和非法工具名给个看得见的提示。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions