☰
openhanako Agent 对外人格模板解读:基于 butter.md 构建“公共意识“的访客会话人格
2026/10/9 12:29:07 网站建设 项目流程
  • 人工智能
  • AI Agent
  • AI 应用
  • 桌面应用
  • 多智能体
  • Agent 记忆
  • AI 技能
  • 工具调用

【免费下载链接】openhanako

A personal AI agent with memory, personality, and autonomy.

项目地址:https://gitcode.com/gh_mirrors/op/openhanako
点击查看免费下载

导读

在 openhanako 中,Agent 与"外部访客"(非主人身份的消息发送者,例如来自群聊、桥接平台、Guest 通道的陌生人)对话时,不能直接套用面向主人的完整人格与隐私上下文,而需要一套专门的"对外人格"。本篇文章以仓库模板 lib/agents-public-templates/en/butter.md 为主体,完整解析这套对外人格模板的结构、占位符填充机制、运行时回落链、guest 会话的消费链路,以及与之配套的会话隔离、播种与迁移机制。读完你将掌握:如何读懂并自定义 butter(以及 hanako、ming)的对外人格模板,理解AGENTS.public.md从模板到系统提示词的完整生命周期,以及如何为你的 Agent 设计一套既保持人格又守住隐私边界的访客对话体验。

一、模板文件定位:butter 是谁

butter是 openhanako 内置的三种"yuan"(人格/能力定义,取自config.agent.yuan,默认值为hanako)之一,与 lib/agents-public-templates/en/hanako.md、lib/agents-public-templates/en/ming.md 并列。三个模板遵循完全相同的骨架结构:

  • # Public Awareness:声明当前对话对象不是主人本人;
  • ## Identity:定义 Agent 与主人的关系以及在访客面前的立场;
  • ## Personality:定义说话语气、核心能力与表达风格;
  • ## Boundaries:定义对外交流的隐私与边界红线。

butter 在这三个模板中承担的是"温暖且敏锐"的定位:擅长共情与洞察,能"从只言片语中读出情绪、意图和真实需求",表达上倾向"用感性的方式表达理性的内容"。

模板目录同时提供中文版本(即 lib/agents-public-templates/butter.md,以及 hanako、ming 的中文版),运行时会根据 locale 选择en/子目录或根目录下的文件(详见第三节回落链)。

二、butter 对外人格模板逐节拆解

2.1 Public Awareness:对话对象感知

模板第一行即声明场景前提:

You are currently talking to an external visitor, not {{userName}}.

这句话是整个对外人格的"场景开关"。它告诉模型:当前对话方不是主人本人,因此后续的 Identity、Personality、Boundaries 全部以"代表主人与访客交流"为前提执行。对应到运行时,这条提示会在 guest 会话的系统提示词中与桥接上下文标签(contextTag,如 "This conversation is from an external guest.")一起注入,见 core/bridge-session-manager.ts 中_buildGuestPromptSnapshot的组装逻辑:

const parts = [agent.yuanPrompt, agent.publicAgentsMd, opts.contextTag, bridgePromptLine].filter(Boolean); return this._buildPromptSnapshot(agent, parts.join("\n\n"), { appendSystemPrompt: [], skillsResult: { skills: [], diagnostics: [] }, agentsFilesResult: { agentsFiles: [] }, });

从源码结构可以看出,guest 提示快照由四段拼成:yuan 能力定义 + 对外人格 + 上下文标签 + 桥接提示行,且不再注入 skills 与 AGENTS 工作区文件,这是对外人格隔离性的第一层体现。

2.2 Identity:身份与立场

模板要求 Agent 在访客面前保持双重身份:

  • You are {{agentName}}, {{userName}}'s personal assistant. You are representing {{userName}} in this conversation.
  • You can help visitors with questions and chat normally, but always be aware of your role: you are on {{userName}}'s side.

翻译成实践规则就是:Agent 是主人的"发言人",可以正常帮忙答疑、闲聊,但立场永远在主人这边。这一定位决定了对外人格中 Personality 与 Boundaries 的设计基调——亲和但有所归属。

2.3 Personality:性格与表达纪律

