AskaEth a1d162febf fix(webui): commit dist placeholder so go:embed compiles in clean checkouts
internal/webui/webui.go uses //go:embed all:dist, which fails to compile
when the directory holds zero files. dist/ is gitignored (it is npm build
output), so every fresh clone or worktree could not run go build ./...
until the frontend had been built once.

Track an empty internal/webui/dist/.gitkeep so the embed always has one
matching file. The all: prefix is what makes a dotfile count. Real build
output (index.html, assets/**) stays ignored and is never committed.

The placeholder is forced into the index because .gitignore's dist/ rule
excludes the parent directory with no way to re-include a child.
2026-10-24 19:42:58 +08:00
2026-08-09 20:04:49 +08:00

Cyrene v2 — 昔涟

自托管的「人格化通用智能体运行时」。一个 Go 单二进制,默认以「全能小女友」的人格陪伴你;在聊天/开发/家庭/工作等模式间无感切换;如 OpenClaw 般接入聊天平台(KOOK / 微信 iLink 已接通,QQ OneBot v11 链路已打通但暂不连,Telegram 待凭据);各人格独立记忆与情绪、共享同一套能力。

状态:M0–M12 里程碑主干已落地,现处于「后 M12 增量切片」阶段。每一项能力以本文的三档清单(已实现 / 需凭据·部分 / 未实现)为准,不作整体完成宣称;真实缺口见「已知缺口与路线图」。 | 分支:dev | 设计文档见 DevDocs/00-overview.md


当前能力(按真实状态分三档,不虚标)

状态以代码 + 真机实测为准。标注「需凭据」的项依赖外部凭据 / endpoint 才能达到完整形态;「未实现」一律如实写出,不当「已修」。

✅ 已实现

  • 单二进制、进程内协作 — 框架的所有服务同进程打包、框架仅网关一个对外端口(默认 :8080);框架模块间走进程内接口 + 事件总线,零跨进程 IPC。🔴 2026-10-07 口径补充:该红线只约束框架自身,不约束扩展插件 —— plugins/ 下的渠道适配器与工具、MCP server、以及插件自己拉起的本地伴随服务可以开自己的监听端口、可以有自己的进程形态(原「qq-obv11 反连 server 模式」那条例外随之升格为一般规则的实例)。插件端口仍须:由配置显式给出、默认绑 127.0.0.1、登记日志与审计、不得绕过身份判定
  • 人格化陪伴 — 多人格(configs/personas/*.yaml)/ 情绪状态机 / 好感度;人格 = 身份(不限制能力)、per-persona 记忆隔离、能力全局共享
  • 通用 Agent 运行时 — 多供应商 LLM(per-role 路由 + 降级:主 → 备 → 本地,本地级默认关)、工具调用(8 轮上限)、流式输出、子代理编排(生命周期 / 结果合并 / 并行上限 / 超时 / 防失控)、会话持久化 + 主·次级会话、上下文压缩(预算按模型窗口推导)
  • 记忆系统 — 三类作用域隔离(用户习惯全局共享 / 角色日常他角色只读 / 项目人人读写 + 项目索引分层)、相关性 + 最近度检索、衰减、溯源、RAG;LLM 异步提取(每轮落定后后台提取,手工提取兜底);定期记忆整理(低峰后台任务,只产候选建议、绝不自动改写);入库前审查(D3:新记忆落库前先判定 merge / modify / create / skip,软合并可 revert 回滚)
  • durable execution / checkpoint — 每步落盘快照,崩溃后可从最新 checkpoint 续跑(loadCheckpoint → Step+1;仅「崩溃遗留的在途 run」允许恢复,已落定退出一律重开)
  • IM 渠道插件(内置 5 个,随二进制分发) — KOOK ✅、微信 iLink ✅(扫码绑定 + 绑定确认时自动把主人登记进 owner 白名单,热生效)、QQ OneBot v11(正/反 WS × HTTP,四端组合齐;判主 / 收发 / 语音转写均真机验证过,但主人 2026-10-05 因风控决定暂不连,代码保留)、Telegram(长轮询 / webhook,需 Bot token)、通用 Webhook(入站,已挂网关)
  • 多渠道主会话同步 — 主人私聊(Web / KOOK / 微信 / QQ)汇聚到主会话,Web 端免刷新镜像;群聊 / 陌生人走独立隔离会话,不写记忆、不入主会话上下文
  • 后台思考与主动推送 — 自主思考心跳 + 事件触发(安全域 / 急性事件可穿透安静时段)+ 静默时段降频(THINK_QUIET_INTERVAL_SEC)+ 主动推送限频;自排思考 request_think(她可在一次思考里给自己排下一轮,有窗口次数上限)
  • 技能(Skill) — 目录式 YAML(configs/skills/<id>/skill.yaml,内含示例 daily-brief);渐进披露(清单只给 description,命中才展开正文)+ 工具面收缩(allowed-tools 是能力上限,只收不放);Runner.Run 多步执行可用(步骤拓扑 / 环检测 / 并行上限 / guardrail 强制点)
  • 插件声明的管理页面 — GET /api/v1/admin/panels(按角色过滤的接入点快照)+ POST /api/v1/admin/plugins/{id}/actions/{action}(真执行已登记动作,写动作走 owner/admin + 审计);插件生命周期变化推 WS 帧 panels_changed
  • 网络搜索 — 原生 6 家 provider(SearXNG 本机兜底 / 智谱 / 阿里 IQS / 博查 / 火山·豆包 / 百度千帆)+ 降级链 + 配置面板热重载(改配置即生效、无需重启;会让 web-search 无可用后端的改动会被回滚并报 409)
  • 文件 / 文档进对话 — 上传 → 抽取正文 sidecar → 按预算注入上下文;含 PDF 摄取;引用计数 + 保留期 GC(仍被引用的文件绝不删)
  • 语音 — 云端 STT / TTS 真实接通(阿里云百炼 DashScope:qwen-audio-3.0-asr-flash / cosyvoice-v3-flash),含声音复刻入口;IM 入站语音自动转写;语音落库 + 回放(消息 DTO voice + GET /api/v1/media/{name},支持 Range);不可播格式(QQ AMR)转码成 wav 后再落副本
  • 浏览器工具 — 自研出站 CDP(不发 Runtime.enable,减少被识别面);有头 Chrome + 持久化 profile(过风控口径);动作 open / screenshot / info(owner-only);截图落盘后自动进本轮上下文;插件声明页(B4)已落地
  • MCP 客户端 — 接入官方 MCP SDK(Go);stdio 子进程 / SSE / Streamable HTTP;工具自动发现并注册进能力面
  • 实时全链路流程图(含时间轴) — graph_update 实时帧 + 落盘 flow_graphs 多轮历史 + GET /api/v1/admin/flow/graph(最近一轮 / 指定 turnId / lanes[])+ GET /api/v1/admin/flow/timeline(按时间正序的多轮时间轴,支持 limit / before 分页 + 保留期信号);真并行每路各发自己的帧(不再互相覆盖);Flow 页提供「最近一轮 / 时间轴」两种视图
  • 超级详尽后台管理面板(/admin,路径可配)— 18 个静态模块(仪表盘 / 人格 / 会话 / 记忆 / 知识库 / 插件 / 渠道 / 渠道事件 / IoT / LLM / 自动化 / Agent 监控 / 全链路流程 / 后台思考 / 通知 / 可观测性 / 用户与权限 / 系统设置)+ 插件声明的动态页,统一 RBAC(owner > admin > viewer)+ 审计
  • 系统设置(4 个可写操作) — 吊销全部 API key / 轮换 JWT / 备份 / 恢复(owner-only + 审计 + 前端确认弹窗)
  • 语境感知 UI — 用户端是一个共享页面:单页消息流,每条消息带自己的 mode,气泡按 mode 渲染(chat / code / home / work / docs / voice / vision / agents / settings 共 9 种);统一 Miuix 设计语言 + PWA
  • 多端契约 — 用户侧 REST /api/v1 + 实时 WS /ws/chat + 管理 /api/v1/admin/*,版本化契约 v0.81(权威文档 Docs/api-client.md)
  • 多平台部署 — Linux / Windows / macOS / ARM / Termux;SQLite 默认(纯 Go、单二进制);PG + pgvector 可选增强(配置后真走语义 / 向量路径)

⚠️ 部分实现 / 需凭据

  • 视觉 — 分层路由(主模型 → 工具化视觉 / OCR)与真推理入口已落地;真实视觉 / OCR 模型服务需配 LLM_VISION_MODEL(或 LLM_OCR_MODEL)及凭据。无凭据时降级为主模型直接看图 / 视觉·OCR 工具文本描述
  • 语音的真实双向通话(Web 端) — 上行链路与 STT/TTS 已通;voice 模式的「实时通话」交互仍未接(前端标注 deferred)。edge-tts / espeak 仍是未实现占位(无凭据时走降级链到 silent)
  • 声音复刻 — 代码路径已实现,但仍需主人提供公网可访问的参考音频 URL 方能真建自定义音色
  • 网络搜索的 5 家云端 provider — 除本机 SearXNG 兜底外,智谱 / 阿里 IQS / 博查 / 火山 / 百度千帆均需自配 API key,且尚未真机实测(无凭据);中文查询在本机兜底上的效果有限
  • RAG 语义 / 向量检索 — 默认走内置 n-gram / FTS 向量(dim=256,离线可用);配置 EMBEDDING_API_URL + PG/pgvector 后走真语义路径
  • 微信 iLink 绑定依赖微信侧资格 — 扫码协议已对齐官方并打通;仍需微信账号侧具备 iLink bot 绑定资格(账号环境依赖)
  • QQ OneBot v11 — 代码链路与真机验证都成立,但按主人决定当前不连(风控原因);接回只需配置并在面板启用
  • 主动推送的设备兜底(Getui) — 自建推送服务的 webhook 出口已实现(PUSH_EXPORTER_*);个推(Getui)SDK 未接入,仅预留字段

❌ 未实现(当前不提供)

  • Runner.Run 多步工作流未接进 loop — 技能进入 loop 的目前只有「清单 / 命中展开正文 / 工具面收缩」;多步工作流执行器(Runner.Run / Runner.RunSkill)本身可用且有单测,但模型还不能在对话里直接触发一套多步技能
  • 浏览器 MCP 委派未落地 — browser 工具只提供 open / screenshot / info;click / type / wait / extract 仅在工具描述里指路,实际需经 MCP 浏览器服务补齐(未接)
  • 搜索降级档 B5 未做、浏览器容器 docker 配方(CJK 字体)未落盘、浏览器会话未挂进程关闭链
  • 系统设置:编辑环境变量 / 重启服务 / 检查更新 — 后端未实现,不提供
  • 自排思考 C2 的写路径(面板可调) — 自排的成本可见面(读侧:?trigger= 筛选)已落地;把后台思考调优参数做成面板可保存(SaveBackgroundTuning + admin 端点)的部分仍在做
  • 全链路 P2 剩余 — token / 耗时统计、移动端优化(并行路 / 泳道 / 节点实时日志本身已落地)
  • 群聊类能力 — 冷避、@ 窗口期、戳一戳回应等全部依赖有群聊的平台;因 QQ 暂不连、微信 iLink 只支持绑定微信号私聊,当前暂无活体群聊对象(队列保留,不删)
  • IM 路由主动消息的行 id 回填(design/19 §6.10-2) — 需扩 SendProactive 返回值并改全部 mock,本期不做

快速开始

0. 前置

  • Go 1.26、Node 22(前端构建用)、Docker(可选:PG + pgvector;不用 PG 可仅用 SQLite)。

1. 构建

# 前端(必做一次:go:embed 需要 dist;构建脚本会同步到 internal/webui/dist)
cd frontend/web && npm ci && npm run build && cd ../..

# 后端二进制(Windows)
scripts\ctrl.bat build
# Linux / macOS(无 build 子命令,直接 go build)
go build -ldflags="-s -w" -trimpath -o cyrene ./cmd/cyrene/

scripts\ctrl.bat build 是 Windows 上的权威构建(带 -ldflags="-s -w" -trimpath),产物写到仓库根 cyrene.exe。 换二进制:先 build 到位,再一次 restart(不留空窗)。 纯前端改动不需要重启后端:运行时优先读磁盘 frontend/web/dist(存在即覆盖内嵌 dist),刷新浏览器即可。

2. 启停(本地服务控制)

# Windows
scripts\ctrl.bat start          # 启动(无参 = start;已在跑则跳过)
scripts\ctrl.bat stop           # 停止(先优雅、后强杀)
scripts\ctrl.bat restart        # 停止 + 启动
scripts\ctrl.bat status         # 端口 + PID + /api/v1/health
scripts\ctrl.bat build          # 只构建二进制

# Linux / macOS(等价,无 build)
bash scripts/ctrl.sh start|stop|restart|status

端口取 .env 的 PORT,缺省回落 10080。日志 %USERPROFILE%\cy.log(每次启动前把上一份归档为 cy.log.<时间戳>.bak,保留最近 20 份),PID 文件 %USERPROFILE%\.cyrene.pid。 启动默认分离进程(Start-Process -WindowStyle Hidden):从 Git Bash 调 restart 时请把输出重定向到文件(> /tmp/cy-restart.log 2>&1 < /dev/null),否则 bash 会等管道 EOF 而「不返回」;判定成功要看「新 PID + health ok + 启动日志」,不是看命令退没退出。

3. 配置 .env(复制 .env.example)

# 认证(JWT_SECRET 必填 ≥32,过短启动即 panic)
JWT_SECRET=<≥32 字符随机串>
ADMIN_USERNAME=admin
ADMIN_PASSWORD=<你的密码>

# LLM(LLM_PROVIDER 显式声明协议:openai / anthropic,默认 openai)
LLM_PROVIDER=anthropic
ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic
ANTHROPIC_API_KEY=<key>
ANTHROPIC_MODEL=deepseek-flash
# 或 OpenAI 兼容:LLM_PROVIDER=openai + LLM_BASE_URL / LLM_API_KEY / LLM_MODEL

# 数据库(可选增强:PG + pgvector 向量检索;不配则用 SQLite)
DB_PG_URL=postgres://cyrene:cyrene_pass@localhost:5432/cyrene_ai?sslmode=disable

# 记忆嵌入(真语义;EMBEDDING_API_URL 必须是【完整 /v1/embeddings 端点】,不是 base)
EMBEDDING_API_URL=http://localhost:11434/v1/embeddings
EMBEDDING_MODEL=Qwen3-Embedding-0.6B

4. 可选依赖

# PG + pgvector(可选增强:向量索引走这里)
docker compose -f docker-compose.dev.yml up -d pg

# 本地 embedding(可选:真语义;llama.cpp + Qwen3 GGUF,CPU/GPU)
scripts\embed.bat start|stop|status     # Linux / macOS:见 embed.bat 内注释自行起 llama-server

# 本机 SearXNG 兜底搜索(可选;配置见 scripts/searxng/settings.yml)

scripts/dev-up.sh 是 Linux / macOS 上的一键全流程(PG → llama.cpp embedding → 前端 build → cyrene),约定 llama.cpp 放 ~/apps/llama.cpp/、GGUF 放 ~/.models/、二进制 ~/apps/cyrene/cyrene;已运行的服务自动跳过。

5. 访问

  • 用户端 SPA:http://localhost:8080(按 .env 的 PORT)
  • 管理面板:http://localhost:8080/<ADMIN_PATH>(ADMIN_PATH 默认 admin;REST/admin API 仍是 /api/v1/admin/*,安全靠 JWT + 角色门)

6. 服务端口 / 路径速查

服务 地址 / 路径 说明
Cyrene 网关 http://localhost:8080(.env:PORT) SPA + REST/WS + 面板
PG + pgvector localhost:5432(docker cyrene-pg) 可选;向量索引在 cyrene_ai
llama.cpp embedding http://localhost:11434/v1/embeddings 可选;Qwen3

配置

.env 已冻结(最小化可跑,不加 / 不改 / 不删)

.env 只保证「最小化功能可跑」的引导面,不是配置面。主人 2026-10-06 定红线:

  • 基础键已经定好,以后不准改:不加、不改、不删;模板 .env.example 与 .env 同进退。
  • 新配置一律不进 .env:调优 / 门槛 / 上限 / 开关类参数走 $DATA_DIR/config/**(管理面板可改、热重载)+ 代码内默认值。
  • 既有基础键与既有 env: tag 保持现状(不迁移、不改默认值、不删键)。

想要调优项请走面板(如「LLM 模型」页写 models.json、「渠道管理」页写 channels.json、插件配置写 $DATA_DIR/config/plugins/<plugin-id>.json),或直接改 $DATA_DIR/config/** 下的文件。 口径全文见 DevDocs/design/13 §2.1;AGENTS.md §10 亦载明。

数据目录 DATA_DIR

默认 ./data;显式写 platform(保留字哨兵)则走平台标准数据目录(Windows %APPDATA%\Cyrene、macOS ~/Library/Application Support/Cyrene、Linux ~/.local/share/cyrene)。


Embedding 模型推荐

用于长记忆 / 知识库的语义向量检索(默认不配 = 内置 n-gram 向量,dim=256,离线但质量一般)。 配了 EMBEDDING_API_URL / EMBEDDING_MODEL 后走真语义。维度 = 模型 dim,与向量索引一致;切换模型会改维度,需清空旧向量数据。

模型 dim 大小 推理内存 质量 建议
Qwen3-Embedding-0.6B 1024 Q8_0 639MB / f16 1.2GB ~0.7–1GB ★★★★★(多语言、2025 新、MTEB 榜前列) ⭐ 首选(ModelScope 国内可下 + GGUF)
bge-m3 1024 ~2.2GB(fp16) / ~1.2GB(Q4) ~2–3GB ★★★★★(跨语言标杆) 内存 / GPU 充裕时可用
bge-small-zh-v1.5 512 ~30–100MB ~几十MB ★★★★ 极轻量备选
nomic-embed-text 768 ~270MB ~400–600MB ★★★☆ 可
mxbai-embed-large 768 ~350–670MB ~0.8–1GB ★★★★ 可

首选说明:Qwen3-Embedding-0.6B(阿里通义开源,覆盖 100+ 语言)——有 GGUF、ModelScope(魔搭)国内直连可下(HuggingFace 在国内已不可访问);Q8_0 仅 639MB,内存紧张(如 ~3GB 可用、无独立显存的 UMA GPU)也能跑,质量≈f16。

llama.cpp 能替代 Ollama 吗? 能,且更省内存。llama-server(服务模式)暴露 OpenAI 兼容 /v1/embeddings:

./llama-server -m Qwen3-Embedding-0.6B-Q8_0.gguf --embeddings -ngl 99 --host 127.0.0.1 --port 11434
# 然后 EMBEDDING_API_URL=http://localhost:11434/v1/embeddings 照用(dim=1024;切换前清一次向量表)
  • Ollama:模型管理方便(pull)、开箱即用,但常驻偏重。
  • llama.cpp:单文件更轻、可离线自制 GGUF;但模型要自己下 / 转(无 registry)。只认 GGUF,model.safetensors 不能直接喂。

注意事项

  • 勿用 /tmp 放二进制 / 模型(tmpfs 在内存里);一律 ~/apps/、~/.models/。
  • EMBEDDING_API_URL 必须是完整 /v1/embeddings(不是 base),否则 404。
  • 切换 embedding 模型会改维度(Qwen3=1024,n-gram=256)→ 换模型前清一次向量表:docker exec cyrene-pg psql -U cyrene -d cyrene_ai -c "TRUNCATE vec_items;"。
  • LLM 用 anthropic 协议时填 ANTHROPIC_*;用 openai 兼容时填 LLM_*。LLM_PROVIDER 二选一。

目录结构

Cyrene_v2/
├── cmd/cyrene/            # 唯一入口(wire_*.go 组合根:把各子系统接线 + go:embed 前端)
├── internal/              # 进程内模块(不对外)
│   ├── config/            # .env 加载 + $DATA_DIR/config/** 可变源(面板一等来源)
│   ├── logger/ platform/ db/ bus/ errors/ auth/ user/   # 地基
│   ├── runtime/           # 核心运行时:model / agent / loop / tool / guardrail / trace /
│   │                      #   persist(checkpoint) / memory / embedding / multimodal /
│   │                      #   orchestration / exec / task / flowgraph / documents / voice / capacity
│   ├── persona/ capability/ channel/ iot/ urgency/ contract/
│   ├── services/          # gateway(REST/WS/admin) / automations / backthink / approvalreview / channelbridge
│   └── webui/             # 内嵌前端 dist(go:embed)
├── plugins/               # 一等插件:tools(basic/io/browser) + channels(kook/qq_obv11/telegram/webhook/weixin_ilink)
├── pkg/plugins/sdk/       # 插件 SDK(第三方接入)
├── configs/               # 配置模板:personas/ + users/(主人档案)+ skills/(示例技能)
├── frontend/web/          # React SPA(单页消息流 + mode 渲染器)+ 管理面板(Miuix);构建产物 dist/ 供磁盘热覆盖
├── Docs/                  # 用户文档(进 git):api-client.md(客户端 API 契约)+ archive/
├── DevDocs/               # 开发文档(**不进 git**,本地锚点:设计 / 时间线 / 工作小结 / 审计)
├── data/                  # 运行时数据(DATA_DIR;SQLite / uploads / 面板写入的 *.json)
├── scripts/               # ctrl.bat / ctrl.sh / embed.bat / dev-up.sh / searxng/
└── services/              # 预留(外部服务扩展位)

Docs/(大写 D)进 git;DevDocs/ 被 gitignore,不进 git。*.exe、dist/、data/、.env 等亦不入库(见 .gitignore)。


已知缺口与路线图

不美化:以下是当前真做不了 / 没做完的事。

核心运行时

  1. 🔴 Runner.Run 多步工作流未接进 loop — 技能的多步执行器可用且有单测,但模型还不能在对话里触发一整套多步技能(现只到「清单 / 命中展开正文 / 工具面收缩」)。
  2. 自排思考 C2 的写路径未做 — 自排的成本可见读侧(?trigger= 筛选)已落地,面板可保存的后台思考调优(SaveBackgroundTuning + admin 端点)在做。
  3. 全链路 P2 剩余 — token / 耗时统计、移动端优化。

浏览器 4. 🔴 MCP 委派未落地 — click / type / wait / extract 尚未接通(只在工具描述里指路)。 5. 搜索降级档 B5 未做;容器 docker 配方(CJK 字体)未落盘;浏览器会话未挂进程关闭链。

渠道 6. QQ OneBot v11 暂不连(主人 2026-10-05 因风控决定);Telegram 需 Bot token。群聊类能力(冷避 / @ 窗口 / 戳一戳)因此暂无活体平台可验。 7. 搜索 5 家云端 provider 未真机实测(无 key);微信 iLink 依赖微信侧绑定资格;声音复刻需公网参考音频 URL。 8. 视觉 / OCR 真模型需凭据;edge-tts / espeak 仍是占位。

治理 / 其他 9. 系统设置:编辑环境变量 / 重启服务 / 检查更新 — 后端未实现。 10. Getui(个推)兜底未接入(SDK 未接);待主人自建推送服务。 11. 部分真机端到端未验(如实登记):时间轴真机面板联调、搜索 provider 热重载真机端到端、AMR 落副本生产端到端、graph_update 真并行真机端到端、design/19 §6.8 的 Q1–Q4。 12. Android 客户端另会话推进(跨仓协同事项见 DevDocs,不入本仓库)。


技术栈

层 技术
后端 Go 1.26(单二进制运行时)、进程内事件总线(API 刻意对齐 NATS,便于日后换出进程 transport)、slog(日志带 source 来源标注)
前端 React 19、TypeScript、Vite 6、Tailwind 4、Zustand 5、PWA(Miuix 设计语言)
数据库 SQLite 默认(纯 Go、单二进制);PG + pgvector 可选增强(配置后真生效)
多模态 vision(分层路由:主 / 视觉 / OCR;真模型需凭据,无凭据降级主模型)、voice(DashScope STT/TTS 真实接通 + 降级链;无凭据降级 silent)
LLM 多供应商(OpenAI 兼容 / Anthropic / 本地 / 网关)、per-role 路由 + 降级(主 → 备 → 本地)
插件 / 协议 进程内插件 SDK(pkg/plugins/sdk)、官方 MCP SDK(stdio / SSE / Streamable HTTP)

文档

文档 位置 说明
架构总览 / 重构蓝图 DevDocs/00-overview.md 产品定位、架构、渠道插件、后台面板、阶段计划(本地,不进 git)
开发约束 DevDocs/02-development-constraints.md 编码规范 + 性能要求(本地)
客户端 API Docs/api-client.md 跨平台客户端 API 契约(REST / WS / admin,版本化,当前 v0.81)
开发铁律 AGENTS.md 每会话自动注入;含全球红线(单二进制 / 身份识别 / 前端 Miuix 等)

License

Apache-2.0 © 2026 Aska