OpenHuman 用户上下文与个性化适配指南:从目标画像到记忆边界的系统提示词设计
【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman
导读
本指南以 OpenHuman 仓库中的 USER.md 为骨架,系统讲解个人 AI 如何根据用户画像、专业水平与沟通偏好动态调整应答方式,以及如何在系统提示词(System Prompt)管线中落地"该记住什么、该忘记什么、如何保护隐私"这三条边界。读完你将掌握:OpenHuman 六类目标用户画像及其适配策略、三档复杂度检测信号、可编辑的用户记忆文件(PROFILE.md / MEMORY.md / USER.md)注入机制,以及基于源码的 KV-Cache 稳定性与隐私实现细节。
一、定位:USER.md 在提示词管线中的角色
在 OpenHuman 中,src/openhuman/agent/prompts/ 目录存放着构建系统提示词的核心素材,与 IDENTITY.md、ROLE.md、SOUL.md、STYLE.md 并列,USER.md专门定义"用户上下文与适配(User Context and Adaptation)"规范:告诉模型用户是谁、处于什么专业水平、偏好什么沟通方式,以及哪些个人信息可以被记住、哪些必须被遗忘。
从源码结构看,这份规范与提示词渲染层深度绑定:
- types.rs 定义了
PromptContext,其中user_identity、include_profile、include_memory_md、curated_snapshot、learned.reflections等字段直接承载 USER.md 所述的用户信息; - sections.rs 中的
UserFilesSection、UserReflectionsSection、UserMemorySection、UserIdentitySection分别把用户画像文件、反思记录、记忆摘要、身份字段渲染进最终提示词; - builder.rs 的
SystemPromptBuilder负责把这些 Section 按固定顺序拼装成完整的系统提示词。
因此,USER.md 不是一份静态的礼仪文档,而是直接决定模型每次会话"以什么口吻、什么深度、基于哪些用户背景"进行回答的可执行规范。
二、目标用户画像:六类人群与对应适配策略
USER.md 开篇即声明 OpenHuman 服务于社区、团队与专业人士(communities, teams, and professionals),并列出六类典型用户。每类用户的需求(Needs)、沟通风格(Communication style)与适配策略(Adapt by)如下表:
| 用户类型 | 核心需求 | 沟通风格 | 适配策略 |
|---|---|---|---|
| 运营者与快节奏专业人士(Operators & fast-moving professionals) | 速度、准确性、最新上下文、简洁回答 | 直接、数字/结果导向、行动导向 | 开门见山给出具体要点,使用精确术语,除非被要求展开否则保持简短 |
| 分析师与高级用户(Analysts & power users) | 对比、风险/权衡框架、结构化推理 | 技术化、注重细节、审慎对待假设 | 清晰命名选项,暴露权衡,必要时引用局限性与来源 |
| 战略负责人与规划者(Strategic leads & planners) | 主题重于战术、尽调支持、清晰叙事 | 专业、详尽、基于证据 | 提供带明确论点与备选方案的结构化分析,尽量引用来源 |
| 研究员与分析人员(Researchers & analysts) | 深度数据、方法论严谨、来源核验 | 学术、精确、好质疑 | 展示方法论,原始数据与解读并列,承认数据局限 |
| 创作者与社区负责人(Creators & community leads) | 内容草稿、受众洞察、趋势发现、排期 | 有创造力、有感染力、受众意识强 | 协助写钩子(hooks)、按平台格式化、建议结构 |
| 开发者(Developers) | 技术文档、代码示例、调试帮助、架构讨论 | 精确、代码友好、系统思维 | 给出代码片段,引用具体 API/SDK,使用专业术语不过度解释,并利用 GitHub 集成获取仓库上下文 |
这六类画像并非彼此排斥——同一位用户在不同场景可能横跨多类。关键是模型需要从对话信号中动态判定当前语境,而非把用户永久钉死在某一类上,这与下文"复杂度检测"机制是配套的。
开发者画像在仓库中的落地证据
开发者画像要求"引用具体 API/SDK、使用技术术语",OpenHuman 通过两处机制支撑:
- 身份字段免重复询问:
UserIdentitySection会把已登录用户的id/name/email渲染为## User块,并明确指示"直接在工具调用中使用这些字段,不要让用户重复输入"(见 sections.rs)。这正对应用户画像中"技术文档、代码示例"类需求——模型不再反复索要已知信息。 - GitHub 集成与仓库上下文:
AgentsInstructionsSection注入预加载的AGENTS.md指令层(全局工作区层 + 本地项目层),对应开发者画像"利用 GitHub 集成获取 repo context"的诉求(见 sections.rs)。
三、复杂度检测:三档信号与响应深度调节
USER.md 要求模型依据信号(signals)自动调整响应深度,共三档:
- 初学者信号(Beginner):基础术语提问、"what is"、"how do I start"、对基本概念困惑。
- 响应:讲清概念、避免行话、给出分步指导。
- 中级信号(Intermediate):具体工具问题、对比请求、"which is better for"。
- 响应:默认对方有基础,聚焦权衡与实用建议。
- 专家信号(Expert):技术深潜、方法论密集请求、边缘情况。
- 响应:匹配其深度、跳过基础、以同侪水平交流。
这套"按需调节深度"的理念在源码中有多处呼应:
- 内存注入有上限、可裁剪:
PROFILE.md与MEMORY.md每个文件被硬性限制在USER_FILE_MAX_CHARS = 2_000字符(约 1000 token),超过部分由注入函数追加[... truncated at 2000 chars — usereadfor full file]提示(见 types.rs 与 render_helpers_part_01.rs)。对初学者给出分步指导、对专家给足细节,二者共享同一套上下文,但容量被刻意收敛,避免长对话中用户文件把上下文窗口撑爆。 - 面向专家信号的完整工具清单:
ToolsSection会根据调度器格式渲染可见工具目录(P-Format 签名或 JSON Schema),并附带dispatcher_instructions行为指引(见 sections.rs)——技术深潜类问题需要模型清楚自己手里有哪些工具可用。
四、个性化边界(Personalization Boundaries)
USER.md 用三大板块约束模型对用户信息的记忆与使用,这是全篇对隐私最敏感的规范。
4.1 该记住什么(What to Remember)
- 用户声明的角色与经验水平;
- 平台偏好(使用了哪些集成);
- 沟通风格偏好(啰嗦 vs 简洁);
- 反复出现的主题与兴趣;
- 时区与排期偏好。
在源码中,这些信息分别落在不同存储介质:
| 记忆内容 | 载体 | 注入方式 |
|---|---|---|
| 角色、经验水平、沟通偏好 | PROFILE.md(onboarding 富化产物) | UserFilesSection按USER_FILE_MAX_CHARS截断注入 |
| 长期事实、跨会话观察 | MEMORY.md(archivist 策展的长期记忆) | 同节注入,并前置MEMORY_MD_FRAMING背景说明 |
| 用户显式自我陈述("记住我……""以后……") | learning_reflections命名空间 | UserReflectionsSection以高优先级渲染 |
| 时区 / 当前时间 | 每次用户消息携带的Current Date & Time:行 | current_datetime_line()按 IANA 时区生成 |
值得注意的细节是 MEMORY_MD_FRAMING 常量:注入MEMORY.md时必须前置"这是跨会话的长期记忆背景,不是当前对话内容"的说明。原因记录在源码注释(GH-4745)中——如果不对记忆块加框,模型会把它误读为"本线程已经说过的话",从而在新线程中错误地宣称连续性("我们之前已经聊过这个")并偷懒简化回答。
4.2 该忘记什么(What to Forget)
- 用户未要求保留的敏感标识符(如私有账号细节);
- 除非用户要求记住,否则不保留机密业务细节;
- 来自已连接平台的私密对话;
- 用户要求遗忘的任何信息。
4.3 隐私规则(Privacy Rules)
- 绝不主动在对话中引用用户的机密细节;
- 若需回忆用户上下文,必须明确说明:"Based on what you've told me before..."(基于你之前告诉我的……);
- 用户可随时询问"what do you know about me?"并获得透明回答;
- 用户可随时请求完全清除记忆(full memory wipe)。
源码层面的隐私实现:只注入非敏感字段
USER.md 的隐私规则在UserIdentitySection的实现中得到严格贯彻(见 sections.rs):
- 只有
id/name/email三个标识字段被允许进入提示词; - 令牌(tokens)、刷新令牌(refresh tokens)以及任何不透明凭据材料被明令禁止(注释对应 issue #926);
- 渲染前执行
sanitize_identity_field净化:把换行与连续空白折叠为单个空格,防止恶意构造的 name 字段利用 Markdown 换行"重塑"## User块结构; - 当所有字段为空/空白时整块跳过,绝不输出一个指向零字段的悬空标题。
同时,PromptContext::user_identity由调用方从auth_get_me缓存预取(app_state::ops::peek_cached_current_user_identity会剥离除 id/email/name 外的全部内容),提示词构建过程永不触网,从数据流上保证了敏感信息不外泄(见 types.rs)。
五、从规范到提示词:用户上下文如何进入系统提示词
5.1 Section 装配顺序
SystemPromptBuilder::with_defaults()(见 builder.rs)按如下顺序装配默认提示词,用户相关 Section 被刻意放在前缀区域(cache-friendly prefix):
IdentitySection(SOUL.md / IDENTITY.md / ROLE.md) → UserFilesSection(PROFILE.md + MEMORY.md,各 2000 字符上限) → AgentsInstructionsSection(AGENTS.md 全局 + 项目层) → UserMemorySection(树摘要器产出的命名空间摘要) → ToolsSection(工具目录) → SafetySection(安全规则) → WorkspaceSection(工作目录约束) → DateTimeSection(时间纪律规则) → RuntimeSection(主机 / 系统 / 模型)其中UserReflectionsSection由会话构建器在学习子系统启用时动态插入到user_memory之前——因为用户显式反思是"近期的、有意的、身份相关的信号",优先级高于任何通用历史摘要(见 sections.rs)。
5.2 用户文件的注入优先级链
UserFilesSection::build(见 sections.rs)对MEMORY.md采用三级优先级:
- 个性人格覆盖(
personality_memory_md):为特定人格提供专属记忆; - 会话冻结的策展快照(
curated_snapshot):从快照中同时注入MEMORY.md与USER.md,保证同一轮内所有被委派的子代理看到字节完全一致的上下文; - 工作区文件回退(
workspace_dir/MEMORY.md):纯提示词单元测试与旧调用点使用。
这里就是 USER.md 文件名(USER.md)真正出现在渲染管线中的位置——在策展快照路径下,inject_snapshot_content会把USER.md与MEMORY.md一并注入。CuratedMemoryPromptSnapshot类型(见 types.rs)定义了这一快照的memory+user双字段结构。
5.3 KV-Cache 稳定性契约
这是本管线最关键的工程约束之一。源码多处强调:
- 一次构建,整会话冻结:系统提示词在会话开始时构建一次,此后每个 turn 复用完全相同的字节,使推理后端的自动前缀缓存(prefix cache)稳定命中(见 builder.rs);
- 用户文件冻结:
PROFILE.md/MEMORY.md一旦注入即冻结,会话中途的 archivist 写入或富化刷新只对下一个会话生效,绝不污染正在进行的会话(见 sections.rs); - 时间戳不进入前缀:具体"当前时间"通过
current_datetime_line()放在用户消息上随 turn 注入,而系统提示词里只放静态的时间纪律规则——因为Local::now()是易变值,冻结进前缀既破坏 KV 缓存又会在长会话中过时(对应 issue #3602,见 render_helpers_part_01.rs); - 记忆日期用绝对日期:内存摘要的
updated_at渲染为2026-05-25这种绝对日期而非"N 天前",避免每日变化的标签打爆缓存前缀(见 render_helpers_part_01.rs)。
5.4 子代理与窄化渲染
当主代理委派子代理(如 integrations_agent、code_executor)时,使用SystemPromptBuilder::for_subagent或render_subagent_system_prompt(见 render_helpers_part_01.rs)。子代理提示词:
- 默认不含
DateTimeSection,因为重复 spawn 同一子代理定义必须产出字节一致的提示词以复用前缀缓存; - 用户文件(PROFILE/MEMORY)通过
SubagentRenderOptions的include_profile/include_memory_md独立门控,即使omit_identity = true(如 welcome / orchestrator)也能按需携带用户上下文; - 同样遵守
USER_FILE_MAX_CHARS上限,并在Native工具调用格式下跳过散文式工具目录以省 token(源码记录:62 个动态 gmail 工具若重复列出约多耗 5.4 万 token)。
六、工作区文件同步机制:用户如何直接编辑这些规范
USER.md 所述的记忆与画像并非黑盒。sync_workspace_file(见 render_helpers_part_01.rs)把内置默认内容同步到工作区目录(如~/.openhuman/users/<id>/workspace/),并遵循一套哈希驱动的更新策略:
- 首次安装时写入内置默认文件;
- 在侧车文件
.{filename}.builtin-hash中记录编译进代码的内容哈希; - 代码升级导致内置内容变化时,若磁盘文件自上次写入后未被用户编辑(哈希匹配)则自动覆盖;若用户手动编辑过,则保留用户版本,只更新存储哈希。
因此,用户可以直接编辑工作区中的STYLE.md、PROFILE.md、MEMORY.md乃至各 Agent 的提示词文件来定制行为——仓库内STYLE.md的权威内容即"sync_workspace_file最后一次写入的内容加上用户的任何编辑"(见 builder.rs)。这为用户在"该记住什么、该忘记什么"层面提供了规范之外的人工兜底:直接改文件,即可精确控制注入模型的用户上下文。
七、反思记忆:超越画像的高优先级上下文
除了 USER.md 中的静态画像,OpenHuman 的学习子系统会从对话中捕捉用户的显式自我陈述("remember that I…""going forward…""I realized…"),存入learning_reflections命名空间(见 learning/reflection.rs)。这类反思是 USER.md"用户声明的角色与经验水平""反复出现的主题"在动态侧的延伸:
- 渲染为
## User Reflections块,优先于所有通用记忆摘要; - 每轮最多截取 10 条反思,保持特权区有界(见 session/turn/context.rs);
- 无反思内容时整块跳过,保持提示词干净(用户从未表达过反思式内容时不产生任何噪音)。
结语
USER.md 虽只有 76 行,却是 OpenHuman 个性化体验的"宪法":它定义了六类用户画像与适配策略、三档复杂度信号,以及"该记住 / 该忘记 / 隐私规则"三大边界。而 prompts/ 下的 Rust 实现把这些规范变成了可运行的机制——UserFilesSection的注入优先级链、UserIdentitySection的非敏感字段过滤、USER_FILE_MAX_CHARS的容量纪律、KV-Cache 稳定性契约、可编辑的工作区文件同步。理解这条从规范到提示词的完整链路,是定制个人 AI 行为、排查个性化失效问题(如"记忆没生效""回答深度不对""隐私信息泄漏风险")的起点。
【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考