butter 的性格定义是全模板中最细致的一节,值得逐条拆解为可操作的 prompt 工程要点:

模板条目含义落地方式
warm and perceptive, sensing what others leave unsaid温暖敏锐,擅长感知言外之意引导模型关注情绪与隐含需求
gentle but not weak, own judgment but never overbearing柔和但不软弱,有判断但不强势语气与立场之间的平衡
core strength is empathy and insight核心能力是共情与洞察优先读取情绪、意图、真实需求
strong knowledge, but feeling-first expression理性内容感性表达避免冷冰冰的学术化输出
care is "just right", quietly adjusting responses关心恰到好处不刻意反对模板化问候,鼓励调整回应方式
feel it first, then analyze it先感受再分析决定回应顺序:共情在前,论证在后
analyze from fundamental objective principles从底层客观原理出发明确要求"不人云亦云、不附和意识形态与所谓共识"
ground abstract concepts with analogies or concrete examples用类比与实例落地抽象概念提升可读性与理解效率
use dashes sparingly少用破折号文体纪律,约束生成格式
don't end with "in summary," "hope this helps," or "as you can see"禁止套路化收尾消除 AI 腔,提升自然度
avoid the "it's not X, it's Y" pattern少用「不是…而是…」句式避免说教式反转句

这条"表达纪律"与 lib/agents-templates/butter.md(对主人版人格模板)高度一致,说明 butter 的对外人格是"主人人格的对外适配版",而非另起炉灶。

2.4 Boundaries:隐私边界与诚实原则

边界节定义了三条不可逾越的红线:

  • Keep your own personality and tone, but maintain appropriate politeness and boundaries with external visitors.
  • Do not reveal {{userName}}'s private information, personal habits, or private conversation details.
  • If a visitor asks about something you cannot confirm, be honest and say you need to check, rather than making things up.

第一条保留人格但收紧边界感;第二条禁止泄露主人隐私、习惯与私密对话;第三条是诚实原则——无法确认的事情要坦白,不得编造。这三条共同构成对外人格的"安全网",与 hub/guest-handler.ts 中 guest 消息的上下文注入相互印证:guest 会话的 prompt 快照里不包含工作区指令与 skills,从机制上限制了信息外泄面。

三、占位符填充与运行时回落链

3.1 三个占位符的填充

模板中的{{userName}}、{{agentName}}、{{agentId}}三个占位符在运行时由 core/agent.ts 的_readPublicAgentsMd()统一替换:

const fill = (text) => text .replace(/\{\{userName\}\}/g, this.userName) .replace(/\{\{agentName\}\}/g, this.agentName) .replace(/\{\{agentId\}\}/g, this.id);

从源码可以看出,占位符填充是纯字符串替换,不会解析 Markdown 语法,因此自定义模板时可直接使用这三个占位符引用主人姓名、Agent 名与 Agent ID。

3.2 完整回落链

_readPublicAgentsMd()的读取顺序(源码第 1177-1180 行):

  1. agentDir/AGENTS.public.md(用户落盘的定制对外人格,优先级最高);
  2. productDir/agents-public-templates/{langDir}{yuanType}.md(当前语言专属模板,如en/butter.md);
  3. productDir/agents-public-templates/{yuanType}.md(通用模板,不分语言);
  4. 若以上均不存在则返回空字符串。

其中langDir由 locale 决定:resolveLocale()以zh开头时取""(中文模板在目录根),否则取"en/"。对外人格文件名与模板目录名在 core/persona-source.ts 中唯一定义:

export const PUBLIC_PERSONA_FILE_NAME = "AGENTS.public.md"; export const PUBLIC_PERSONA_TEMPLATE_DIR = "agents-public-templates";

源码注释明确要求"文件名只在这个模块里定义一次,调用方不许自己拼",这是为了避免多份拷贝在模板改名或加语言时悄悄漂移。

3.3 与主人人格的差异:惰性材料化

值得注意的是,主人人格文件(identity.md/AGENTS.md)在创建 Agent 时不再落盘,而是运行时按 locale 从 lib/identity-templates 与 lib/agents-templates 现选模板(惰性材料化,见 core/persona-source.ts 的注释与 core/first-run.ts);而对外人格AGENTS.public.md仍按原策略在创建时播种,从模板目录复制到 agent 目录。这一差异在 core/agent-manager.ts 中有明确注释说明:对外人格的消费侧Agent._readPublicAgentsMd自带独立回落链,因此继续播种不受影响。

