- 人工智能
- AI Agent
- AI 应用
- 桌面应用
- 多智能体
- Agent 记忆
- AI 技能
- 工具调用
【免费下载链接】openhanako
A personal AI agent with memory, personality, and autonomy.
导读
在 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 行):
agentDir/AGENTS.public.md(用户落盘的定制对外人格,优先级最高);productDir/agents-public-templates/{langDir}{yuanType}.md(当前语言专属模板,如en/butter.md);productDir/agents-public-templates/{yuanType}.md(通用模板,不分语言);- 若以上均不存在则返回空字符串。
其中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 会话的四个关键约束:
- 提示词组合:
yuan 能力定义 + 对外人格 + contextTag + 桥接提示行,不注入 skills 与工作区 AGENTS 文件; - 无工具:
tools: []、customTools: [],访客对话中 Agent 无法调用工具; - 关闭思考链:
thinkingLevel: "off"; - 使用 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 定制入口
基于上文回落链,定制对外人格有三种方式:
- 直接编辑 agent 目录下的
AGENTS.public.md:这是最直接的定制方式,落盘文件优先级最高,会永久覆盖模板; - 修改产品目录模板(本仓库内即
lib/agents-public-templates/下的文件):影响所有未落盘定制的 Agent,适合模板级统一调整; - 新增 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.
相关推荐
openhanako 对外人格模板解读:如何让 AI 助手与外部访客安全、得体地对话
openhanako 对外人格模板解读:如何让 AI 助手与外部访客安全、得体地对话 导读 openhanako 是一个具备记忆、性格与自主性的个人 AI 代理
人工智能AI AgentAI 应用桌面应用多智能体Agent 记忆AI 技能工具调用openhanako Agent 人格模板深度解析:butter 模板的 14 条人格规范与模板回落链加载机制
openhanako Agent 人格模板深度解析:butter 模板的 14 条人格规范与模板回落链加载机制 openhanako 是一个带记忆、人格与自主性
人工智能AI AgentAI 应用桌面应用多智能体Agent 记忆AI 技能工具调用初识metaphone4cj:仓颉语言语音算法完整指南
初识metaphone4cj:仓颉语言语音算法完整指南 metaphone4cj 是一个用仓颉语言(Cangjie)实现的语音算法库,它能把英文单词转换为发音代
人工智能AI AgentAI 应用桌面应用多智能体Agent 记忆AI 技能工具调用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考