Appearance
内部开发指南
面向在源码里做二次开发的开发者。 不是用户手册 —— 这里讲的是数据流、机制与"别踩的坑"。来源:
CLAUDE.md+ 实测沉淀。
0. 一句话
Familiars = Electron(Vue3) 前端 → 本地 FastAPI bridge(127.0.0.1:18711) → OpenAI 兼容 LLM + 本地小模型 + 工具系统。后端单进程、Windows-first。
1. 核心数据流
Renderer ──window.familiars API──▶ main.js(preload / IPC)
│ spawn
▼
src.bridge.run (hypercorn HTTPS/2)
│ X-Bridge-Token
┌────────────┴──────────────┐
▼ ▼
DialogueManager / ConversationSession 工具系统 ToolDispatcher
(LLM tool-loop, MAX_TURNS=50) │ ├─ security gate(风险分/审批)
│ │ ├─ browser/shared-Chrome
▼ │ ├─ multimodal/vision
MemoryWriter → workspace/ │ ├─ memory/tools
(Scoping: dialogue/agent/user) │ └─ broker / skill……
▼ ▼
SQLite (familiars.db, WAL) workspace/ 文件树2. Bridge 启动副作用顺序(重要!)
src/bridge/app.py 在 import 时按精确顺序做副作用,别乱改顺序:
- pin
WORKSPACE_ROUTE(仓库根) - 主线程 pin CUDA(Windows WDDM 不允许 worker 线程首触 GPU)
align_all_paths()(路径漂移自动对齐,必须在任何 DialogueManager 读对话前)- import+mount 47 个路由
- CORS + BridgeTokenMiddleware
startuphooks 顺序:broker_workshop bootstrap → anyio 线程限制器 → pool 看门狗 → 浏览器生命周期- 模块级:杀孤儿 GPU 进程 → 预热 embedder/rembg/rewriter/最近的 agent DH → autorun 检查 → rehydrate 监控/cron/技能调度
3. 路径对齐机制(改路径别慌)
- 仓库根漂移:启动时比较所有
dialogue.path前缀与repo_root(),漂移自动改写dialogue.json+turn_*/plan.json+step_*.json,并记录到workspace/.paths_aliases.json。 - 外部目录别名:
python -m src.tools.paths_migrate <old> <new> --record一次性记录,之后每次开机回放;--dry-run先预览,每个改动文件备份为.bak_<ts>。 - 日志文件(
.bridge.log、audit.log)永不改写,保留真实历史。
4. 内存 / VRAM 约定
- 单一 VRAM 准入闸(
src/base/vram_gate.py:4 级优先级、3 级驱逐)。 - MRU/参考上位回调用
DialogueManager.release_memory+ensure_dialogue_loaded(JIT,避免常驻几个亿 token 的 RSS)。 - HTTP 端点:
POST /api/agents/{id}/release-memory;GET /api/memory观测。 - 保持
on_evict约定:凡持有显存/内存的对象都要实现 evict 回调,驱逐时可协作。
5. 工具系统
ToolDispatcher默认注册 15 个工具实例(Daily/DailyMonitor/Base+InputController/Multimodal/Browser/Doc/Memory/System/User/UserSecret/Phone/Skill/SkillWatcher/Broker + 按需run_call_conversation/ask_user_questions/bridge_call)。- 工具 schema 存
workspace/tools.json,按客户端 merge 到src/models/clients/*_client.py。 _CONSULT_TARGETS仍会把consult_doc路由到 doc_tools —— 别删它在 base_client 里的映射。
6. 三大 agent 模型的接线
- AssistantManager(agent 0 / 管理者)持 N 个 Assistant,跑独立的
MANAGER_MODEL做摘要与人设演化。 - ConversationSession + DialogueManager:LLM I/O 层,
MAX_TURNS不再是硬上限(有 turn-budget 升级器)。 - AssistantRouter / TaskDecomposer:多 agent 分工。
7. 测试红线(每一条都踩过代价)
- 真 SQLite(
FAMILIARS_DB_PATH=:memory:),不要 mock 仓库。 - Bridge-route 测试:恢复
sys.modules捕获项;不要reload路由模块。 - Scratch agent 目录回
runs/。 - 浏览器自动化走
familiars_cdp_port()单一共享 Chrome。 - 新增日志要进
KNOWN_LOGS(src/utils/framework_tools.py)—— manager 才能看到。
8. 常见坑(血泪)
| 坑 | 说明 |
|---|---|
uvicorn src.bridge.app:app --reload | 丢 HTTP/2 + worker 线程 race 初始化 CUDA → 崩溃。用 python -m src.bridge.run |
| 两个 router 同 prefix | 先注册的赢(broker_user vs user 曾碰撞)。加 prefix 路由前先想冲突 |
| HKDF info 字符串 | b"familiars-secrets-v1" —— 轮换会失效所有 SECRET.json,须同时迁移 |
workspace/tools.json 里空 parameters | 会让 LLM 看不到该工具。给每个空 schema 加 reason+placeholder |
| 贴一张"为啥不修" | 先查 audit.log 与 .bridge.log,再怀疑代码 —— amend 前先看清事件流 |
9. 下一步
- CLI 命令全表:
../dev/cli.md - REST 面:
../dev/api-bridge.md - 生态开发:
../ecosystem/index.md(Recipe/Flow/Broker)
