add update_inner_state tool, life loop with tools, timeout protection
- update_inner_state: LLM can update its own persistent inner state - inner_state injected into chat loop system prompt (read-only) - Life Loop now uses run_openai_with_tools (full tool access) - Life Loop LLM calls wrapped in 120s tokio::time::timeout - All reqwest clients: 120s timeout (whisper: 60s) - doc/life.md: life loop architecture design doc - todo.md: removed completed items
This commit is contained in:
69
doc/life.md
Normal file
69
doc/life.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Life Loop 设计
|
||||
|
||||
## 核心理念
|
||||
|
||||
小乖不只是一个对话机器人。对话是她跟用户交流的窗口,但 Life Loop 才是她"活着"的地方。
|
||||
|
||||
## 双循环架构
|
||||
|
||||
```
|
||||
Chat Loop (被动) Life Loop (主动)
|
||||
收到消息 → 处理 → 回复 每 30 秒醒来 → 检查 timers
|
||||
context: context:
|
||||
persona persona
|
||||
inner_state (只读) inner_state (读写)
|
||||
对话历史 + scratch timer payload
|
||||
memory_slots 无对话历史
|
||||
tools (全量)
|
||||
决策:
|
||||
- 发消息给某个 chat
|
||||
- 更新 inner_state
|
||||
- 什么都不做
|
||||
|
||||
┌─── SQLite (共享状态层) ───┐
|
||||
│ inner_state │
|
||||
│ timers │
|
||||
│ conversations/messages │
|
||||
│ memory_slots / scratch │
|
||||
│ config │
|
||||
└───────────────────────────┘
|
||||
```
|
||||
|
||||
## 状态层级
|
||||
|
||||
| 层级 | 名称 | 生命周期 | 用途 |
|
||||
|------|------|---------|------|
|
||||
| persona | 人格 | 永久 | 定义小乖是谁 |
|
||||
| inner_state | 内在状态 | 永久,LLM 自更新 | 小乖对当前情况的感知 |
|
||||
| memory_slots | 记忆槽 | 永久,LLM 管理 | 跨会话的关键事实/偏好 |
|
||||
| summary | 对话摘要 | 按 session | 长对话的压缩记忆 |
|
||||
| scratch | 草稿 | session 内 | 当前任务的工作笔记 |
|
||||
|
||||
## Timer 系统
|
||||
|
||||
### 调度格式
|
||||
|
||||
- 相对时间:`5min`, `2h`, `30s`, `1d`
|
||||
- 绝对时间:`once:2026-04-10 09:00`
|
||||
- 周期性:`cron:0 8 * * *`(标准 cron 表达式)
|
||||
|
||||
### 触发流程
|
||||
|
||||
```
|
||||
Life Loop tick
|
||||
→ 扫描 timers 表,找到 next_fire <= now 的
|
||||
→ 构建 LLM 请求:
|
||||
system: persona + inner_state + 当前时间
|
||||
user: [timer] {label}
|
||||
→ 调用 LLM(无工具,轻量)
|
||||
→ 发送回复到 chat
|
||||
→ cron 类型: 计算下次触发时间,更新 next_fire
|
||||
→ 一次性: 删除
|
||||
```
|
||||
|
||||
### 演进方向
|
||||
|
||||
- 给 Life Loop 的 LLM 调用也加工具(查待办、执行命令)
|
||||
- inner_state 自动更新(对话结束后 LLM 反思)
|
||||
- 预设 cron(晨间/晚间报告)
|
||||
- 事件驱动(不只是时间驱动)
|
||||
57
doc/todo.md
57
doc/todo.md
@@ -1,50 +1,37 @@
|
||||
# noc roadmap
|
||||
|
||||
## "会呼吸的助手" — 让 noc 活着
|
||||
|
||||
核心理念:noc 不应该只在收到消息时才被唤醒,而是一个持续运行、有自己节奏的存在。
|
||||
# noc todo
|
||||
|
||||
### 主动行为
|
||||
- [ ] 定时任务 (cron):LLM 可以自己设置提醒、定期检查
|
||||
- [ ] 预设 cron:晨间待办汇总、晚间日记、定期记忆整理
|
||||
- [ ] 事件驱动:监控文件变化、git push、CI 状态等,主动通知
|
||||
- [ ] 晨间/晚间报告:每天自动汇总待办、提醒重要事项
|
||||
- [ ] 情境感知:根据时间、地点、日历自动调整行为
|
||||
|
||||
### 记忆与成长
|
||||
- [x] 持久记忆槽 (memory_slots):100 个跨 session 的记忆槽位,注入 system prompt
|
||||
- [ ] AutoMem:后台定时(如每 10 条消息)自动分析对话,由 LLM 决定 SKIP/UPDATE/INSERT 记忆,无需用户手动触发(参考 luke)
|
||||
- [ ] 分层记忆:核心记忆(身份/原则,始终注入)+ 长期记忆(偏好/事实,RAG 检索)+ scratch(当前任务)(参考 xg 三层 + luke 四层架构)
|
||||
- [ ] 语义搜索:基于 embedding 的记忆检索(BGE-M3/Gemini embedding + Qdrant 向量库)
|
||||
- [ ] 记忆合并:新记忆与已有记忆 cosine ≥ 0.7 时,用 LLM 合并而非插入(参考 xg)
|
||||
- [ ] 二次联想召回:第一轮直接检索 → 用 top-K 结果做第二轮关联检索,去重后合并(参考 xg/luke 2-pass recall)
|
||||
- [ ] 时间衰减:记忆按时间指数衰减加权,近期记忆优先(参考 xg 30 天半衰期)
|
||||
- [ ] 自我反思:定期回顾对话质量,优化自己的行为
|
||||
|
||||
### 知识图谱(参考 luke concept graph)
|
||||
- [ ] 概念图:Aho-Corasick 模式匹配用户消息中的关键概念,自动注入相关知识
|
||||
- [ ] update_concept tool:LLM 可动态添加/更新概念节点及关联关系
|
||||
- [ ] LRU 缓存:内存中保持热门概念,微秒级匹配
|
||||
- [ ] AutoMem:后台定时自动分析对话,LLM 决定 SKIP/UPDATE/INSERT 记忆
|
||||
- [ ] 分层记忆:核心记忆(始终注入)+ 长期记忆(RAG 检索)+ scratch(当前任务)
|
||||
- [ ] 语义搜索:基于 embedding 的记忆检索
|
||||
- [ ] 记忆合并:相似记忆 cosine >= 0.7 时 LLM 合并
|
||||
- [ ] 时间衰减:记忆按时间指数衰减加权
|
||||
- [ ] 自我反思:定期回顾对话质量,优化行为
|
||||
|
||||
### 工具系统
|
||||
- [x] spawn_agent(Claude Code 子代理)
|
||||
- [x] update_scratch / update_memory
|
||||
- [x] send_file / agent_status / kill_agent
|
||||
- [x] 外部脚本工具发现 (tools/ 目录)
|
||||
- [ ] run_code tool:安全沙箱执行 Python/Shell 代码,捕获输出返回(参考 luke run_python)
|
||||
- [ ] gen_image tool:调用图像生成 API(Gemini/FLUX/本地模型)
|
||||
- [ ] gen_voice tool:TTS 语音合成,发送语音消息(参考 luke Elevenlabs / xg Fish-Speech)
|
||||
- [ ] set_timer tool:LLM 可设置延迟/定时任务,到时触发回调(参考 luke timer 系统)
|
||||
- [ ] web_search tool:网页搜索 + 摘要,不必每次都 spawn 完整 agent
|
||||
- [ ] run_code:安全沙箱执行 Python/Shell
|
||||
- [ ] gen_image:图像生成
|
||||
- [ ] web_search:网页搜索 + 摘要(简单场景不必 spawn agent)
|
||||
|
||||
### 感知能力
|
||||
- [ ] 链接预览/摘要
|
||||
- [ ] 语音转文字 (STT):接收语音消息后自动转写(当前 xg 用 FunASR,luke 用 Whisper)
|
||||
|
||||
### 交互体验
|
||||
- [ ] 语音回复 (TTS)
|
||||
- [ ] 流式分句发送:长回复按句号/问号断句分批发送,体验更自然
|
||||
- [ ] 多频道支持:同一 bot 核心逻辑支持 Telegram + WebSocket + HTTP(参考 luke MxN 多路复用架构)
|
||||
- [ ] Typing indicator
|
||||
- [ ] 语音回复(TTS → Telegram voice message)
|
||||
- [ ] Inline keyboard 交互
|
||||
|
||||
### 上下文管理
|
||||
- [ ] 智能上下文分配:system prompt / 记忆 / 历史消息 / 工具输出各占比可配置,预留 60-70% 给工具输出(参考 luke 保守分配策略)
|
||||
- [ ] 对话历史滚动窗口优化:当前 100 条硬上限,可改为 token 预算制
|
||||
- [ ] 智能上下文分配:token 预算制替代硬上限
|
||||
- [ ] Context pruning:只裁工具输出,保留对话文本
|
||||
|
||||
### 可靠性
|
||||
- [ ] API 重试策略(指数退避)
|
||||
- [ ] 用量追踪
|
||||
- [ ] Model failover
|
||||
- [ ] Life Loop / API 调用超时保护
|
||||
|
||||
Reference in New Issue
Block a user