From e83da37120788effeeb79a453c729f7a536978db Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Thu, 21 May 2026 19:32:43 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=B8=8E=E9=87=8D=E6=9E=84=E8=BF=BD=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - REFACTOR.md: 更新 check list 状态(multi-hop qa 已完成) - agents-config/sandbox-architecture/skills-management: 适配命名变更 - roadmap: 更新进度记录 --- REFACTOR.md | 6 ++++-- docs/agents/agents-config.md | 21 +++++++++++++-------- docs/agents/sandbox-architecture.md | 4 ++-- docs/agents/skills-management.md | 12 ++++++------ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/REFACTOR.md b/REFACTOR.md index 0639bad7..5f65de81 100644 --- a/REFACTOR.md +++ b/REFACTOR.md @@ -24,9 +24,11 @@ - [ ] 权限新增一个 guest 的预设字段,暂无任何权限 - [ ] rename database table name, such as skills -> agent_skills, subagents -> agent_subagents, mcp, tool_call, 等等 - [x] department 的 id 也不能使用那个索引的 id 来使用了,应该是一个独立的 dept_id,需要确认 -- [ ] allow user config skill +- [ ] allow user config skill, and envs +- [ ] add model retry times to agent context config +- [ ] add user envs when load sandbox - [ ] Config spacy model 的 load -- [ ] allow multi-hop qa generate +- [x] allow multi-hop qa generate - [x] 在工作区的文件编辑的时候,保存和取消的按钮应该是悬浮在编辑框的右上角,而不是在 header 上面 - [x] default enable all build in tools / kbs / skills / mcps / subagents - [x] 链接 Notion 和 feishu 目前来看,都是支持的 diff --git a/docs/agents/agents-config.md b/docs/agents/agents-config.md index 26b9cc15..bedfb37e 100644 --- a/docs/agents/agents-config.md +++ b/docs/agents/agents-config.md @@ -221,9 +221,15 @@ config_json.context + runtime ids -> context_schema instance 因此 Graph 不是和 Context 解耦的。相反,Graph 的构造本身就依赖 Context。 -### 4.4 中间件运行阶段 +### 4.4 Graph 构建与中间件运行阶段 -中间件通过 `request.runtime.context` 或 `runtime.context` 继续读取和修改 Context。 +`get_graph()` 创建 LangGraph 前会先调用 `prepare_agent_runtime_context`,用当前用户重新过滤资源字段,并派生运行时字段: + +- `_visible_knowledge_bases`:当前会话实际可查询的知识库对象 +- `_prompt_skills`:需要注入提示词的 Skill 闭包 +- `_readable_skills`:`/home/gem/skills` 和沙盒可读的 Skill 闭包 + +中间件通过 `request.runtime.context` 或 `runtime.context` 继续读取这些结果。 例如: @@ -231,15 +237,14 @@ config_json.context + runtime ids -> context_schema instance - 读取 `model`、`system_prompt`、`tools`、`mcps` - 动态覆盖模型、系统提示词和工具列表 - `SkillsMiddleware` - - 读取 `skills` - - 计算可见技能闭包 - - 将 skills 提示段注入 `system_prompt` - - 在运行期回写 `_visible_skills` + - 读取 `_prompt_skills` 注入 skills 提示段 + - 读取 `_readable_skills` 校验可激活 Skill + - 根据 `activated_skills` 按需挂载工具和 MCP 依赖 - 文件系统与沙盒接入 - 通过 `thread_id` 获取对应沙盒 - - 通过 `skills` 决定 `/home/gem/skills` 的可见范围 + - 通过 `_readable_skills` 决定 `/home/gem/skills` 的可读范围 -所以 Context 既是输入配置,也是中间件共享的运行时状态载体。 +所以 Context 既是输入配置,也是 Graph 创建前整理出的运行时资源上下文。 ### 4.5 文件系统与 Viewer 阶段 diff --git a/docs/agents/sandbox-architecture.md b/docs/agents/sandbox-architecture.md index 15532c99..0642c7fa 100644 --- a/docs/agents/sandbox-architecture.md +++ b/docs/agents/sandbox-architecture.md @@ -147,13 +147,13 @@ Yuxi 不会把整个容器文件系统都开放给 Agent 或 viewer。当前 vie `/home/gem/user-data` 是主要工作区。它允许模型和工具写入,但推荐语义并不相同。内置 prompt 中已经明确说明,`workspace` 应当放中间文件,`outputs` 应当放最终产物,`uploads` 是用户上传文件的位置。对于普通对话 Agent,文案甚至提示“非必要不要写 workspace,而优先写 outputs”。 -`/home/gem/skills` 是只读目录。它不是简单地把 `saves/skills` 整个暴露进去,而是先根据当前线程可见的 skill 列表,把这些技能从全局 skills 根目录同步复制到 `saves/threads//skills`,再把这个线程目录只读挂进沙盒。这样做的结果是,不同线程看到的 skill 集可能不同,而且模型永远不能在运行时修改 skills 内容。 +`/home/gem/skills` 是只读目录。它不是简单地把 `saves/skills` 整个暴露进去,而是先根据当前线程的 `_readable_skills`,把这些技能从全局 skills 根目录同步复制到 `saves/threads//skills`,再把这个线程目录只读挂进沙盒。这样做的结果是,不同线程看到的 skill 集可能不同,而且模型永远不能在运行时修改 skills 内容。 知识库访问不属于沙盒文件系统暴露规则。当前 Agent 可见知识库仍由用户权限和 Agent 配置共同决定,但只通过 `query_kb`、`open_kb_document` 等工具访问,不提供沙盒目录投影。 ## 十、skills、知识库、附件是怎么和沙盒结合的 -skills 的结合方式分成两层。第一层是提示词层,`SkillsMiddleware` 会把当前线程配置的 skill 列表和依赖闭包注入到系统提示里,让模型知道哪些 skill 存在、它们的入口文件一般在 `/home/gem/skills//SKILL.md`。第二层是文件系统层,运行时会调用 `sync_thread_visible_skills`,把当前线程真正可见的 skill 目录复制到线程自己的 `saves/threads//skills` 下,再由沙盒只读挂载到 `/home/gem/skills`。也就是说,skill 既是 prompt 中的能力说明,也是文件系统中的只读知识目录。 +skills 的结合方式分成两层。第一层是提示词层,`prepare_agent_runtime_context` 会先根据当前线程配置的 `context.skills` 展开依赖闭包,`SkillsMiddleware` 再把 `_prompt_skills` 注入到系统提示里,让模型知道哪些 skill 存在、它们的入口文件一般在 `/home/gem/skills//SKILL.md`。第二层是文件系统层,运行时会调用 `sync_thread_readable_skills`,把 `_readable_skills` 对应的 skill 目录复制到线程自己的 `saves/threads//skills` 下,再由沙盒只读挂载到 `/home/gem/skills`。也就是说,skill 既是 prompt 中的能力说明,也是文件系统中的只读知识目录。 附件的结合方式更偏向“先落盘,再把路径告诉模型”。用户上传文件后,系统会先把原始文件写入 `saves/threads//user-data/uploads`。如果该文件可以被解析,系统还会额外生成一个 Markdown 副本,写到 `saves/threads//user-data/uploads/attachments/.md`。随后,LangGraph state 中会维护一份 `uploads` 列表,`AttachmentMiddleware` 会把这些可读路径注入系统提示,告诉模型优先用 `read_file` 去读取这些路径。因此,附件并不是“作为消息大段内联塞给模型”,而是被转换成沙盒文件系统中的路径对象。 diff --git a/docs/agents/skills-management.md b/docs/agents/skills-management.md index 79979373..5ebb29c0 100644 --- a/docs/agents/skills-management.md +++ b/docs/agents/skills-management.md @@ -160,11 +160,11 @@ Skills 之间可以建立依赖关系,形成一个松耦合的技能网络。 **阶段一:会话启动** 当 Agent 会话启动时,系统会: -1. 读取 Agent 配置中的 `context.skills` 列表 -2. 递归展开 `skill_dependencies`,构建完整的可见技能集(`visible_skills`) -3. 将可见技能列表注入到系统提示词中 +1. 在创建 Graph 前读取已过滤的 `context.skills` 列表 +2. 递归展开 `skill_dependencies`,派生 `_prompt_skills` 和 `_readable_skills` +3. 将 `_prompt_skills` 对应的技能说明注入到系统提示词中 -这意味着:只要配置了某个 Skill,它的依赖 Skill 就会立即对 Agent 可见。 +这意味着:只要配置了某个 Skill,它的依赖 Skill 就会立即进入提示词和 `/home/gem/skills` 只读范围。 **阶段二:技能激活** @@ -191,8 +191,8 @@ Skills 之间可以建立依赖关系,形成一个松耦合的技能网络。 - **pro-skill**:依赖 `advanced-skill` 当在 Agent 配置中只选择 `pro-skill` 时: -1. 启动阶段:`visible_skills` = [`pro-skill`, `advanced-skill`, `base-skill`](自动展开依赖链) -2. Agent 首次调用任何 skill 时:所有三个 Skill 都可见 +1. 启动阶段:`_readable_skills` = [`pro-skill`, `advanced-skill`, `base-skill`](自动展开依赖链) +2. Agent 首次调用任何 skill 时:所有三个 Skill 都可读 3. 当 Agent 读取 `pro-skill/SKILL.md` 时:触发激活,工具和 MCP 依赖被加载 ## 权限管理