文章目录
- 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 构建 HarnessAgent
- 3.2 编写 AGENTS.md
- 3.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.md+memory/分片文件;后台任务自动从对话抽取事实、压缩降噪,每轮推理自动注入系统提示词。 - 自学习技能:存储于
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时自动降级为SESSION |
| AGENT | 该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 Spec | subagents/子智能体配置目录 |
| 加载自定义技能包 | skills/技能存放目录 |
| 开启规划模式 Plan Mode | plans/持久化计划目录 |
执行任意一次call()调用任务 | agents/<agentId>/运行时根目录(内含sessions、tasks) |
2.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。
HarnessAgentagent=HarnessAgent.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.json |
disableSessionPersistence() | AgentState自动持久化 |
4. 重点目录
4.1 skills/ — 可复用技能包
技能是”写好的能力包”——一个子目录放一份SKILL.md(YAML 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/ |
| 2 | skillRepository(...) | Git / Nacos / MySQL / classpath |
| 3 | workspace/skills/ | 工作区共用 |
| 4(最高) | <userId>/skills/ | 用户隔离,覆盖以上所有 |
每轮推理前DynamicSkillMiddleware重新合成 → 在system prompt中渲染为<available_skills>块(只列name+description),agent判断相关后通过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>/)。跨节点恢复 / 多副本部署时需共享这些数据(RedisAgentStateStore+RemoteFilesystemSpec,或沙箱 + 分布式状态)。
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预算。