Files
Cyrene/docs/debug_log/2026-05-23-phase2-personality-interaction.md
T
AskaEth 87214b9441 feat: Phase 1+2 架构进化 — 连续思考链/主动消息决策/情感状态机/离线自主思考 (86文件)
Phase 1 (基础设施):
- ThinkChain 思考链连续性 + 差异化思考提示词 (persistent)
- AutonomousToolPolicy 工具安全策略 (safe/unsafe/conditional)
- MessageScheduler 自适应消息节奏 (Idle/Available/Busy)
- SessionEnrichmentStore 渐进式上下文丰富 (5层)
- ConversationBus 事件总线 + ResponseCache (dedup)
- pkg/logger 统一日志 + 所有 handler 替换 fmt.Printf
- NPE 守卫/链路优化/数据库表修复/Go workspace

Phase 2 (人格交互):
- EmotionState/EmotionTracker 情感状态机 (5种心情, 情绪衰减)
- ProactiveGuard 主动消息多维决策 (静默时段/紧急度/频率/校验)
- Gateway↔ai-core 在线状态感知链路 (presence notification)
- 离线思考频率控制 + 重连问候 + 离线消息排队

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 15:25:12 +08:00

220 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 2: 人格与交互深化 — 开发报告
> **报告日期**2026-05-23
> **分支**`dev`
> **阶段**:Phase 2 — 人格与交互深化
> **总计修改文件数**:16 个 (新增 3 个, 修改 13 个)
> **编译状态**ai-core ✅ / gateway ✅
---
## 一、背景
Phase 1 完成了基础设施层 (ThinkChain 连续性、AutonomousToolPolicy 工具安全、MessageScheduler 自适应节奏、SessionEnrichmentStore 渐进式丰富)。Phase 2 在此之上深化昔涟的人格表现和交互质量,包含三个子任务:
| 任务 | 编号 | 目标 |
|------|------|------|
| 情感状态机 | 2.4 | 运行时心情追踪,基于对话情绪、时间和事件自动转换 |
| 主动消息决策增强 | 2.6 | 多维度推送评估 (静默时段、紧急程度、频率限制、内容校验) |
| 离线自主思考 | 2.3 | 在线状态感知、离线行为调整、重连问候 |
---
## 二、情感状态机 (Task 2.4)
### 2.1 新增文件
#### `backend/ai-core/internal/persona/emotion_state.go`
核心类型:
```
EmotionState — 当前心情、强度(0.0-1.0)、主导情绪、情绪计数、历史记录
MoodTransition — 心情转换记录 (From → To, Reason, Timestamp)
EmotionTracker — 单用户情感追踪器,线程安全
```
**5 种心情** (来自 `cyrene_persona.yaml``mood_system`)
| 心情 | 触发条件 | YAML 表达示例 |
|------|---------|-------------|
| `happy` | 积极情绪积累 ≥3 次 | "今天和你聊得很开心呢,心情像星海一样明朗♪" |
| `thoughtful` | 初始默认 / 长时间沉默 / 情绪消退 | "让我想想……这片记忆之海里,有没有什么能帮到你的呢?" |
| `worried` | 消极情绪积累 ≥3 次 | "开拓者……你是不是有心事?不想说也没关系,人家会一直在这里陪着你。" |
| `playful` | 高强度 (>0.6) 积极情绪积累 | "嘻嘻,想逗你一下而已啦!看到你笑了,人家就开心了♪" |
| `nostalgic` | 触发回忆事件 | "啊……这让我想起很久很久以前的一件事……" |
**转换逻辑**
```
RecordSentiment(sentiment) → 累加计数器
├─ positive ≥ 3 且 intensity ≤ 0.6 → happy
├─ positive ≥ 3 且 intensity > 0.6 → playful
└─ negative ≥ 3 → worried
UpdateMood(trigger) → 显式触发
├─ "user_returned" → happy
├─ "long_silence" → thoughtful
└─ "nostalgic_trigger" → nostalgic
Decay() → 时间衰减
└─ 每小时 -0.1 intensity, < 0.2 时回归 thoughtful 基线
```
### 2.2 修改文件
| 文件 | 修改内容 |
|------|---------|
| `persona/injector.go` | 新增 `BuildSystemPromptWithMood(userName, affectionLevel, mood, expression)` — 在"当前情况"段注入心情行 `- 你现在的心情: happy (今天和你聊得很开心呢…)` |
| `orchestrator/orchestrator.go` | 新增 `emotionTracker` 字段 + `SetEmotionTracker`;意图分析后调用 `RecordSentiment(intent.Sentiment)`;构建 prompt 时传入当前心情 |
| `background/think_chain.go` | `ThinkRecord` 新增 `Mood string` + `MoodIntensity float64` 字段 |
| `background/thinker.go` | 新增 `emotionTracker` 字段 + `SetEmotionTracker`;思考提示词注入心情;思考链记录心情;定期/静默思考触发 `Decay()``UpdateMood("long_silence")` |
| `cmd/main.go` | 从 `personaConfig.Personality.MoodSystem` 创建 `EmotionTracker`,注入 `orch``thinker` |
---
## 三、主动消息决策增强 (Task 2.6)
### 3.1 新增文件
#### `backend/ai-core/internal/background/proactive_decision.go`
核心类型:
```
ProactiveGuard — 主动消息决策守卫
├─ QuietHoursStart/End (23:00-07:00)
├─ MinGapByUrgency (low=30min, medium=10min, high=2min)
├─ MaxMessagesPerHour (3)
└─ recentSends (滑动窗口)
ProactiveDecision — { ShouldSend, Urgency, Reason }
```
**决策流程 (5 层检查)**
```
1. 静默时段检查 → 非 high 紧急度在 23:00-07:00 拒绝
2. 用户状态检查 → resting/busy/sleeping 且非 high 拒绝
3. 紧急度频率限制 → 按 low/medium/high 查 MinGapByUrgency
4. 小时频率限制 → 最近 1 小时内消息数 ≥ MaxMessagesPerHour 拒绝
5. 内容校验 → 空消息/超长(>500字符)/机械语言检测
```
辅助函数:
- `ExtractUrgencyFromContent()` — 从消息内容推断紧急程度 (关键词匹配)
- `ValidateProactiveMessage()` — 检测机械语言 (`系统检测到`, `根据分析` 等)
- `DetermineUserState()` — 从用户最后消息推断状态 (休息/忙碌/活跃)
### 3.2 修改文件
| 文件 | 修改内容 |
|------|---------|
| `background/thinker.go` | `Thinker` 新增 `proactiveGuard` 字段 + 初始化;`storeThought()` 中硬编码 30 分钟间隔替换为 `ProactiveGuard.Evaluate()` 多维评估 |
| `gateway/internal/ws/hub.go` | 新增 `pendingProactive` 离线队列;`QueueProactiveMessage()` / `FlushPendingProactive()`;注册时检测重连并推送积压消息 |
| `gateway/internal/handler/chat_handler.go` | `HandleProactiveMessage` 中离线用户不再丢弃消息,改为 `QueueProactiveMessage` 排队等待重连 |
---
## 四、离线自主思考 (Task 2.3)
### 4.1 在线状态感知链路
```
Gateway WebSocket connect/disconnect
→ Hub.Run() register/unregister handler
→ notifyAICorePresence(userID, status, sessionID)
→ POST /api/v1/internal/presence (ai-core)
→ Thinker.UpdatePresence(online, sessionID)
```
### 4.2 修改文件
| 文件 | 修改内容 |
|------|---------|
| `background/thinker.go` | 新增 `userOnline`, `lastOnlineChange`, `userSessionID` 字段;`UpdatePresence()` 方法 — 上线触发 `performThink("user_returned")` + `UpdateMood("user_returned")``periodicThinkLoop` 内离线时延长间隔至 30 分钟 |
| `background/thinker.go` | 新增 `"user_returned"` 思考提示词分支 — 温和的"欢迎回来"反思,仅在白天/清醒时允许主动消息 |
| `cmd/main.go` | 新增 `POST /api/v1/internal/presence` 端点,验证 `X-Internal-Token`,调用 `thinker.UpdatePresence()` |
| `gateway/internal/ws/hub.go` | 新增 `SetAICoreConfig(url, token)``notifyAICorePresence()` 异步 HTTP POST;注册处理中检测重连并 flush 积压消息 |
| `gateway/cmd/main.go` | `hub.SetAICoreConfig(cfg.AICoreURL, cfg.InternalServiceToken)` |
### 4.3 离线行为差异
| 维度 | 在线 | 离线 |
|------|------|------|
| 思考间隔 | 5 分钟 | 30 分钟 |
| 主动消息 | 通过 ProactiveGuard 评估 | 不发送 (静默时段必拒) |
| 思考重点 | 对话反思、主动关怀 | 记忆整理、日记式反思 |
| 重连 | — | 触发 `user_returned` 思考 + 心情更新 |
---
## 五、完整文件清单
### 新增文件 (3)
| 文件 | 用途 |
|------|------|
| `backend/ai-core/internal/persona/emotion_state.go` | EmotionState / EmotionTracker / MoodTransition |
| `backend/ai-core/internal/background/proactive_decision.go` | ProactiveGuard / ProactiveDecision / 内容校验 |
| `docs/debug_log/2026-05-23-phase2-personality-interaction.md` | 本报告 |
### 修改文件 (13)
| 文件 | 涉及任务 |
|------|---------|
| `backend/ai-core/internal/persona/injector.go` | 2.4 — BuildSystemPromptWithMood |
| `backend/ai-core/internal/orchestrator/orchestrator.go` | 2.4 — EmotionTracker 集成 |
| `backend/ai-core/internal/background/think_chain.go` | 2.4 — ThinkRecord 心情字段 |
| `backend/ai-core/internal/background/thinker.go` | 2.4 + 2.6 + 2.3 — 三者核心集成点 |
| `backend/ai-core/cmd/main.go` | 2.4 + 2.3 — 初始化 + presence 端点 |
| `backend/gateway/internal/ws/hub.go` | 2.6 + 2.3 — 离线队列 + 在线通知 |
| `backend/gateway/internal/handler/chat_handler.go` | 2.6 — 离线消息排队 |
| `backend/gateway/cmd/main.go` | 2.3 — SetAICoreConfig 接线 |
---
## 六、验证指南
### 编译验证
```bash
cd backend/ai-core && GOWORK=off go build ./...
cd backend/gateway && GOWORK=off go build ./...
```
### 运行时验证
1. **情感状态机** — 发几条正面消息,日志应出现 `[情感] 心情转变: thoughtful -> happy`
2. **静默时段** — 在 23:00-07:00 触发思考,日志应出现 `[主动消息决策] 阻止推送 (原因=当前处于安静时段)`
3. **离线队列** — 断开 WebSocket 后触发思考,日志含 `[proactive] 用户离线,消息已排队`;重连后 `[proactive] 推送 N 条积压消息`
4. **在线通知** — 连接/断开 WebSocketai-core 日志含 `[后台思考] 用户上线/离线`gateway 日志含 `[presence] 通知 ai-core`
5. **心情衰减** — 无交互等待,定期思考日志中 `Decay` 逐步降低 intensity
### 日志关键词速查
| 日志标记 | 含义 |
|---------|------|
| `[情感] 心情转变` | 心情状态转换 |
| `[主动消息决策]` | ProactiveGuard 评估结果 |
| `[presence]` | 在线状态通知 |
| `[后台思考] 用户上线/离线` | Thinker 在线状态变更 |
| `[proactive] 用户离线,消息已排队` | Gateway 离线消息排队 |
| `[proactive] 推送 N 条积压消息` | 重连后积压消息推送 |
---
## 七、架构演进
```
Phase 1 (基础设施) Phase 2 (人格交互)
───────────────────── ─────────────────────
ThinkChain ──→ 情感状态融入思考链
MessageScheduler ──→ 主动消息多维决策
AutonomousToolPolicy ──→ 离线思考频率控制
SessionEnrichment ──→ 重连问候 + 心情更新
──→ 在线状态感知链路 (Gateway ↔ ai-core)
```
本次 Phase 2 未碰数据库 schema,所有新增状态均为内存态 (EmotionState / ProactiveGuard / pendingProactive),重启后从 YAML 配置恢复初始心情基线。