归属系统:对话交互式 AI 系统
版本:v1.0
日期:2026-03-15
参考:OpenClaw Memory(Markdown 文件 + 语义检索)、OpenClaw.NET 工具注册机制、OpenClaw Windows Node HITL 哲学
实现位置:NewLife.AI核心库 +NewLife.ChatAI应用层
自学习系统是 ChatAI 智能体框架的核心差异化能力。系统通过 自动分析用户对话,提取用户偏好、行为习惯和业务知识,持久化存储为结构化记忆,使 AI 在持续使用过程中 越用越懂用户。
| 定位 | 说明 |
|---|---|
| 自我进化 | AI 智能体通过对话分析自主学习,无需人工维护知识库 |
| 个性化服务 | 基于偏好记忆,提供针对性回答 |
| 业务知识积累 | 从高质量对话中提取业务规则、领域知识,形成组织知识资产 |
| 隐私可控 | 用户可选择开启/关闭自学习,可查看/删除已学习内容 |
| OpenClaw 实践 | ChatAI 借鉴方案 |
|---|---|
Markdown 文件记忆(MEMORY.md + memory/YYYY-MM-DD.md) |
初期采用 Markdown 存储,结构化元数据入库,正文存文件;后期迁移向量数据库 |
USER.md / SOUL.md 用户与人格描述 |
偏好记录 |
| 语义记忆搜索(embedding + cosine) | 复用 ISemanticMemory + IVectorStore |
| 信念偏差防控(Belief Deviation Prevention) | 对话评分机制:仅高分对话触发学习,避免低质量信息污染 |
| HITL 人在回路(Human-In-The-Loop) | 学习开关 + 学习日志可审阅 + 知识可人工修正/删除 |
| 技能三层架构(bundled / managed / workspace) | 知识三层分类:系统知识 / 组织知识 / 用户个人知识 |
| 跨会话状态管理 | 记忆跨会话持久化,全局生效 |
每条记忆包含以下属性:
| 属性 | 类型 | 说明 |
|---|---|---|
| Id | Long | 主键 |
| UserId | Int | 所属用户 |
| Category | String | 知识分类(见第 5 节) |
| Title | String | 记忆标题,一句话概括 |
| Content | String | 记忆正文,Markdown 格式 |
| Source | String | 来源类型:auto(自动提取)/ manual(手动添加)/ system(系统生成) |
| SourceConversationId | Long | 来源对话 ID(自动提取时关联) |
| Tags | String[] | 标签列表,便于检索和分类 |
| Score | Double | 知识质量评分(0~1),由对话评分引擎生成 |
| Vector | Float[] | 嵌入向量,用于语义检索(可选,后期填充) |
| Enable | Boolean | 是否启用,禁用的记忆不参与上下文注入 |
| CreateTime | DateTime | 创建时间 |
| UpdateTime | DateTime | 最后更新时间 |
| AccessCount | Int | 被检索引用的次数,用于衡量记忆价值 |
| LastAccessTime | DateTime | 最后被引用时间 |
| 阶段 | 存储方案 | 说明 |
|---|---|---|
| 第一阶段 | XCode 数据库 + Markdown 文件 | 元数据(标题、分类、标签、评分)存数据库,正文存 Markdown 文件(Data/Memory/{userId}/{category}/{id}.md) |
| 第二阶段 | + 向量索引 | 在第一阶段基础上增加嵌入向量,复用 IVectorStore 接口做语义检索 |
| 第三阶段 | + 外部向量数据库 | 将 InMemoryVectorStore 替换为 Redis/Qdrant 等后端,支持大规模知识库 |
当用户发送消息时,系统自动从记忆库中检索相关知识并注入上下文:
用户消息 → 语义检索(Top-K 相关记忆) → 拼接为上下文 → 注入 System Prompt → 发送给模型
- 检索策略:优先语义检索(向量相似度),降级为关键词匹配
- 注入数量:默认注入 Top-5 条最相关记忆,可配置
- 注入格式:以结构化 Markdown 块注入到 System Prompt 中
## 用户记忆(自动注入)
以下是关于该用户的已知信息,请在回答时参考:
### 用户偏好
- 偏好简洁回答,不喜欢过长的解释
- 常用编程语言:C#、Python
### 业务知识
- 项目使用 NewLife.XCode 框架做数据访问
- 部署环境为 Docker + Kubernetes- Token 预算:记忆注入总量不超过模型上下文窗口的 10%,超出时按评分从低到高裁剪
- 用户可见性:记忆注入过程对用户透明,不在对话界面中显示
对话分析在 AI 回复完成后异步执行,不阻塞用户对话:
AI 回复完成 → 异步触发分析 → 对话评分 → 高分对话触发知识提取 → 存入记忆库
系统对每轮对话(用户消息 + AI 回复)进行价值评分,决定是否值得从中提取知识:
| 评分维度 | 权重 | 说明 |
|---|---|---|
| 信息密度 | 30% | 对话中是否包含有价值的事实、数据、业务规则 |
| 用户意图明确性 | 20% | 用户表达是否清晰,是否包含明确的偏好/需求声明 |
| 对话深度 | 20% | 是否为多轮深入讨论,而非简单问答 |
| 业务相关性 | 20% | 是否涉及专业领域知识或具体业务场景 |
| 新颖性 | 10% | 相比已有记忆,是否包含新信息 |
- 评分方式:调用模型对对话进行评价,输出 0~1 的综合评分
- 评分阈值:可配置,默认 0.6,低于阈值的对话不触发知识提取
- 评分提示词:可在系统设置中自定义(见第 6 节),允许管理员调整评分标准
- 评分结果:写入对话记录的
Score字段,便于后续分析
当对话评分超过阈值时,系统自动从对话中提取知识片段:
| 提取类型 | 说明 | 示例 |
|---|---|---|
| 用户偏好 | 用户表达的个人喜好、风格偏好 | "我喜欢简洁的代码风格"、"请用中文回答" |
| 行为习惯 | 用户的使用模式、交互习惯 | "用户常在晚上提问"、"偏好图表展示数据" |
| 业务知识 | 领域特定的规则、事实、流程 | "公司使用 GitLab 做 CI/CD"、"订单超过 30 天不可退" |
| 技术知识 | 技术栈、架构选择、工具使用 | "项目基于 .NET 8"、"数据库用 MySQL" |
| 关系知识 | 人物、组织、系统间的关系 | "张三是项目经理"、"A 系统调用 B 系统的 API" |
- 提取方式:调用模型分析对话,输出结构化的知识片段
- 提取提示词:可自定义(见第 6 节)
- 去重校验:提取前与已有记忆做语义相似度比对(阈值 0.85),避免重复存储
- 冲突处理:当新知识与旧知识矛盾时,保留新知识,旧知识标记为
Enable=false并记录更新原因
❌ 不做。用户画像与标签系统曾实现(v1.0 规划),后因实际价值不高、维护成本大于收益,已整体移除,仅保留用户记忆体系。
采用 两级分类,第一级固定,第二级可扩展:
| 一级分类 | 二级分类(预置) | 说明 |
|---|---|---|
| user_preference | style、language、tool、topic |
用户个人偏好(回答风格、常用工具、关注话题) |
| business | rule、process、product、customer |
业务知识(业务规则、流程、产品信息、客户信息) |
| technical | architecture、stack、practice、issue |
技术知识(架构、技术栈、最佳实践、已知问题) |
| organizational | team、role、project、convention |
组织知识(团队结构、角色职责、项目信息、惯例) |
| domain | 动态扩展 | 领域专业知识(根据用户行业自动识别并创建子分类) |
| 范围 | 说明 | 可见性 |
|---|---|---|
| personal | 用户个人知识,仅本人对话中提取 | 仅本人 |
| shared | 共享知识,管理员标记为组织级 | 所有用户 |
| system | 系统级知识,管理员手动维护 | 所有用户 |
在系统设置(ChatSetting)中增加以下配置项:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| EnableAutoLearning | Boolean | false | 全局自学习开关,关闭后不分析任何对话 |
| LearningScoreThreshold | Double | 0.6 | 对话评分阈值,低于此值不触发知识提取 |
| MaxMemoryPerUser | Int | 500 | 每用户最大记忆条数 |
| MemoryRetentionDays | Int | 365 | 记忆保留天数,超期且 AccessCount=0 的记忆自动清理 |
| MemoryInjectionCount | Int | 5 | 每次对话注入的最大记忆条数 |
| MemoryTokenBudgetPercent | Int | 10 | 记忆注入占模型上下文窗口的最大百分比 |
| LearningModel | String | (空) | 用于分析和评分的模型名称,为空时使用当前对话模型 |
管理员可自定义对话评分的提示词模板(ChatSetting.ScoringPrompt):
请分析以下对话内容,从以下维度进行评分(0~1):
1. **信息密度**(30%):对话中是否包含有价值的事实、数据或业务规则?
2. **意图明确性**(20%):用户是否清晰表达了偏好、需求或业务逻辑?
3. **对话深度**(20%):是否为深入讨论?
4. **业务相关性**(20%):是否涉及专业领域知识或具体业务场景?
5. **新颖性**(10%):是否包含以前未见过的新信息?
输出 JSON:
{"score": 0.75, "dimensions": {"density": 0.8, "clarity": 0.7, "depth": 0.6, "relevance": 0.9, "novelty": 0.5}, "reason": "简要说明"}管理员可自定义知识提取的提示词模板(ChatSetting.ExtractionPrompt):
请从以下对话中提取有价值的知识片段,输出为 JSON 数组。每条知识包含:
- **title**:一句话概括(不超过 30 字)
- **content**:知识详细描述(Markdown 格式)
- **category**:一级分类(user_preference / business / technical / organizational / domain)
- **subcategory**:二级分类
- **tags**:标签列表
注意:
- 只提取明确的、可复用的知识,不要提取一次性的问答内容
- 同一对话可提取多条知识
- 如果对话没有可提取的知识,返回空数组在用户设置(UserSetting)中增加以下选项,允许用户个人控制:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| EnablePersonalLearning | Boolean | true | 个人学习开关(需全局开关也开启) |
在设置页弹窗中新增"学习"(Learning)Tab,包含以下内容:
| 区域 | 说明 |
|---|---|
| 学习开关 | Toggle:启用/禁用个人学习功能 |
| 记忆统计 | 显示记忆总数、分类分布、最近学习时间 |
| 记忆列表 | 分类展示已学习的知识,支持搜索、查看详情、删除单条 |
| 清除所有记忆 | 按钮,二次确认后删除所有个人记忆 |
- 当系统正在分析对话时,在消息底部显示微弱的"🧠 学习中..."指示(2 秒后自动消失)
- 用户可在设置中关闭此指示器
| 功能 | 说明 |
|---|---|
| 全局学习统计 | 知识总量、分类分布、学习趋势 |
| 共享知识管理 | 将个人知识提升为组织知识 |
| 评分/提取提示词配置 | 在线编辑评分和提取用的提示词模板 |
| 学习日志 | 查看自动学习的执行日志和提取结果 |
| 集成点 | 说明 |
|---|---|
| 语义记忆 | 记忆检索复用 ISemanticMemory.SearchAsync,存储复用 SaveAsync |
| 向量存储 | 记忆嵌入向量存储复用 IVectorStore,支持后期切换到外部向量数据库 |
| 过滤器 | 新增 LearningFilter : IChatFilter,在 Chat 调用完成后异步触发对话分析 |
| 技能管理 | 从高频业务知识中自动生成技能建议(后续迭代) |
| System Prompt | 记忆内容在技能内容之后、用户输入之前注入 |
| 使用量统计 | 学习分析调用的 Token 消耗独立统计,不计入用户用量 |
| 用户设置 | UserSetting 扩展个人学习配置项 |
| 会话记录 | Conversation 表扩展 Score 字段存储对话评分 |
| 安全措施 | 说明 |
|---|---|
| 隐私保护 | 自学习默认关闭,需用户和管理员双重同意才生效 |
| 数据最小化 | 仅提取结构化知识,不存储原始对话内容(仅关联 ConversationId) |
| 用户主权 | 用户可随时查看、删除自己的记忆,可关闭学习功能 |
| 敏感信息过滤 | 提取知识前自动过滤手机号、邮箱、身份证号等敏感信息 |
| 审计日志 | 自动学习的操作全程记录日志,管理员可审阅 |
| 数据隔离 | 个人知识严格隔离,不同用户间不可见(除非管理员提升为共享知识) |