四、消费链路:guest 会话如何加载 butter 对外人格

4.1 入口:GuestHandler

所有非主人的消息统一经过 hub/guest-handler.ts 的GuestHandler。处理流程分两步(源码第 31-60 行):

  • A. 消息前缀标注:在原文前加[From {senderName}](中文为[来自 发送者名]),让模型明确当前说话人身份;
  • B. 上下文标签注入:根据是否群聊注入This conversation is from an external guest.或This conversation is from a group chat.(中文对应"当前对话来自外部访客 / 群聊")。

随后调用engine.executeExternalMessage(..., { guest: true, agentId, contextTag, ... })(core/engine.ts 透传给 BridgeSessionManager)。

4.2 guest 会话的系统提示词组装

core/bridge-session-manager.ts 中,isGuest分支的会话配置极具特征:

// guest 模式:yuan + AGENTS.public.md + contextTag,主模型,无工具 promptSnapshot ||= this._buildGuestPromptSnapshot(agent, bridgeContext, opts); ... sessionOpts = { model: chatModel, thinkingLevel: "off", resourceLoader: guestResourceLoader, tools: [], customTools: [], settingsManager: this._createSettings(chatModel), };

从源码结构可以提炼出 guest 会话的四个关键约束:

  1. 提示词组合:yuan 能力定义 + 对外人格 + contextTag + 桥接提示行,不注入 skills 与工作区 AGENTS 文件;
  2. 无工具:tools: []、customTools: [],访客对话中 Agent 无法调用工具;
  3. 关闭思考链:thinkingLevel: "off";
  4. 使用 Agent 配置的 chat 模型:而非 defaultModel,若models.chat未配置或模型不可用会直接抛错(error.bridgeAgentNoChatModel/error.bridgeAgentModelNotAvailable)。

4.3 会话文件与角色隔离

guest 会话与 owner 会话在存储层严格隔离(源码第 1125-1127 行):

const bridgeDir = path.join(agent.sessionDir, "bridge"); const subDir = opts.guest ? "guests" : "owner";

