diff --git a/README.md b/README.md index 37b98e5..ce29441 100644 --- a/README.md +++ b/README.md @@ -35,18 +35,113 @@ PicoBot 的设计目标不是“只会聊天”的单进程 Bot,而是一个 5. 生成的 user / assistant / tool / system 消息按真实顺序写入 SQLite 6. OutboundDispatcher 将结果投递到目标通道 +### 2.1 消息流转图 + +```mermaid +sequenceDiagram + autonumber + participant U as User / External Chat + participant C as Channel + participant B as MessageBus + participant P as InboundProcessor + participant SM as SessionManager + participant SES as Session + participant AES as AgentExecutionService + participant AL as AgentLoop + participant T as ToolRegistry + participant DB as SQLite + participant OD as OutboundDispatcher + + U->>C: 输入消息 + C->>B: publish_inbound + B->>P: consume_inbound + P->>SM: handle_message(channel, sender, chat, content) + SM->>SES: active_session(channel) + AES->>SES: ensure_persistent_session / ensure_chat_loaded + AES->>DB: 追加 user / system 消息 + AES->>AL: process(history) + AL->>T: 调用工具 + T-->>AL: 返回 tool result + AL-->>AES: emitted_messages + AES->>DB: 按真实顺序持久化 assistant / tool / assistant + AES->>SES: 安排后台历史压缩 + AES-->>SM: outbound messages + SM-->>P: outbound messages + P->>B: publish_outbound + B->>OD: consume_outbound + OD->>C: dispatch + C-->>U: 最终回复 +``` + +### 2.2 项目架构图 + +```mermaid +flowchart TB + subgraph Edge[接入层] + CLI[CLI Client / WebSocket] + FEI[Feishu Channel] + HTTP[HTTP Health / WS Gateway] + end + + subgraph Gateway[网关与运行时编排] + CM[ChannelManager] + BUS[MessageBus] + IP[InboundProcessor] + OD[OutboundDispatcher] + SSM[SessionManager] + SVC[SessionLifecycle / Message / ScheduledTask Services] + AES[AgentExecutionService] + end + + subgraph Agent[Agent 执行层] + LOOP[AgentLoop] + COMP[ContextCompressor] + SK[SkillRuntime] + TOOLS[ToolRegistry] + PROV[LLM Providers] + end + + subgraph Runtime[持久化与后台能力] + STORE[SessionStore / SQLite] + SCH[Scheduler] + MEM[Memory Maintenance] + end + + CLI --> HTTP + FEI --> CM + HTTP --> CM + CM --> BUS + BUS --> IP + IP --> SSM + SSM --> SVC + SVC --> AES + AES --> LOOP + LOOP --> TOOLS + LOOP --> SK + LOOP --> PROV + AES --> COMP + SSM --> STORE + AES --> STORE + SCH --> BUS + SCH --> SSM + MEM --> STORE + BUS --> OD + OD --> CM +``` + 主要模块如下: -- src/gateway:网关入口、HTTP 健康检查、WebSocket 控制面、Session 池、CLI 会话服务、OutboundDispatcher 与 Agent 执行编排 +- src/gateway:网关生命周期、InboundProcessor、OutboundDispatcher、SessionManager,以及消息执行、调度任务执行、Prompt 注入、历史压缩和记忆维护编排 - src/bus:消息总线队列与消息结构定义,不包含渠道投递逻辑 - src/agent:AgentLoop 与上下文压缩器 - src/providers:不同 LLM Provider 的统一抽象,当前支持 openai 和 anthropic -- src/tools:内置工具集合 +- src/tools:内置工具集合与 ToolRegistry - src/storage:SQLite 持久化实现 - src/channels:渠道适配层,当前已有 CLI 与飞书通道 - src/scheduler:数据库驱动的计划任务调度器 - src/skills:技能发现、加载与运行时管理 -- src/client / src/cli:本地 CLI 客户端和交互命令 +- src/client / src/cli:本地 CLI 客户端、输入命令解析与会话交互 +- src/protocol:WebSocket 入站 / 出站协议结构 ## 3. 消息机制 @@ -142,7 +237,7 @@ PicoBot 会在 ~/.picobot/agent/AGENT.md 维护一份持久化 Agent 画像文 带有 agent_prompt 和 scheduled_system_prompt 标记的 system 消息会被原样保留,避免丢失 Agent 基本设定和调度任务附加约束。 6. 除这些必须保留的 system 消息外,分界点之前的其余消息会被整理成一段待摘要 transcript。 transcript 会保留角色信息;tool 消息还会带上工具名,方便摘要时保留关键操作和结果。 -7. 如果 transcript 本身已经过长,会先按 context_summary_max_chars 截断,再交给模型总结。 +7. 如果 transcript 本身已经过长,会先按当前模型上下文窗口推导出的摘要字符预算截断,再交给模型总结。 8. 摘要调用和主对话使用同一个 provider,提示词明确要求保留: 用户请求、关键标识符、文件路径、URL、工具调用、命令、结果、错误、决策、偏好和当前任务状态。 如果摘要调用失败,会退化为直接截断 transcript,而不会中断主流程。 @@ -270,7 +365,7 @@ PicoBot 不只是“把记忆存进去”,还内置了记忆整理逻辑。 Scheduler 默认内置一个任务: - builtin.memory_maintenance_daily -- 每天本地时间 03:00 运行 +- 默认按本地时区每 4 小时运行一次(cron: 0 */4 * * *) 这个任务以 internal_event 的方式触发 memory_maintenance 事件。触发后,系统会遍历所有已有用户 scope,逐个执行记忆维护,并在全部处理完成后统一更新 AGENT.md 中的“用户记忆摘要”托管区块。 @@ -280,8 +375,12 @@ PicoBot 支持基于文件系统的技能系统,用来给 Agent 注入某一 ### 7.1 技能发现位置 -- 项目级技能:.picobot/skills/*/SKILL.md +当前技能运行时按从低到高优先级合并多个来源,后加载来源可覆盖同名技能: + - 用户级技能:~/.picobot/skills/*/SKILL.md +- 用户 Agent 级技能:~/.picobot/agent/skills/*/SKILL.md +- 项目级技能:.picobot/skills/*/SKILL.md +- 项目 Agent 级技能:.picobot/agent/skills/*/SKILL.md ### 7.2 最小 SKILL.md 格式 @@ -328,7 +427,7 @@ skills 配置示例: { "skills": { "enabled": true, - "sources": ["project", "user"], + "sources": ["user", "user_agent", "project", "project_agent"], "max_index_chars": 4000, "max_listed_skills": 32 } @@ -340,12 +439,14 @@ skills 配置示例: PicoBot 的 Agent 是围绕工具调用构建的。当前默认注册的工具包括: - calculator:简单数学计算 +- time:获取当前时间与时区上下文 - file_read:读取文件 - file_write:写文件 - file_edit:编辑文件 - memory_search:读取长期记忆 - memory_manage:写入 / 更新 / 删除长期记忆 - scheduler_manage:管理调度任务 +- skill_activate:读取并激活某个技能内容 - skill_list:列出技能 - skill_manage:管理技能 - bash:执行 shell 命令 @@ -357,6 +458,7 @@ PicoBot 的 Agent 是围绕工具调用构建的。当前默认注册的工具 - 文件工具适合做代码库和文档操作 - 记忆工具适合维持长期用户画像 - scheduler_manage 允许 Agent 自主创建后续计划任务 +- skill_activate 负责把具体技能正文注入当前任务上下文 - bash / http_request / web_fetch 让 Agent 具备更强的外部交互能力 ## 9. 调度器机制 @@ -406,6 +508,8 @@ silent_agent_task 和 agent_task 使用同一套 Agent 执行能力,但路由 任务定义和状态都会写进 SQLite,所以重启后仍可恢复。 +当前内置任务只默认写入记忆维护任务;`session_cleanup` 作为 `internal_event` 仍然受支持,但如果需要启用,需在配置中显式声明。 + 调度器配置示例: ```json @@ -543,7 +647,8 @@ CLI 中已实现的交互命令包括: "type": "openai", "base_url": "", "api_key": "", - "extra_headers": {} + "extra_headers": {}, + "llm_timeout_secs": 120 } }, "models": { @@ -557,19 +662,21 @@ CLI 中已实现的交互命令包括: "default": { "provider": "default", "model": "default", + "max_tool_iterations": 100, "tool_result_max_chars": 20000, - "context_summary_max_chars": 20000, "context_tool_result_trim_chars": 2000 } }, "gateway": { "host": "0.0.0.0", "port": 19876, + "show_tool_results": false, "agent_prompt_reinject_every": 100 }, "scheduler": { "enabled": true, "tick_resolution_ms": 1000, + "worker_queue_capacity": 128, "misfire_policy": "skip", "jobs": [] } @@ -579,10 +686,10 @@ CLI 中已实现的交互命令包括: 常用配置项: - providers:Provider 连接信息 -- models:模型参数 -- agents:Agent 级别的工具轮次、token 上限和上下文裁剪参数 +- models:模型参数,包括上下文窗口估算所用的 context_window_tokens +- agents:Agent 级别的工具轮次、工具结果裁剪与上下文裁剪参数 - gateway:监听地址、端口、工具结果展示、会话 TTL、Prompt 重注入策略 -- scheduler:调度器开关和任务列表 +- scheduler:调度器开关、worker 队列容量、误触发策略和任务列表 - channels:飞书等通道配置 - skills:技能来源与索引限制 - time.timezone:时区,默认应使用 IANA 时区名,例如 Asia/Shanghai