双脑架构设计(Dual Brain Architecture)
1. 核心概念
双脑分离是"第二大脑"的底层架构原则。用户产生的所有内容属于个人脑(Personal Brain);从外部互联网采集的所有内容属于网络脑(Network Brain)。两者在数据模型、存储策略、隐私处理、UI 呈现、LLM 路由上完全分离,仅在用户主动"融合查询"时发生交叉。
| 维度 | 个人脑(Personal Brain) | 网络脑(Network Brain) |
|---|---|---|
| 数据来源 | 用户手动输入、笔记、日记、想法、时间胶囊、个人上传文件 | 网页剪藏、RSS 订阅、社交媒体抓取、邮件导入、API 抓取 |
| 隐私级别 | 🔴 最高(敏感,不离开本地设备) | 🟡 中等(公开互联网内容,可脱敏处理) |
| 默认 LLM | 本地模型(Ollama) | 外部模型(OpenAI/Claude/Kimi/千问) |
| 数据所有权 | 用户绝对所有,不可被第三方访问 | 用户所有,但内容本身来自公共领域 |
| 视觉标识 | 暖色调(琥珀色/个人头像) | 冷色调(蓝色/地球图标) |
| 关键词 | 创作、思考、记忆、决策、情感 | 采集、阅读、研究、追踪、验证 |
| 图谱节点 | 实心圆,个人图标 | 空心圆,来源图标 |
| 导出策略 | 完全导出,无限制 | 可导出,但保留来源链 |
2. 数据模型层
2.1 全局 brain_side 枚举
typescript
enum BrainSide {
PERSONAL = 'personal', // 个人脑:用户自己产生的
NETWORK = 'network', // 网络脑:从外部采集的
BOTH = 'both', // 融合状态:双脑查询结果
UNKNOWN = 'unknown' // 系统无法判断时
}2.2 核心实体扩展
typescript
// ==================== 知识单元(Knowledge Unit) ====================
interface KnowledgeUnit {
id: string;
userId: string;
// 双脑标记
brainSide: BrainSide;
// 内容
content: {
raw: string;
processed: string;
type: 'claim' | 'opinion' | 'data' | 'methodology' | 'prediction' | 'diary' | 'thought';
};
// 来源区分
source: {
type: 'manual_input' | 'browser_clip' | 'rss_item' | 'email_import' | 'social_import' | 'file_upload' | 'api_fetch' | 'llm_generated';
url?: string;
title?: string;
author?: string;
publishDate?: Date;
};
// 个人脑特有
personalMeta?: {
isPrivate: boolean; // 是否绝对私密
encryptionLevel: 'none' | 'local_aes' | 'e2e';
diaryEntry?: boolean; // 是否日记条目
thoughtChain?: string[]; // 思维链
};
// 网络脑特有
networkMeta?: {
provenanceChain: SourceNode[]; // 来源血统
crawlTimestamp: Date; // 采集时间
originalHtml?: string; // 原始 HTML(可选)
archiveUrl?: string; // Wayback Machine 存档
};
// 通用字段
tags: string[];
embedding: number[];
createdAt: Date;
updatedAt: Date;
}
// ==================== 笔记(Note)—— 仅个人脑 ====================
interface Note {
id: string;
userId: string;
brainSide: 'personal'; // 笔记只能是个人脑
title: string;
content: string; // TipTap JSON / Markdown
// 双向链接
backlinks: string[]; // 被哪些笔记引用
forwardLinks: string[]; // 引用了哪些笔记
// 个人属性
mood?: MoodSnapshot;
location?: string;
weather?: string;
// 时间胶囊关联
capsuleRefs?: string[]; // 被哪些胶囊引用
createdAt: Date;
updatedAt: Date;
}
// ==================== 时间胶囊(Capsule)—— 仅个人脑 ====================
interface TimeCapsule {
id: string;
userId: string;
brainSide: 'personal'; // 胶囊只能是个人脑
content: {
type: 'text' | 'voice' | 'image' | 'mixed';
body: string;
attachments: Attachment[];
mood: MoodSnapshot;
};
// 封存上下文
sealed: {
at: Date;
context: ContextSnapshot; // 包含当时的个人脑状态快照
fingerprint: string; // 当时的思维指纹版本
};
// 解锁条件
unlock: {
type: 'temporal' | 'eventual' | 'milestone' | 'conditional' | 'compound';
config: UnlockConfig;
status: 'locked' | 'unlocked' | 'opened' | 'revisited';
};
// 对话记录
dialogues: Dialogue[];
// 严格的隐私标记
privacy: {
requireAuth: boolean; // 解锁是否需要额外验证
allowExport: boolean; // 是否允许导出
encryptionLevel: 'local' | 'e2e';
};
}
// ==================== 浏览器剪藏(Clip)—— 仅网络脑 ====================
interface BrowserClip {
id: string;
userId: string;
brainSide: 'network'; // 剪藏只能是网络脑
content: {
title: string;
url: string;
domain: string;
excerpt: string;
fullText: string;
readabilityScore: number; // 阅读难度
};
// 网络来源
source: {
author?: string;
publishDate?: Date;
siteType: 'blog' | 'news' | 'academic' | 'forum' | 'social' | 'wiki' | 'docs' | 'other';
credibilityScore: number; // 0-1
};
// 采集元数据
capture: {
timestamp: Date;
method: 'browser_extension' | 'api_fetch' | 'rss_import' | 'manual_paste';
userAgent?: string;
screenshotUrl?: string;
};
// 反脆弱验证
verification: {
status: 'unverified' | 'checking' | 'confirmed' | 'disputed' | 'debunked';
checks: VerificationCheck[];
consensus: number;
};
// 处理状态
processing: {
extracted: boolean; // 是否提取正文
summarized: boolean; // 是否生成摘要
tagged: boolean; // 是否自动标签
embedded: boolean; // 是否生成向量
};
}
// ==================== RSS 条目(RSSItem)—— 仅网络脑 ====================
interface RSSItem {
id: string;
userId: string;
brainSide: 'network';
feedId: string; // 所属订阅源
content: {
title: string;
summary: string;
fullText?: string;
url: string;
};
source: {
feedName: string;
feedUrl: string;
siteUrl: string;
author?: string;
publishDate: Date;
};
// 阅读状态
reading: {
status: 'unread' | 'read' | 'later' | 'archived';
readAt?: Date;
readingTime?: number; // 预估阅读时间(分钟)
};
// AI 处理
ai: {
summary?: string; // AI 摘要
keyPoints?: string[]; // 关键点
relatedNotes?: string[]; // 关联的个人笔记
};
}
// ==================== 邮件导入(EmailImport)—— 仅网络脑 ====================
interface EmailImport {
id: string;
userId: string;
brainSide: 'network';
content: {
subject: string;
from: string;
to: string[];
body: string;
bodyPlain: string;
attachments: EmailAttachment[];
};
source: {
account: string; // 哪个邮箱账户
imapServer: string;
receivedAt: Date;
messageId: string;
threadId?: string;
};
// 提取内容
extracted: {
tasks: ExtractedTask[];
events: ExtractedEvent[];
contacts: ExtractedContact[];
links: string[];
};
}
// ==================== 注意力活动(AttentionActivity)—— 可区分来源 ====================
interface AttentionActivity {
id: string;
userId: string;
// 活动来源:本地应用 vs 网络浏览器
activitySource: 'local_app' | 'network_browser' | 'unknown';
brainSide?: BrainSide; // 当可关联到具体脑时
description: string;
category: string;
startTime: Date;
endTime?: Date;
// 本地应用活动
localMeta?: {
appName: string;
windowTitle: string;
projectName?: string; // 关联的个人项目
};
// 网络浏览器活动
networkMeta?: {
url: string;
domain: string;
pageTitle: string;
siteCategory: string;
};
focusScore: number;
source: 'manual' | 'browser_extension' | 'desktop_app' | 'ai_detected';
}
// ==================== 知识图谱节点(GraphNode)—— 双脑标记 ====================
interface GraphNode {
id: string;
entityId: string;
entityType: 'note' | 'clip' | 'rss_item' | 'email' | 'knowledge_unit' | 'capsule' | 'concept';
brainSide: BrainSide;
label: string;
color: string; // 个人脑暖色 / 网络脑冷色
icon: string; // 类型图标
// 节点属性
properties: Record<string, any>;
// 向量嵌入
embedding?: number[];
// 时间戳
createdAt: Date;
}
// ==================== 知识图谱边(GraphEdge)—— 可跨脑 ====================
interface GraphEdge {
id: string;
sourceId: string; // 源节点
targetId: string; // 目标节点
// 边的来源脑
sourceBrainSide: BrainSide;
targetBrainSide: BrainSide;
type: 'references' | 'similar' | 'parent' | 'child' | 'tags' | 'mentions' | 'contradicts' | 'supports' | 'derived_from';
strength: number; // 0-1
context: string; // 关联上下文
// 跨脑关联时的特殊标记
crossBrain: boolean; // 是否跨脑连接
crossBrainConfidence: number; // 跨脑关联置信度
createdAt: Date;
}2.3 SQLite 数据库 Schema 扩展
sql
-- ==================== 全局 brain_side 枚举 ====================
-- 在 SQLite 中通过 CHECK 约束实现
-- ==================== 知识单元表扩展 ====================
ALTER TABLE knowledge_units ADD COLUMN brain_side TEXT DEFAULT 'network'
CHECK(brain_side IN ('personal', 'network', 'both', 'unknown'));
-- 创建 brain_side 索引
CREATE INDEX idx_knowledge_units_brain_side ON knowledge_units(user_id, brain_side);
-- 按来源类型索引(区分个人/网络)
CREATE INDEX idx_knowledge_units_source_type ON knowledge_units(source_type);
-- ==================== 笔记表(仅个人脑) ====================
CREATE TABLE notes (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
brain_side TEXT DEFAULT 'personal' CHECK(brain_side = 'personal'),
title TEXT NOT NULL,
content TEXT NOT NULL,
content_format TEXT DEFAULT 'markdown' CHECK(content_format IN ('markdown', 'tiptap_json', 'plain')),
-- 双向链接
backlinks TEXT, -- JSON: string[]
forward_links TEXT, -- JSON: string[]
-- 个人属性
mood_emotion TEXT,
mood_intensity REAL,
mood_energy_level REAL,
location TEXT,
weather TEXT,
-- 时间胶囊关联
capsule_refs TEXT, -- JSON: string[]
-- 隐私
is_private BOOLEAN DEFAULT true,
encryption_level TEXT DEFAULT 'local_aes' CHECK(encryption_level IN ('none', 'local_aes', 'e2e')),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE INDEX idx_notes_user ON notes(user_id);
CREATE INDEX idx_notes_brain_side ON notes(brain_side); -- 始终为 'personal'
-- ==================== 浏览器剪藏表(仅网络脑) ====================
CREATE TABLE browser_clips (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
brain_side TEXT DEFAULT 'network' CHECK(brain_side = 'network'),
-- 内容
title TEXT NOT NULL,
url TEXT NOT NULL,
domain TEXT NOT NULL,
excerpt TEXT,
full_text TEXT,
readability_score REAL,
-- 来源
author TEXT,
publish_date TIMESTAMP,
site_type TEXT CHECK(site_type IN ('blog', 'news', 'academic', 'forum', 'social', 'wiki', 'docs', 'other')),
credibility_score REAL,
-- 采集元数据
capture_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
capture_method TEXT CHECK(capture_method IN ('browser_extension', 'api_fetch', 'rss_import', 'manual_paste')),
user_agent TEXT,
screenshot_url TEXT,
-- 处理状态
extracted BOOLEAN DEFAULT false,
summarized BOOLEAN DEFAULT false,
tagged BOOLEAN DEFAULT false,
embedded BOOLEAN DEFAULT false,
-- 反脆弱验证
verification_status TEXT DEFAULT 'unverified'
CHECK(verification_status IN ('unverified', 'checking', 'confirmed', 'disputed', 'debunked')),
verification_consensus REAL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE INDEX idx_browser_clips_user ON browser_clips(user_id);
CREATE INDEX idx_browser_clips_domain ON browser_clips(domain);
CREATE INDEX idx_browser_clips_verification ON browser_clips(verification_status);
-- ==================== RSS 条目表(仅网络脑) ====================
CREATE TABLE rss_items (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
brain_side TEXT DEFAULT 'network' CHECK(brain_side = 'network'),
feed_id TEXT NOT NULL,
title TEXT NOT NULL,
summary TEXT,
full_text TEXT,
url TEXT NOT NULL,
feed_name TEXT,
feed_url TEXT,
site_url TEXT,
author TEXT,
publish_date TIMESTAMP,
reading_status TEXT DEFAULT 'unread' CHECK(reading_status IN ('unread', 'read', 'later', 'archived')),
read_at TIMESTAMP,
reading_time INTEGER,
ai_summary TEXT,
ai_key_points TEXT, -- JSON: string[]
ai_related_notes TEXT, -- JSON: string[]
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (feed_id) REFERENCES rss_feeds(id)
);
CREATE INDEX idx_rss_items_user ON rss_items(user_id);
CREATE INDEX idx_rss_items_feed ON rss_items(feed_id);
CREATE INDEX idx_rss_items_status ON rss_items(reading_status);
-- ==================== 注意力活动表扩展 ====================
ALTER TABLE attention_activities ADD COLUMN activity_source TEXT DEFAULT 'unknown'
CHECK(activity_source IN ('local_app', 'network_browser', 'unknown'));
ALTER TABLE attention_activities ADD COLUMN brain_side TEXT
CHECK(brain_side IN ('personal', 'network', 'both', 'unknown'));
CREATE INDEX idx_attention_activities_source ON attention_activities(activity_source);
CREATE INDEX idx_attention_activities_brain ON attention_activities(brain_side);
-- ==================== 图谱节点表扩展 ====================
ALTER TABLE graph_nodes ADD COLUMN brain_side TEXT DEFAULT 'unknown'
CHECK(brain_side IN ('personal', 'network', 'both', 'unknown'));
CREATE INDEX idx_graph_nodes_brain ON graph_nodes(brain_side);
-- ==================== 图谱边表扩展 ====================
ALTER TABLE graph_edges ADD COLUMN source_brain_side TEXT DEFAULT 'unknown'
CHECK(source_brain_side IN ('personal', 'network', 'both', 'unknown'));
ALTER TABLE graph_edges ADD COLUMN target_brain_side TEXT DEFAULT 'unknown'
CHECK(target_brain_side IN ('personal', 'network', 'both', 'unknown'));
ALTER TABLE graph_edges ADD COLUMN cross_brain BOOLEAN DEFAULT false;
ALTER TABLE graph_edges ADD COLUMN cross_brain_confidence REAL;
CREATE INDEX idx_graph_edges_cross_brain ON graph_edges(cross_brain);3. API 设计层
3.1 双脑切换 API
typescript
// ==================== 获取当前双脑状态 ====================
GET /api/v1/brain/status
Response: {
currentBrain: 'personal' | 'network' | 'both'; // 当前激活的脑
personalStats: {
totalItems: number; // 个人脑总条目
totalNotes: number;
totalCapsules: number;
storageUsed: number; // 字节
lastSync: Date;
};
networkStats: {
totalItems: number; // 网络脑总条目
totalClips: number;
totalRSS: number;
totalEmails: number;
storageUsed: number;
lastSync: Date;
};
fusionMode: boolean; // 是否融合模式
}
// ==================== 切换当前脑 ====================
POST /api/v1/brain/switch
Request: {
targetBrain: 'personal' | 'network' | 'both';
preserveContext?: boolean; // 是否保留当前上下文
}
Response: {
success: boolean;
currentBrain: 'personal' | 'network' | 'both';
switchedAt: Date;
// 切换后的默认视图
defaultView: string;
}
// ==================== 融合查询(跨脑搜索) ====================
POST /api/v1/brain/fusion-search
Request: {
query: string; // 搜索查询
searchMode: 'semantic' | 'keyword' | 'hybrid';
includePersonal: boolean; // 包含个人脑
includeNetwork: boolean; // 包含网络脑
filters: {
personal?: {
noteTypes?: string[];
dateRange?: [Date, Date];
mood?: string[];
};
network?: {
sourceTypes?: string[];
domains?: string[];
verificationStatus?: string[];
dateRange?: [Date, Date];
};
};
limit: number;
offset: number;
}
Response: {
results: FusionResult[];
totalPersonal: number;
totalNetwork: number;
crossBrainConnections: { // 跨脑关联
personalId: string;
networkId: string;
connectionType: string;
confidence: number;
}[];
}
interface FusionResult {
id: string;
brainSide: BrainSide;
entityType: string;
title: string;
excerpt: string;
relevanceScore: number;
source: string;
createdAt: Date;
// 跨脑关联标记
crossBrainLinks?: {
linkedTo: string; // 关联的另一脑条目ID
linkedBrainSide: BrainSide;
linkType: string;
}[];
}
// ==================== 跨脑关联创建 ====================
POST /api/v1/brain/cross-link
Request: {
sourceId: string;
sourceBrainSide: BrainSide;
targetId: string;
targetBrainSide: BrainSide;
linkType: 'inspired_by' | 'references' | 'contradicts' | 'supports' | 'related' | 'cited_in';
context: string; // 关联上下文说明
}
Response: {
linkId: string;
confidence: number; // AI 计算的关联置信度
createdAt: Date;
}
// ==================== 获取跨脑关联图谱 ====================
GET /api/v1/brain/cross-brain-graph
Query: {
centerNodeId: string; // 中心节点
centerBrainSide: BrainSide;
depth: number; // 关联深度
minConfidence: number; // 最小置信度
}
Response: {
nodes: CrossBrainNode[];
edges: CrossBrainEdge[];
}
interface CrossBrainNode {
id: string;
brainSide: BrainSide;
label: string;
type: string;
color: string; // 个人脑暖色 / 网络脑冷色
size: number; // 节点大小(关联度加权)
}
interface CrossBrainEdge {
source: string;
target: string;
sourceBrainSide: BrainSide;
targetBrainSide: BrainSide;
type: string;
strength: number;
isCrossBrain: boolean;
color: string; // 跨脑边用渐变色
}
// ==================== 个人脑隐私设置 ====================
PUT /api/v1/brain/personal/privacy
Request: {
defaultEncryption: 'none' | 'local_aes' | 'e2e';
autoLockTimeout: number; // 分钟,空闲后自动锁定
exportRequiresAuth: boolean; // 导出是否需要额外认证
llmRoutingPolicy: 'local_only' | 'prefer_local' | 'ask_every_time';
}
Response: {
settings: PersonalPrivacySettings;
}
// ==================== 网络脑来源管理 ====================
GET /api/v1/brain/network/sources
Response: {
sources: NetworkSource[];
}
interface NetworkSource {
id: string;
type: 'rss' | 'email' | 'browser' | 'social' | 'api';
name: string;
url: string;
status: 'active' | 'paused' | 'error';
lastFetch: Date;
totalItems: number;
credibilityThreshold: number; // 最低可信度阈值
autoVerify: boolean; // 是否自动验证
}
POST /api/v1/brain/network/sources
Request: {
type: string;
name: string;
url: string;
config: Record<string, any>;
credibilityThreshold: number;
autoVerify: boolean;
}3.2 现有 API 的 brain_side 参数扩展
typescript
// 所有列表查询 API 增加 brain_side 筛选参数
GET /api/v1/knowledge?brain_side=personal|network|both
GET /api/v1/capsules?brain_side=personal // 胶囊始终 personal
GET /api/v1/attention/activities?brain_side=personal|network
GET /api/v1/graph/nodes?brain_side=personal|network|both
GET /api/v1/graph/edges?cross_brain=true // 仅跨脑关联
// 统计 API 增加双脑维度
GET /api/v1/stats/brain-distribution
Response: {
personal: {
notes: number;
capsules: number;
knowledgeUnits: number;
graphNodes: number;
storageBytes: number;
};
network: {
clips: number;
rssItems: number;
emails: number;
knowledgeUnits: number;
graphNodes: number;
storageBytes: number;
};
crossBrain: {
links: number;
fusionSearches: number;
};
}4. 前端 UI 层
4.1 双脑切换器(Brain Switcher)
┌─────────────────────────────────────────────────────────────────┐
│ 🧠 Molore │
│ ═══════════════════════════════════════════════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ 顶部主导航栏 + 双脑切换器 │ │
│ │ │ │
│ │ [📥 采集] [🔗 图谱] [🧬 认知镜像] [💡 涌现工作室] [🎯 注意力] │ │
│ │ │ │
│ │ ┌────────────────────────────────────────┐ │ │
│ │ │ 🧠 双脑切换器 │ │ │
│ │ │ │ │ │
│ │ │ ┌────────────┐ ┌────────────┐ ┌────┐ │ │ │
│ │ │ │ 🧑💻 个人脑 │ │ 🌐 网络脑 │ │ ⚡ │ │ │ │
│ │ │ │ │ │ │ │融合│ │ │ │
│ │ │ │ 1,247条 │ │ 3,456条 │ │ │ │ │ │
│ │ │ │ 笔记·胶囊 │ │ 剪藏·RSS │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ [激活中] │ │ [点击切换]│ │ │ │ │ │
│ │ │ │ 琥珀色边框 │ │ 蓝色边框 │ │ │ │ │ │
│ │ │ └────────────┘ └────────────┘ └────┘ │ │ │
│ │ │ │ │ │
│ │ │ 当前模式:个人脑优先(敏感数据本地处理) │ │
│ │ │ [切换偏好设置] │ │ │
│ │ └────────────────────────────────────────┘ │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘4.2 双脑切换器交互设计
typescript
// 双脑切换器组件
interface BrainSwitcherProps {
currentBrain: BrainSide;
onSwitch: (brain: BrainSide) => void;
personalStats: BrainStats;
networkStats: BrainStats;
fusionMode: boolean;
}
const BrainSwitcher: React.FC<BrainSwitcherProps> = ({
currentBrain,
onSwitch,
personalStats,
networkStats,
fusionMode
}) => {
return (
<div className="brain-switcher">
<div className="switcher-container">
{/* 个人脑卡片 */}
<motion.div
className={`brain-card personal ${currentBrain === 'personal' ? 'active' : ''}`}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
onClick={() => onSwitch('personal')}
animate={{
borderColor: currentBrain === 'personal' ? '#d29922' : '#30363d',
boxShadow: currentBrain === 'personal'
? '0 0 20px rgba(210, 153, 34, 0.3)'
: 'none'
}}
>
<div className="brain-icon">🧑💻</div>
<div className="brain-name">个人脑</div>
<div className="brain-count">{personalStats.totalItems.toLocaleString()} 条</div>
<div className="brain-types">笔记 · 胶囊 · 想法</div>
<div className="brain-privacy">
<span className="privacy-badge local">🔒 本地优先</span>
</div>
{currentBrain === 'personal' && (
<motion.div
className="active-indicator"
layoutId="activeIndicator"
/>
)}
</motion.div>
{/* 融合模式切换 */}
<div className="fusion-toggle">
<button
className={`fusion-btn ${fusionMode ? 'active' : ''}`}
onClick={() => onSwitch(fusionMode ? 'personal' : 'both')}
>
<motion.div
animate={{ rotate: fusionMode ? 180 : 0 }}
transition={{ duration: 0.3 }}
>
⚡
</motion.div>
<span>{fusionMode ? '融合中' : '融合'}</span>
</button>
</div>
{/* 网络脑卡片 */}
<motion.div
className={`brain-card network ${currentBrain === 'network' ? 'active' : ''}`}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
onClick={() => onSwitch('network')}
animate={{
borderColor: currentBrain === 'network' ? '#58a6ff' : '#30363d',
boxShadow: currentBrain === 'network'
? '0 0 20px rgba(88, 166, 255, 0.3)'
: 'none'
}}
>
<div className="brain-icon">🌐</div>
<div className="brain-name">网络脑</div>
<div className="brain-count">{networkStats.totalItems.toLocaleString()} 条</div>
<div className="brain-types">剪藏 · RSS · 邮件</div>
<div className="brain-privacy">
<span className="privacy-badge cloud">☁️ 云端增强</span>
</div>
{currentBrain === 'network' && (
<motion.div
className="active-indicator"
layoutId="activeIndicator"
/>
)}
</motion.div>
</div>
{/* 当前模式提示 */}
<div className="mode-hint">
{currentBrain === 'personal' && (
<span>🔒 个人脑模式:敏感数据仅由本地模型处理,不上传云端</span>
)}
{currentBrain === 'network' && (
<span>🌐 网络脑模式:可调用外部大模型,自动验证来源可信度</span>
)}
{currentBrain === 'both' && (
<span>⚡ 融合模式:同时搜索个人记忆与网络知识,发现跨域关联</span>
)}
</div>
</div>
);
};4.3 切换后的全局上下文变化
typescript
// 双脑上下文状态
interface BrainContext {
currentBrain: BrainSide;
fusionMode: boolean;
// 各脑的功能可用性
features: {
personal: {
noteCreation: boolean; // 笔记创建
capsuleCreation: boolean; // 胶囊创建
diaryEntry: boolean; // 日记
localLLM: boolean; // 本地 LLM
graphExploration: boolean; // 个人图谱
attentionTracking: boolean; // 注意力追踪(本地应用)
};
network: {
clipImport: boolean; // 剪藏
rssReading: boolean; // RSS 阅读
emailSync: boolean; // 邮件同步
socialAggregation: boolean; // 社交聚合
externalLLM: boolean; // 外部 LLM
verification: boolean; // 知识验证
webSearch: boolean; // 网页搜索
};
};
// 搜索默认范围
searchDefault: {
scope: 'personal' | 'network' | 'both';
prioritize: 'recency' | 'relevance' | 'personal';
};
// LLM 路由默认策略
llmRouting: {
defaultProvider: 'local' | 'external';
sensitiveData: 'local_only' | 'ask_user';
longContext: 'kimi' | 'local';
};
// UI 主题
uiTheme: {
primaryColor: string; // 个人脑: #d29922 网络脑: #58a6ff
accentColor: string;
backgroundTone: 'warm' | 'cool';
};
}
// Zustand Store
const useBrainStore = create<BrainState>((set, get) => ({
currentBrain: 'personal',
fusionMode: false,
switchBrain: (brain) => {
const state = get();
// 切换时执行上下文迁移
if (brain === 'personal') {
set({
currentBrain: 'personal',
fusionMode: false,
uiTheme: { primaryColor: '#d29922', accentColor: '#d29922', backgroundTone: 'warm' },
searchDefault: { scope: 'personal', prioritize: 'personal' },
llmRouting: { defaultProvider: 'local', sensitiveData: 'local_only', longContext: 'local' }
});
} else if (brain === 'network') {
set({
currentBrain: 'network',
fusionMode: false,
uiTheme: { primaryColor: '#58a6ff', accentColor: '#58a6ff', backgroundTone: 'cool' },
searchDefault: { scope: 'network', prioritize: 'relevance' },
llmRouting: { defaultProvider: 'external', sensitiveData: 'ask_user', longContext: 'kimi' }
});
} else if (brain === 'both') {
set({
currentBrain: 'both',
fusionMode: true,
uiTheme: { primaryColor: '#a371f7', accentColor: '#a371f7', backgroundTone: 'warm' },
searchDefault: { scope: 'both', prioritize: 'relevance' },
llmRouting: { defaultProvider: 'external', sensitiveData: 'ask_user', longContext: 'kimi' }
});
}
// 触发全局主题切换事件
document.documentElement.style.setProperty('--accent-primary', get().uiTheme.primaryColor);
},
// 融合查询
fusionSearch: async (query, filters) => {
const response = await fetch('/api/v1/brain/fusion-search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, filters, includePersonal: true, includeNetwork: true })
});
return response.json();
}
}));4.4 左侧边栏的双脑感知
┌────────────────────────────────────────┐
│ 🧑💻 个人脑 │
│ ══════════════════════════════════════ │
│ [切换至网络脑 ▼] │
│ │
│ 📥 最近刷入(个人来源) │
│ ┌──────────────────────────────────┐ │
│ │ 📝 刚刚 快速笔记 │ │
│ │ "关于项目架构的反思..." │ │
│ │ [查看] [编辑] [添加到胶囊] │ │
│ └──────────────────────────────────┘ │
│ │
│ 📤 最近上传(个人文件) │
│ ┌──────────────────────────────────┐ │
│ │ 📄 昨天 个人年度总结.md │ │
│ │ 已解析:12个知识点 │ │
│ │ [查看] [私密标记] │ │
│ └──────────────────────────────────┘ │
│ │
│ ⏳ 即将解锁的胶囊(个人) │
│ ┌──────────────────────────────────┐ │
│ │ 🔒 2027-01-01 解锁 │ │
│ │ "关于职业转型的思考..." │ │
│ │ [7天后解锁] │ │
│ └──────────────────────────────────┘ │
│ │
│ ───────────────────────────────────── │
│ 💡 个人脑统计 │
│ 笔记:245 胶囊:12 想法:89 │
│ 存储:156MB 全部本地加密 ✓ │
│ │
└────────────────────────────────────────┘4.5 知识图谱的双脑可视化
┌─────────────────────────────────────────────────────────────────┐
│ 🔗 知识图谱 > 双脑融合视图 │
│ ═══════════════════════════════════════════════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ [力导向图谱] │ │
│ │ │ │
│ │ 🟡 个人脑节点(实心,暖色) │ │
│ │ 🔵 网络脑节点(空心,冷色) │ │
│ │ 🟣 跨脑关联边(渐变,虚线) │ │
│ │ │ │
│ │ 🟡 │ │
│ │ / \ │ │
│ │ / \ │ │
│ │ 🟡------🟣------🔵 │ │
│ │ \ / \ / │ │
│ │ \ / \ / │ │
│ │ 🟡 🔵🔵 │ │
│ │ │ │
│ │ 图例: │ │
│ │ 🟡 个人笔记 🔵 网页剪藏 🟣 跨脑关联 │ │
│ │ │ │
│ │ 当前显示:个人脑 89 节点,网络脑 156 节点,跨脑关联 23 条 │ │
│ │ [仅看个人脑] [仅看网络脑] [显示跨脑关联] [隐藏孤立节点] │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ 选中节点:「Rust 内存安全」—— 网络脑(剪藏) │ │
│ │ │ │
│ │ 跨脑关联: │ │
│ │ → 🟡 个人笔记「我的 Rust 学习路径」(关联度:0.87) │ │
│ │ → 🟡 个人笔记「系统编程思考」(关联度:0.72) │ │
│ │ → 🟡 时间胶囊「技术选型决策」(关联度:0.65) │ │
│ │ │ │
│ │ [查看跨脑关联详情] [在个人脑中创建关联笔记] │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘5. LLM 路由的双脑策略
typescript
// 双脑感知的 LLM 路由策略
interface DualBrainLLMRouter {
// 根据当前脑选择默认策略
routeByBrain(query: string, brainSide: BrainSide, taskType: string): LLMProvider {
if (brainSide === 'personal') {
// 个人脑:优先本地,保护隐私
return this.routePersonal(query, taskType);
} else if (brainSide === 'network') {
// 网络脑:优先外部,利用能力
return this.routeNetwork(query, taskType);
} else {
// 融合模式:智能选择
return this.routeFusion(query, taskType);
}
}
private routePersonal(query: string, taskType: string): LLMProvider {
// 个人脑路由策略
const sensitivePatterns = [
'日记', '情感', '隐私', '密码', '家庭', '健康', '财务', '决策', '反思'
];
const isSensitive = sensitivePatterns.some(p => query.includes(p));
if (isSensitive) {
// 敏感内容 → 绝对本地
return {
provider: 'local',
model: 'llama3.1:8b',
reason: '个人脑敏感内容,强制本地处理'
};
}
// 非敏感个人内容 → 本地优先,除非能力不足
if (taskType === 'simple_summary' || taskType === 'tagging') {
return { provider: 'local', model: 'llama3.1:8b', reason: '简单任务,本地即可' };
}
// 复杂任务但非敏感 → 询问用户
return { provider: 'ask_user', model: null, reason: '复杂任务,需用户确认是否使用外部模型' };
}
private routeNetwork(query: string, taskType: string): LLMProvider {
// 网络脑路由策略
const routingMap = {
'coding': { provider: 'claude', model: 'sonnet-4.6', reason: '代码任务首选 Claude' },
'chinese_content': { provider: 'kimi', model: 'k2.6', reason: '中文内容首选 Kimi' },
'long_context': { provider: 'kimi', model: 'k2.6', reason: '长文本首选 Kimi 1M 上下文' },
'verification': { provider: 'openai', model: 'gpt-4', reason: '验证任务需要最强推理' },
'summary': { provider: 'kimi', model: 'k2.6', reason: '摘要任务,成本效益最优' },
'quick_qa': { provider: 'local', model: 'llama3.1:8b', reason: '快速问答,本地响应快' }
};
return routingMap[taskType] || { provider: 'kimi', model: 'k2.6', reason: '默认路由' };
}
private routeFusion(query: string, taskType: string): LLMProvider {
// 融合模式:根据查询内容智能判断
// 如果查询涉及个人内容 → 使用外部模型但脱敏处理
// 如果纯网络内容 → 使用外部模型
return { provider: 'kimi', model: 'k2.6', reason: '融合模式,使用外部大模型处理,个人数据已脱敏' };
}
}6. 数据隔离与隐私策略
typescript
// 数据隔离策略
interface DataIsolationPolicy {
// 存储隔离
storage: {
personal: {
location: 'local_only'; // 个人脑数据仅本地存储
encryption: 'aes-256-gcm'; // 强制加密
backup: 'e2e_encrypted'; // 备份也端到端加密
sync: 'optional'; // 同步可选,但必须 E2E
};
network: {
location: 'local_and_cloud'; // 网络脑数据可本地+云端
encryption: 'tls_transit'; // 传输加密即可
backup: 'standard'; // 标准备份
sync: 'automatic'; // 自动同步
};
};
// 处理隔离
processing: {
personal: {
llm: 'local_only'; // 个人脑内容仅本地 LLM 处理
embedding: 'local_model'; // 嵌入用本地模型
analytics: 'on_device'; // 分析在设备上
};
network: {
llm: 'any_available'; // 网络脑可用任何 LLM
embedding: 'any_model'; // 嵌入可用任何模型
analytics: 'cloud_enhanced'; // 分析可云端增强
};
};
// 导出隔离
export: {
personal: {
requiresAuth: true; // 导出需要额外认证
watermark: 'personal_export'; // 添加水印
auditLog: true; // 记录导出日志
};
network: {
requiresAuth: false; // 网络脑导出无需额外认证
watermark: false; // 无需水印
auditLog: false; // 无需审计
};
};
}7. 双脑融合的智能场景
场景 1:跨脑联想(个人笔记 × 网络剪藏)
用户正在写个人笔记"关于微服务架构的反思"...
系统检测到:
- 个人脑:笔记「微服务拆分经验」+ 胶囊「架构决策」
- 网络脑:剪藏「微服务反模式」+ RSS「Service Mesh 趋势」
融合建议:
💡 发现跨脑关联:
- 你的笔记中提到"服务拆分粒度"问题
- 网络剪藏中有 3 篇相关文章讨论此问题
- 建议:查看反模式文章,更新你的决策笔记场景 2:时间胶囊的网络增强
用户创建胶囊:"给1年后的自己——关于技术选型的思考"
系统建议:
- 个人脑:记录你的当前思考
- 网络脑:同时追踪相关技术的新闻和趋势
- 融合:胶囊解锁时,不仅展示你过去的思考,
还展示这一年该技术的发展变化,形成对比场景 3:注意力与内容来源关联
注意力管家发现:
- 用户下午 3-4 点经常浏览网络脑的技术文章
- 但个人脑的深度工作产出在下降
融合建议:
⚠️ 模式检测:
- 你在低能量时段偏向网络脑的被动消费
- 建议:将网络脑阅读安排在上午,
下午保留给个人脑的创作输出8. 实现优先级
| 优先级 | 任务 | 预估时间 | 依赖 |
|---|---|---|---|
| P0 | 数据模型 brain_side 字段 | 1天 | 无 |
| P0 | 双脑切换器 UI 组件 | 1天 | 无 |
| P0 | 左侧边栏双脑感知 | 1天 | 无 |
| P1 | 融合查询 API | 2天 | 向量搜索 |
| P1 | 跨脑关联创建 | 2天 | 图谱引擎 |
| P1 | LLM 路由双脑策略 | 1天 | LLM Router |
| P2 | 双脑可视化图谱 | 3天 | D3.js 图谱 |
| P2 | 数据隔离策略实现 | 2天 | 加密模块 |
| P2 | 自动跨脑联想 | 3天 | 融合查询 |
| P3 | 融合模式高级功能 | 5天 | 全部基础功能 |