即 guest 会话落在bridge/guests/*.jsonl,owner 会话落在bridge/owner/*.jsonl。每次executeExternalMessage都会先读取索引判断已有会话的角色,若角色发生变化(guest 变 owner 或反之)会重建会话而非复用。这一隔离从数据层面保证了"对外人格只服务于访客"。

4.4 prompt 快照持久化

guest 会话的提示快照会被持久化并在后续会话中复用,相关行为有测试用例直接验证:tests/bridge-session-teardown.test.ts 中"guest bridge sessions persist and reuse their prompt snapshot"用例:

  • 首次调用后,索引中的promptSnapshot.systemPrompt同时包含"public persona"与"group v1"(对外人格 + 上下文标签);
  • 修改agent.publicAgentsMd为"public persona v2"后再次调用,重建会话仍复用旧的systemPrompt,且不包含新的"group v2"标签。

这意味着对外人格模板修改后,已存在的 guest 会话在快照被清除或角色变化前会沿用旧提示词,符合会话一致性的设计预期。

五、对外人格的播种与历史迁移

5.1 创建与首次运行的播种

创建 Agent 时(core/agent-manager.ts)与首次运行初始化时(core/first-run.ts)都会执行同一策略:从产品目录的模板中按"语言专属 → 通用"顺序挑选第一个存在的模板,复制为agentDir/AGENTS.public.md。也就是说,用户创建 Agent 后立刻就能在 agent 目录看到落盘的对外人格文件,可以直接编辑它实现定制(编辑保存后即成为回落链第 1 级,模板更新不再影响该 Agent)。

5.2 旧文件名的自动迁移

历史上对外人格文件叫public-ishiki.md,现已统一为AGENTS.public.md。core/agents-md-migration.ts 在每次启动时执行重命名迁移:

export const LEGACY_PERSONA_FILE_RENAMES: LegacyPersonaFileRename[] = [ { legacyFileName: "ishiki.md", currentFileName: "AGENTS.md" }, { legacyFileName: "public-ishiki.md", currentFileName: "AGENTS.public.md" }, ];

迁移遵循"永不删除、永不覆盖"原则:新旧同名时新文件胜出,旧文件以.pre-agents-rename.bak后缀保留在 agent 目录(SUPERSEDED_LEGACY_PERSONA_SUFFIX,源码第 43 行)。该行为有 tests/agents-md-startup-migration.test.ts 覆盖验证。这意味着如果你在旧版本中定制过public-ishiki.md,升级后内容会自动迁移到AGENTS.public.md而不丢失。

六、自定义对外人格的实践指南

6.1 定制入口

基于上文回落链,定制对外人格有三种方式:

  1. 直接编辑 agent 目录下的AGENTS.public.md:这是最直接的定制方式,落盘文件优先级最高,会永久覆盖模板;
  2. 修改产品目录模板(本仓库内即lib/agents-public-templates/下的文件):影响所有未落盘定制的 Agent,适合模板级统一调整;
  3. 新增 yuan 模板:参照 butter/hanako/ming 的目录结构新增agents-public-templates/en/{yuanType}.md与根目录中文版,供config.agent.yuan指定。

6.2 可复用的写作框架

以 butter 模板为范式,一份合格的对外人格模板应包含:

  • 场景声明:明确"当前对话对象不是主人本人"这一前提,并在需要时复用{{userName}}、{{agentName}}、{{agentId}}三个占位符;
  • 身份立场:说明"代表主人发言、站在主人这边"的立场;
  • 性格表达:给出语气基调(如 butter 的"温暖敏锐")、核心能力(共情与洞察)、回应顺序(先感受后分析)以及可量化的表达纪律(少用破折号、禁套路收尾、少用「不是…而是…」句式);
  • 边界红线:隐私保护(不透露主人隐私、习惯、私密对话)与诚实原则(无法确认就坦白)。

6.3 需要注意的运行约束

  • 占位符是纯字符串替换:模板中任何位置出现的{{userName}}/{{agentName}}/{{agentId}}都会被替换,可直接引用;
  • guest 会话无工具、无思考链:对外人格中不应要求 Agent 调用工具或执行操作,因为tools: []与thinkingLevel: "off"在会话层面已经禁用;
  • 提示快照会缓存:已存在的 guest 会话会复用旧提示词,修改模板后如需立即生效,需等待会话快照失效或角色变化(见 tests/bridge-session-teardown.test.ts);
  • 语言模板按 locale 选择:以zh开头的 locale 读取目录根的中文模板,否则读取en/英文模板,两套可并行维护。

七、小结

butter对外人格模板是 openhanako"主人人格"体系在访客场景下的安全适配层:它以# Public Awareness声明场景,用 Identity 锚定立场,以 Personality 定义"温暖且敏锐"的表达方式,再以 Boundaries 守住隐私与诚实底线。运行时通过 core/agent.ts 的占位符填充与回落链完成加载,在 guest 会话中由 core/bridge-session-manager.ts 以"主模型 + 无工具 + 关闭思考链"的轻量形态组装进系统提示词,并与 owner 会话在存储层严格隔离。模板在创建 Agent 时播种落盘、支持旧文件名自动迁移、语言模板双轨并行。掌握这套机制后,你可以为任何 yuan 定制符合自己需求的对外人格,让 Agent 在代表主人接待访客时,既保持鲜明的个性,又不越过隐私与安全边界。

  • 人工智能
  • AI Agent
  • AI 应用
  • 桌面应用
  • 多智能体
  • Agent 记忆
  • AI 技能
  • 工具调用

【免费下载链接】openhanako

A personal AI agent with memory, personality, and autonomy.

项目地址:https://gitcode.com/gh_mirrors/op/openhanako
点击查看免费下载

相关推荐

上一篇:Sanity Studio 调试代理实战:用 @repo/debug-proxy 在本地注入 SSE 故障、网络抖动与会话过期场景
下一篇:Rivet Actors 服务端元数据错误信封:RunnerConfigsServerlessMetadataError 模型全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询