Agent Scope Java 2.x 系列【16】Harness:工作区(Workspace)

📅 2026/6/15 23:17:02
Agent Scope Java 2.x 系列【16】Harness:工作区(Workspace)
文章目录1. 概述1.1 设计理念1.2 四大核心设计原则1.2.1 智能体定义与进化的唯一可信源1.2.2 文件按生命周期分层隔离存储1.2.3 原生多租户数据隔离1.2.4 工作区与文件存储层解耦2. 工作区目录2.1 工作区逻辑目录布局2.2 存储兼容特性2.3 自动生成规则2.4 写入工作区安全规范2.4.1 路径入参安全校验规则2.4.2 文件写入标准调用方式3. 入门案例3.1 构建 HarnessAgent3.2 编写 AGENTS.md3.3 按需关闭子系统4. 重点目录4.1 skills/ — 可复用技能包4.2 subagents/ — 子 Agent 声明4.3 tools.json — 工具白名单与 MCP 配置4.4 plans/ — 计划文件4.5 agents/agentId/ — 运行时数据4.6 knowledge/ — 领域知识库1. 概述1.1 设计理念工作区Workspace是HarnessAgent智能体定义与自我进化的唯一可信源source of truth。核心特性智能体身份定位、行为规则、迭代学习成果全部通过目录结构Markdown/JSON普通文件承载配置不硬编码嵌入业务代码、不强制绑定数据库表文件即配置、文件即资产、文件即演化记录。1.2 四大核心设计原则1.2.1 智能体定义与进化的唯一可信源所有智能体基础配置它是谁、怎么行事均可在工作区目录中以文件形式定义全部配置项均为可选配置内容存储文件路径人设、行为约束、系统提示词AGENTS.md私有领域知识库、参考附件knowledge/KNOWLEDGE.md 配套资源文件可复用技能能力包skills/技能名/SKILL.md内嵌子智能体配置subagents/子AgentID.md工具调用白名单、MCP服务配置tools.json双向等价适配文件配置与代码API配置完全对等代码可通过链式构建方法systemPrompt()、skill()、subagent()、toolsConfig()传入一模一样的配置参数两种方式可自由切换、混用。原生多租户能力文件化定义核心价值同一套Agent业务代码逻辑无需分支改造、无需多环境部署仅新增用户专属覆盖目录即可为不同用户分配独立人设、知识库、技能集合快速实现千人千面定制。智能体运行过程中跨会话学习、沉淀的内容由框架后台自动写入工作区无需开发者手动维护生命周期长期记忆MEMORY.mdmemory/分片文件后台任务自动从对话抽取事实、压缩降噪每轮推理自动注入系统提示词。自学习技能存储于skills/目录Agent从成功执行案例中自主生成技能草稿可配置人工审批闸门审批通过后转为正式复用技能后台托管过期技能老化归档。任务计划文件存放于plans/规划模式Plan Mode下生成的执行计划持久保存、跨调用复用实现思考环节与执行环节解耦。大体积工具输出压缩落盘超长工具返回内容写入磁盘上下文仅保留首尾预览片段文件读取指针Agent可按需重读完整内容避免上下文窗口溢出。全量会话日志路径agents/agentId/sessions/原始对话完整追加存储永不自动压缩删除支持全量溯源排查。进化数据默认长期留存记忆持续累积、日志只增不删各模块生命周期维护规则可单独配置调控关键区分瞬时运行上下文AgentState不属于工作区AgentState是单次对话中途的易失快照对话缓冲、滚动摘要、权限、任务、计划元数据等独立存储在AgentStateStore和工作区文件树物理隔离。1.2.2 文件按生命周期分层隔离存储工作区同一目录树内内部区分三条独立读写链路三类数据互不干扰类型写入方读取方典型文件示例静态资产研发/运维人工编辑框架每轮推理注入、按需加载AGENTS.md、knowledge/、skills/、subagents/、tools.json运行时产物框架/Agent自动写入下次调用自动还原加载agents//sessions/、agents//tasks/、plans/长期累积记忆Agent推理后台托管任务每轮注入提示词、Agent工具查询MEMORY.md、memory/日期分片文件目录统一打包仅为部署便捷性复制整个目录即可迁移一套完整Agent底层读写逻辑完全分离。1.2.3 原生多租户数据隔离依靠单一隔离域IsolationScope对工作区文件、存储数据分桶隔离业务层无需手写分区、过滤逻辑隔离域定义数据共享边界IsolationScope 枚举数据共享范围适用场景SESSION单个会话完全独立隔离一次性临时沙箱、单次任务隔离USER默认同一用户ID下全部会话互通记忆、技能普通C端用户多端会话同步学习无userId时自动降级为SESSIONAGENT该Agent实例下所有用户共用一套知识库标准化公共知识库型智能体GLOBAL全局所有Agent、用户共用同一个存储桶谨慎使用多实例资源竞争风险高注意事项不同存储介质下隔离落地形态不同本地磁盘为路径前缀、共享KV为命名空间、容器沙箱为独立状态槽位AgentState拥有一套正交寻址逻辑不受IsolationScope影响始终以(userId, sessionId)作为唯一存储键存入独立AgentStateStore单HarnessAgent实例可支撑数千并发用户租户之间数据物理隔离、零泄露。1.2.4 工作区与文件存储层解耦同一套标准目录结构可无缝对接三类存储载体切换部署形态无需修改Agent业务代码本地本机磁盘文件系统分布式共享KV存储Redis、JDBC数据库隔离沙箱容器内部文件系统这一解耦设计是实现一套代码、多形态部署单机/集群/容器沙箱的底层核心支撑。2. 工作区目录2.1 工作区逻辑目录布局标准逻辑根路径.agentscope/workspace/说明该路径仅为本地磁盘默认物理位置属于逻辑目录规范存储载体可无缝切换相对路径结构全程保持不变。.agentscope/workspace/ ├── AGENTS.md # 静态资产智能体人设、系统指令、行为约束规则 ├── MEMORY.md # 长期记忆汇总提炼后的全局事实摘要 ├── tools.json # 静态资产MCP服务配置、工具调用白名单可选配置 ├── memory/ # 长期记忆按日期拆分的原始记忆流水 │ └── YYYY-MM-DD.md ├── knowledge/ # 静态资产专属领域知识库与附件资源 │ ├── KNOWLEDGE.md │ └── 各类参考文档/素材文件 ├── skills/ # 静态资产可复用技能包一个技能对应一个子目录 │ └── skill-name/SKILL.md ├── subagents/ # 静态资产子智能体配置文件名等于子Agent唯一ID │ └── agent-id.md ├── plans/ # 运行时产物规划模式持久化执行方案 │ └── PLAN.md └── agents/agentId/ # 运行时根目录单个智能体专属运行数据 ├── sessions/ # 运行时产物全量会话日志与会话索引 │ ├── sessions.json │ └── sessionId.log.jsonl # 完整原始对话日志永久追加不压缩 └── tasks/ # 运行时产物后台异步任务、子任务执行记录 └── sessionId.json2.2 存储兼容特性布局为逻辑统一规范不绑定物理存储介质本地部署直接映射服务器本机磁盘目录分布式集群依托RemoteFilesystemSpec对接Redis、JDBC、对象存储OSS安全隔离场景通过SandboxFilesystemSpec完整映射至容器沙箱内部所有文件相对路径在三种存储模式下完全对齐切换存储后端无需修改Agent业务代码存储切换统一由框架filesystem配置项控制全文档配置、读写逻辑均基于此套标准逻辑布局实现。2.3 自动生成规则AGENTS.md核心手动文件仅此文件需要人工编写属于非强制文件缺失时Agent可正常运行只是不会注入人设、行为约束、系统提示词。tools.json可选手动配置文件MCP服务、工具白名单配置按需手动新建不创建则无工具权限约束、未接入MCP。其余目录/文件由框架按需自动创建触发条件自动生成资源代码配置记忆压缩.compaction(...)MEMORY.md、memory/日期分片目录注入子Agent配置 Subagent Specsubagents/子智能体配置目录加载自定义技能包skills/技能存放目录开启规划模式 Plan Modeplans/持久化计划目录执行任意一次call()调用任务agents/agentId/运行时根目录内含sessions、tasks2.4 写入工作区安全规范2.4.1 路径入参安全校验规则additionalContextFile、writeUtf8WorkspaceRelative、memory_get等读写接口统一接收工作区相对路径框架内置路径穿越防护校验拦截../../、../等向上跳转路径写法禁止访问工作区目录树以外的宿主系统文件如/etc/passwd、系统配置、宿主业务文件等所有文件读写操作被约束在当前隔离域工作区逻辑目录内。2.4.2 文件写入标准调用方式写入、修改、读取工作区文件必须通过HarnessAgent#getWorkspaceManager()获取管理器操作。禁止直接使用原生java.nio.Files原因沙箱部署模式java.nio.Files会写入宿主机磁盘而非容器隔离沙箱内部工作区分布式共享存储Redis/JDBC/OSS模式原生文件API无法操作KV/对象存储会直接落盘本地磁盘数据存储错位、多实例数据不一致。唯一豁免场景: 仅框架Builder装配初始化阶段可使用原生文件API允许使用java.nio.Files典型场景initWorkspaceIfAbsent初始化种子文件自动生成基础AGENTS.md模板阶段特征尚未生成完整运行时上下文、未初始化WorkspaceManager实例设计目的仅用于本地模板资源落地不属于Agent运行期业务读写逻辑。3. 入门案例3.1 构建 HarnessAgent最简构建指定工作区路径即可运行。不传workspace则默认${user.dir}/.agentscope/workspace。HarnessAgentagentHarnessAgent.builder().name(MyAgent).model(model).workspace(Paths.get(.agentscope/workspace)).additionalContextFile(SOUL.md)// 可选额外注入工作区内的文件.additionalContextFile(PREFERENCES.md).maxContextTokens(8000)// 可选MEMORY 注入的 token 预算.build();3.2 编写 AGENTS.md在workspace/AGENTS.md中定义智能体的人设和行为约束框架每轮推理自动注入system prompt。不创建该文件Agent也能正常运行只是没有人设注入。# MyAgent 你是 XX 助手遵循以下行为约定。 ## 行为 - 用中文回答用户问题 - 不确定时主动询问不编造信息 - 涉及文件操作前先确认路径 ## 限制 - 不执行删除命令 - 不访问工作区以外的路径3.3 按需关闭子系统以下方法用于调试或自行接管子系统时关闭对应能力方法关闭的子系统disableWorkspaceContext()System prompt 注入AGENTS.md/MEMORY.md/knowledge/disableMemoryHooks()记忆 flush 后台维护disableMemoryTools()memory_search/memory_get/session_search工具disableSubagents()整个子 Agent 子系统disableDynamicSkills()每轮动态合并技能改为 build 时一次性加载disableToolsConfig()不读取tools.jsondisableSessionPersistence()AgentState自动持久化4. 重点目录4.1 skills/ — 可复用技能包技能是”写好的能力包”——一个子目录放一份SKILL.mdYAML frontmatter 指令正文可附带参考文档和脚本。skills/code-reviewer/ ├── SKILL.md # name description (YAML) 给 agent 的指令 ├── references/style-guide.md # 可选agent 按需 read_file └── scripts/run-checks.sh # 可选agent 通过 shell 工具调用注册优先级低 → 高重名时上层覆盖优先级注册方式示例1最低projectGlobalSkillsDir(Path)~/.agentscope/skills/2skillRepository(...)Git / Nacos / MySQL / classpath3workspace/skills/工作区共用4最高userId/skills/用户隔离覆盖以上所有每轮推理前DynamicSkillMiddleware重新合成 → 在system prompt中渲染为available_skills块只列namedescriptionagent判断相关后通过load_skill_through_path按需加载详情。4.2 subagents/ — 子 Agent 声明每个agent-id.md声明一个子Agent文件名即agent_id。YAML frontmatter描述身份和约束正文是子Agent的系统提示。--- description: 代码评审专家。当用户需要 review PR、找代码风格问题时使用。 workspace: mode: isolated # isolated默认| shared model: qwen3-max # 可选默认继承父 Agent tools: [read_file, grep_files] # 可选工具白名单 --- 你是一个专注代码评审的子 agent…加载机制AgentSpecLoader在构建期非递归扫描workspace/subagents/*.md再合并通过.subagent(SubagentDeclaration...)编程注册的声明。主Agent通过agent_spawn agent_id”reviewer” task”...”调用。4.3 tools.json — 工具白名单与 MCP 配置工作区根目录下的JSON文件框架在build()时一次性读取。{“allow”:[“read_file”,“grep_files”,“execute”],“deny”:[“write_file”],“mcpServers”:{“amap”:{“transport”:“streamableHttp”,“url”:“https://mcp.amap.com/mcp?key${AMAP_API_KEY}”},“local-py”:{“transport”:“stdio”,“command”:“python”,“args”:[“mcp_servers/my_server.py”],“env”:{“PYTHONUNBUFFERED”:“1”}}}}关键行为规则说明allow非空时只允许列出的工具白名单模式deny列出的工具一律不暴露优先级高于allow过滤范围allow/deny在所有工具注册完成后应用也会过滤 Harness 内置工具read_file、memory_search、agent_spawn等。用白名单时务必把要保留的内置工具一并列出环境变量${ENV_VAR}语法替换未设置时 warning 空字符串编程替代可用builder.toolsConfig(ToolsConfig.builder()...)编程注入disableToolsConfig()完全关闭读取共享存储远端为上层、本机模板为下层的 overlay 模式4.4 plans/ — 计划文件Plan Mode下plan_write写入的当前计划。默认路径plans/PLAN.md可通过.planFileDirectory(“design-docs”)修改。plans/ └── PLAN.md # plan_write 写入的当前计划内容PlanModeContext是否处于 plan 阶段、当前计划文件路径属于运行时状态跟随AgentState通过AgentStateStore持久化默认~/.agentscope/state/agentId/在工作区之外。plans/下仅存储 markdown 内容本身。4.5 agents// — 运行时数据框架自动维护的运行时根目录一般无需手动操作agents/agentId/ ├── sessions/ │ ├── sessions.json # 该 agent 的会话索引 │ └── sessionId.log.jsonl # 原始对话日志append-only永不压缩 └── tasks/ └── sessionId.json # 子 agent 后台任务记录 (taskId → TaskRecord)AgentState序列化数据不在此处——它存储在配置的AgentStateStore默认~/.agentscope/state/agentId/。跨节点恢复 / 多副本部署时需共享这些数据RedisAgentStateStoreRemoteFilesystemSpec或沙箱 分布式状态。4.6 knowledge/ — 领域知识库knowledge/ ├── KNOWLEDGE.md # 入口/概览全文注入 system prompt ├── api-reference.md ├── domain-terms.md └── ...加载策略KNOWLEDGE.md全文进入domain_knowledge_context注入 system prompt同目录下其他文件任意深度只列出路径清单agent通过read_file/grep_files/glob_files按需读取这种目录存细节、prompt放索引的模式避免将整个知识库塞入token预算。