Doramagic 项目包 · 项目说明书
minty 项目
生成时间:2026-05-11 23:57:10 UTC
项目介绍
Minty 是一个本地优先的人脉网络记忆系统,旨在帮助用户从多个通讯渠道(WhatsApp、Telegram、邮件、日历、LinkedIn 等)汇总联系人信息,构建统一的人脉知识图谱,并通过 AI 驱动的自然语言查询能力实现"记住所有人"的愿景。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Minty 是一个本地优先的人脉网络记忆系统,旨在帮助用户从多个通讯渠道(WhatsApp、Telegram、邮件、日历、LinkedIn 等)汇总联系人信息,构建统一的人脉知识图谱,并通过 AI 驱动的自然语言查询能力实现"记住所有人"的愿景。
该系统完全本地化运行,不依赖任何云端 API,采用本地 AI 模型(Ollama)或本地 Claude Code CLI 进行智能分析,确保用户数据的隐私安全。资料来源:README.md
核心特性
| 特性 | 描述 |
|---|---|
| 多源数据整合 | 支持 WhatsApp、Telegram、Gmail、日历、LinkedIn 等多种数据源的导入与同步 |
| 本地 AI 驱动 | 使用 Ollama 或 Claude Code CLI,完全离线运行,无云端依赖 |
| 智能匹配 | 跨来源自动合并重复联系人,消除数据孤岛 |
| 自然语言查询 | 通过 MCP 协议支持自然语言的人脉搜索 |
| 关系热度追踪 | 自动计算联系人亲密度与互动频率,识别关系衰减信号 |
| 定期回顾 | 生成"失联联系人"提醒与重连建议 |
资料来源:README.md, ARCHITECTURE.md
系统架构
整体架构
graph TD
A[数据源] --> B[sources/ 导入层]
B --> C[data/<source>/ 原始数据]
C --> D[crm/merge.js 合并]
D --> E[data/unified/ 统一存储]
E --> F[AI 推理层]
E --> G[CRM Web UI]
E --> H[MCP Server]
B1[WhatsApp] --> B
B2[Telegram] --> B
B3[Gmail/Email] --> B
B4[Calendar] --> B
B5[LinkedIn] --> B
B6[Slack] --> B核心模块说明
| 模块 | 文件 | 功能描述 |
|---|---|---|
| 导入层 | sources/*/import.js | 各数据源的独立导入器,写入 data/<source>/ |
| 数据合并 | crm/merge.js | 加载各来源数据,进行规范化、去重,写入 data/unified/contacts.json 和 interactions.json |
| 匹配算法 | crm/match.js | 跨来源联系人匹配逻辑,遵循 MATCHING.md 规范 |
| 数据模式 | crm/schema.js | Contact 和 Interaction 的规范数据结构定义 |
| 查询 CLI | crm/query.js | 命令行工具:npm run stats、npm run search |
| 自然语言查询 | crm/network-query.js | "Ask"视图,支持自然语言提问 |
| 重连建议 | crm/reconnect.js | 识别"关系衰减"联系人并生成重连草稿 |
| AI 适配器 | crm/ai.js | 本地 Claude Code CLI / Ollama 适配器,无云端 API |
| 数据陈旧检测 | crm/staleness.js | 标记陈旧联系人数据,供 UI 告警使用 |
| 同步守护进程 | crm/sync.js | 监视 data/<source>/export/ 目录,自动触发导入器 |
| 高层功能 | calendar.js, digest.js, meeting-debrief.js, goal-retro.js, life-events.js | 基于统一存储的高级功能 |
| 工具函数 | crm/utils.js | 电话/邮箱/姓名规范化、评分辅助、内存联系人索引 |
资料来源:ARCHITECTURE.md
数据模型
系统使用两个核心数据结构:
Contact(联系人)
- 基本信息:姓名、电话、邮箱、组织、职位
- 来源追踪:
sources字段记录每个来源的具体数据 - 关系评分:
relationshipScore基于互动频率计算 - 亲密度:
warmth指标反映关系深度 - 最后联系:
daysSinceContact计算天数
Interaction(互动记录)
- 时间戳与来源
- 内容摘要:
subject、body - 互动类型:会议、消息、通话等
资料来源:crm/schema.js, ARCHITECTURE.md
数据源支持
支持的来源
| 数据源 | 状态 | 导入方式 |
|---|---|---|
| 生产就绪 | 扫码认证、Session 自动恢复 | |
| Telegram | 生产就绪 | Bot Token 认证 |
| Gmail/Email | 生产就绪 | Microsoft Graph API (OAuth) |
| Google Calendar | 生产就绪 | Google Calendar API |
| 实验性 | CSV 导入 + 即将支持自动同步 | |
| Slack | 生产就绪 | Workspace Token |
| SMS | 生产就绪 | iOS 备份解析 |
| WhatsApp Business | 生产就绪 | iOS 备份解析 |
每个数据源独立运行,写入 data/<source>/ 目录。统一存储由 crm/merge.js 从各来源重建。
资料来源:README.md, ARCHITECTURE.md
启动方式
服务模式(推荐)
# 基础服务
npm run service
# 指定用户 UUID
MINTY_USER_UUID=abc npm run service
# 启用定期 GBrain 导出
MINTY_GBRAIN_EXPORT=1 npm run service
服务模式以无头守护进程运行,无 Web UI,适合长期部署。
Web UI 模式
npm run crm
启动后在浏览器访问 http://localhost:3456,可浏览联系人、配置数据源、进行 QA 测试。
Agent 原生模式
# 初始化演示数据
npm run seed:demo
# 自然语言查询
CRM_DATA_DIR=./data-demo npm run agent -- "who can help with crypto insurance"
# 启动 MCP 服务器
CRM_DATA_DIR=./data-demo npm run mcp
MCP 服务器可注册到 OpenClaw 或 Hermes,实现智能体对人脉网络的自然语言访问。
快速网络查询
npm run network:search -- "investors in fintech"
npm run network:changes
npm run network:reconnect
npm run service:status
资料来源:README.md
MCP 工具接口
Minty 提供四个核心 MCP 工具:
| 工具 | 功能 | 示例参数 |
|---|---|---|
search_network | 自然语言搜索人脉网络 | {"query": "investors in London", "limit": 5} |
person_context | 查询特定联系人详情 | {"person": "Alice Müller", "limit": 3} |
workflow_brief | 生成目标导向简报 | {"goal": "Find EU partners", "limit": 5} |
source_health | 检查数据源健康状态 | {"source": "telegram"} |
这些工具通过 scripts/minty-mcp-server.js 暴露,是系统的工具接口规范。
资料来源:hermes/minty-network-memory/SKILL.md
版本与发布
当前版本
最新稳定版本信息记录在 CHANGELOG.md 中,采用语义化版本号 MAJOR.MINOR.PATCH。
发布流程
``bash npm version X.Y.Z --no-git-tag-version ``
``bash git add CHANGELOG.md package.json package-lock.json git commit -m "release: vX.Y.Z" ``
``bash git tag vX.Y.Z git push origin main git push origin v.X.Y.Z ``
- 版本决策:查看
CHANGELOG.md的Unreleased部分,确定版本号 - 更新 CHANGELOG:将
## [Unreleased]替换为## [X.Y.Z] - YYYY-MM-DD - 升级 package.json:
- 提交:
- 打标签推送:
发布工作流自动验证标签与 package.json 的一致性,并从 CHANGELOG.md 提取发布说明创建 GitHub Release。
热修复流程
对于安全或生产级问题:
- 从标签分支:
git checkout -b hotfix/X.Y.Z+1 v.X.Y.Z - 修复代码
- 按标准发布流程升级 PATCH 版本
- 必要时将修复 cherry-pick 回 main 分支
资料来源:RELEASING.md
技术要求
| 要求 | 规格 |
|---|---|
| Node.js 版本 | Node 20 + 22 |
| 包管理器 | npm |
| 可选依赖 | Playwright(LinkedIn 自动同步)、csv-parse |
| AI 后端 | Ollama(qwen2.5:7b 等模型)或 Claude Code CLI |
所有 AI 输出(洞察、摘要、重连草稿、查询排名)均为预计算并缓存于 data/unified/*.json,Web 服务器读取静态文件,请求时无 API 调用。
资料来源:README.md, CHANGELOG.md
数据隐私与许可
- 数据存储:所有数据本地存储于
data/目录 - 隐私保护:支持匿名化导出(
npm run gbrain:export),避免原始联系人/消息泄露 - 许可协议:采用 AGPL-3.0 许可证,开源且允许商业使用
- 商业授权:如需在专有产品中嵌入 Minty,可申请商业许可
资料来源:README.md
贡献指南
欢迎贡献代码。贡献者请先阅读:
- CONTRIBUTING.md — 贡献流程规范
- CODE_OF_CONDUCT.md — 行为准则
- SECURITY.md — 安全报告流程
开发者入门
| 任务 | 起点 |
|---|---|
| 添加新数据源 | 复制 sources/telegram/,参照文件布局 |
| 改进匹配算法 | 阅读 crm/MATCHING.md,修改 crm/match.js,添加测试 fixture |
| UI 开发 | 编辑 crm/ui.html.js 和 crm/server.js,重启 npm run crm |
| 性能优化 | 关注 crm/merge.js 路径,参考 tests/integration/ 的性能测试 |
资料来源:ARCHITECTURE.md
项目愿景
Minty 的核心目标是构建一个"永不遗忘的人脉记忆系统"。系统通过持续整合用户的通讯数据,自动识别联系人关系的变化,并在关键时刻提供智能化的回顾与行动建议。长期愿景是让用户能够专注于建立和维护有意义的人际关系,而不是记忆细节。
项目路线图详见 VISION.md。
资料来源:README.md
资料来源:[README.md](), [ARCHITECTURE.md]()
项目文件结构
Minty 是一个个人关系管理系统(Personal CRM),用于聚合来自多个通讯平台的数据,构建统一的人际关系视图。项目采用模块化架构,将数据导入、合并、搜索和服务层分离,便于扩展和维护。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Minty 是一个个人关系管理系统(Personal CRM),用于聚合来自多个通讯平台的数据,构建统一的人际关系视图。项目采用模块化架构,将数据导入、合并、搜索和服务层分离,便于扩展和维护。
资料来源:ARCHITECTURE.md
顶层目录结构
minty/
├── crm/ # 核心 CRM 服务层
├── sources/ # 各平台数据导入器
├── hermes/ # Hermes 工作流集成
├── scripts/ # 工具脚本
├── data/ # 运行时数据目录(gitignored)
├── docs/ # 文档
└── package.json
核心模块详解
crm/ — 核心服务层
CRM 层负责数据合并、API 服务和前端渲染,是整个系统的中枢。
| 文件 | 职责 |
|---|---|
server.js | HTTP API 服务器,处理所有 /api/* 路由 |
index.js | 入口文件,路由分发 |
merge.js | 多源数据标准化、去重、合并 |
match.js | 跨源匹配算法 |
schema.js | Contact 和 Interaction 的规范数据模型 |
query.js | CLI 工具:npm run stats、npm run search |
network-query.js | 自然语言查询接口 |
reconnect.js | 关系淡化检测与草稿生成 |
ai.js | AI 适配器(本地 Claude Code / Ollama) |
staleness.js | 数据新鲜度评估 |
sync.js | 监听 data/<source>/export/ 目录变化 |
calendar.js | 日历集成 |
digest.js | 每周摘要生成 |
meeting-debrief.js | 会议复盘 |
goal-retro.js | 目标回顾 |
life-events.js | 人生大事记录 |
utils.js | 电话/邮箱/姓名标准化,评分辅助 |
review-server.js | 匹配审核服务器(人工确认) |
资料来源:ARCHITECTURE.md
sources/ — 数据导入器
每个数据源独立运行,向 data/<source>/ 目录写入 JSON 文件。
sources/
├── _shared/ # 共享工具
│ └── progress.js # 统一的进度追踪
├── whatsapp/ # WhatsApp 导入器
├── telegram/ # Telegram 导入器
├── email/ # Email 导入器(Microsoft Graph)
├── google-contacts/ # Google Contacts 同步
├── linkedin/ # LinkedIn CSV 解析
├── sms/ # 短信导入
└── slack/ # Slack 导入
#### 进度追踪机制
sources/_shared/progress.js 提供原子化的进度文件写入:
// 导入器启动时调用
P.startProgress(DATA_DIR, 'email', { step: 'init', message: 'Connecting…' });
// 导入过程中更新
P.updateProgress(DATA_DIR, 'email', {
step: 'messages',
message: 'Fetching via Microsoft Graph…'
});
进度文件格式(.progress.json)包含:step、message、current、total、itemsProcessed、errors、startedAt、updatedAt。
资料来源:sources/_shared/progress.js:1-50
#### Email 导入器
sources/email/import.js 支持两种认证方式:
- Microsoft Graph API — 使用
EMAIL_ACCESS_TOKEN和EMAIL_TOKEN_TYPE=microsoft - 通用 OAuth — 通过
EMAIL_ACCESS_TOKEN环境变量
导入结果写入 data/email/ 目录,包含消息和联系人。
资料来源:sources/email/import.js:50-80
#### Google Contacts 同步
sources/google-contacts/sync-hermes.js 实现基于身份(邮箱/电话)的联系人合并:
function mergeByIdentity(contacts) {
const byKey = new Map();
for (const contact of contacts) {
const key = contact.emails[0] || contact.phones[0] || ...;
// 合并重复联系人
}
return [...byKey.values()];
}
资料来源:sources/google-contacts/sync-hermes.js:30-45
data/ — 运行时数据目录
数据目录结构如下(受 CRM_DATA_DIR 环境变量控制):
data/
├── whatsapp/ chats.json, contacts.json, metadata.json, profile_pics/
├── linkedin/ export/ (用户上传的 ZIP) + 解析后的 CSV
├── telegram/ result.json + 解析结果
├── email/ 按账户分文件夹
├── sms/ 按平台分文件夹
├── google-contacts/ 同步数据
├── unified/ 合并后的统一视图
│ ├── contacts.json # 唯一联系人列表
│ ├── interactions.json # 交互时间线
│ └── match_overrides.json # 手动匹配覆盖
└── goals/ 目标数据
资料来源:ARCHITECTURE.md
hermes/ — 工作流集成
hermes/minty-network-memory/ 包含 Hermes 工作流的技能定义,暴露以下 MCP 工具:
| 工具 | 功能 |
|---|---|
search_network | 自然语言网络搜索 |
person_context | 单个联系人上下文查询 |
workflow_brief | 目标导向的联系人推荐 |
source_health | 数据源健康状态检查 |
资料来源:hermes/minty-network-memory/SKILL.md
scripts/ — 工具脚本
| 脚本 | 用途 |
|---|---|
minty-mcp-server.js | MCP 服务器入口 |
sync-labels.js | GitHub 标签同步 |
seed-dev-data.js | 开发数据生成 |
资料来源:README.md
数据流程架构
graph TD
subgraph 用户操作
A[运行导入器] --> B[source/import.js]
end
subgraph 源数据层
B --> C[data/<source>/]
C --> D[whatsapp/]
C --> E[email/]
C --> F[telegram/]
C --> G[linkedin/]
end
subgraph 合并层
H[crm/merge.js] --> I[标准化]
I --> J[去重匹配]
J --> K[构建时间线]
H -.-> L[data/unified/]
end
subgraph 服务层
M[crm/server.js] --> N[REST API]
M --> O[crm/query.js]
M --> P[crm/network-query.js]
end
subgraph 前端
Q[crm/ui.html.js] --> N
R[Hermes Agent] --> S[MCP Tools]
end
L --> MAPI 路由概览
crm/server.js 提供的主要 REST 端点:
| 方法 | 路由 | 功能 |
|---|---|---|
| GET | /api/contacts | 获取联系人列表 |
| GET | /api/contacts/:id | 获取单个联系人 |
| GET | /api/interactions | 交互时间线 |
| GET | /api/sync/progress | 同步进度 |
| GET | /api/sources/:key/progress | 单源进度 |
| GET | /api/goals | 目标列表 |
| GET | /api/goals/:id/pipeline | 目标联系人管道 |
| GET | /api/goals/:id/retro | 目标回顾 |
| GET | /api/export | 导出数据 |
| POST | /api/export | 创建加密备份 |
数据新鲜度管理
crm/staleness.js 实现数据新鲜度检测:
function getStalenessMessage(source, days) {
if (days === null) return `${label} has never synced`;
if (days === 0) return `${label} synced today`;
if (days <= 7) return `${label} synced ${days} days ago`;
if (days <= 30) return `${label} export is ${days} days old — refresh?`;
return `${label} export is ${days} days old — data may be outdated`;
}
新鲜度等级:
- 高:最近 7 天有同步
- 中:7-30 天未同步
- 低:超过 30 天或从未同步
贡献者指南
新增导入器
- 复制简单导入器模板(如
sources/telegram/) - 写入
data/<your-source>/ - 在
crm/merge.js中添加合并步骤
匹配算法改进
- 阅读
crm/MATCHING.md规范 - 修改
crm/match.js - 在
tests/添加测试用例
UI 开发
- 编辑
crm/ui.html.js修改 SPA - 编辑
crm/server.js调整路由 - 重启
npm run crm以热更新
资料来源:ARCHITECTURE.md
环境变量配置
| 变量 | 默认值 | 说明 |
|---|---|---|
CRM_DATA_DIR | ./data | 数据根目录 |
EMAIL_EXPORT_DIR | - | Email 导出目录 |
EMAIL_ACCESS_TOKEN | - | Graph API 令牌 |
MINTY_USER_UUID | - | 用户 UUID |
AI_BACKEND | claude | AI 后端(ollama/claude) |
模块依赖关系
graph LR
subgraph 数据源
A[WhatsApp] --> G[merge.js]
B[Email] --> G
C[Telegram] --> G
D[LinkedIn] --> G
end
G --> H[unified/contacts.json]
G --> I[unified/interactions.json]
H --> J[server.js]
I --> J
J --> K[ui.html.js]
J --> L[MCP Server]
J --> M[CLI Query]资料来源:[ARCHITECTURE.md]()
架构总览
Minty 是一个本地优先的 CRM 系统,用于聚合来自多个数据源的联系人与交互记录,并通过本地 AI(Claude Code CLI 或 Ollama)生成洞察和关系评分。项目完全离线运行,所有数据存储在本地 data/ 目录,无遥测、无分析、无云端同步。资料来源:README.md
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
项目概述
Minty 是一个本地优先的 CRM 系统,用于聚合来自多个数据源的联系人与交互记录,并通过本地 AI(Claude Code CLI 或 Ollama)生成洞察和关系评分。项目完全离线运行,所有数据存储在本地 data/ 目录,无遥测、无分析、无云端同步。资料来源:README.md
核心模块架构
项目采用模块化架构,主要分为三个顶层目录:
| 模块 | 路径 | 功能描述 |
|---|---|---|
| crm/ | crm/ | 应用主程序 + 确定性的 AI 检索引擎 |
| sources/ | sources/ | 每个数据源的独立导入器 |
| scripts/ | scripts/ | CLI/MCP 入口点,供 OpenClaw、Hermes 等 agent 调用 |
资料来源:README.md
crm/ # 应用核心 + 检索引擎
scripts/ # CLI/MCP 入口
sources/ # 数据源导入器
ee/ # 预留商业功能
data/ # 本地数据(gitignored)
docs/ # 文档 + ADR
tests/ # 单元/集成/e2e 测试
CRM 模块详细架构
CRM 模块是系统的核心,包含以下关键文件:
| 文件 | 功能 |
|---|---|
ui.html.js | 单页应用外壳(HTML/CSS/JS 合一模板) |
merge.js | 加载各源数据、规范化、去重、写入 unified/contacts.json 和 interactions.json |
match.js | 跨源匹配算法,读取 MATCHING.md 规范 |
schema.js | Contact 和 Interaction 的规范记录格式 |
query.js | CLI 工具:npm run stats、npm run search |
network-query.js | 自然语言"Ask"视图 |
reconnect.js | "渐行渐远的人"界面 + 草稿生成 |
ai.js | 本地 Claude Code CLI / Ollama 适配器,无云端 API |
staleness.js | 标记陈旧联系人数据 |
sync.js | 监听 data/<source>/export/ 目录变化并触发导入器 |
calendar.js、digest.js、meeting-debrief.js、goal-retro.js、life-events.js | 基于统一存储构建的高级界面 |
utils.js | 电话/邮箱/姓名规范化、评分辅助函数、内存联系人索引 |
资料来源:ARCHITECTURE.md
数据模型(Schema)
系统定义了规范的联系人与交互记录格式:
// Contact 核心结构
{
id: string,
name: string,
phones: string[],
emails: string[],
资料来源:{ [sourceName]: sourceData },
relationshipScore: number,
daysSinceContact: number,
activeChannels: string[],
// ...
}
// Interaction 核心结构
{
id: string,
timestamp: string,
source: string,
body: string,
subject: string,
participants: string[],
// ...
}
修改数据模型时,应首先编辑 schema.js,其余模块随之更新。资料来源:ARCHITECTURE.md
数据流架构
数据生命周期端到端流程如下:
graph TD
A["用户运行导入器"] --> B["源导入器<br/>sources/<src>/..."]
B --> C["data/<source>/*.json<br/>每源记录"]
C --> D["crm/merge.js"]
D --> E["规范化手机/邮箱/姓名"]
D --> F["跨源去重<br/>crm/match.js, MATCHING.md"]
D --> G["构建统一交互时间线"]
E --> H["data/unified/contacts.json"]
F --> H
G --> I["data/unified/interactions.json"]
H --> J["crm/server.js<br/>REST API"]
I --> J
J --> K["ui.html.js<br/>单页应用"]
J --> L["ai.js<br/>Claude Code CLI / Ollama"]
L --> M["生成洞察、评分、摘要"]
M --> H资料来源:ARCHITECTURE.md
导入器(Sources)架构
每个数据源是独立的导入模块,写入 data/<source>/ 目录。统一存储由 crm/merge.js 重建。
支持的数据源
| 数据源 | 路径 | 说明 |
|---|---|---|
data/whatsapp/ | chats.json, contacts.json, metadata.json, profile_pics/ | |
data/linkedin/ | 用户上传的 ZIP 包 + 解析后的 CSV | |
| Telegram | data/telegram/ | result.json + 解析结果 |
data/email/ | 按账户分文件夹 | |
| SMS | data/sms/ | 按平台分文件夹 |
| Google Contacts | data/google-contacts/ | 同步数据 |
| 统一存储 | data/unified/ | contacts.json, interactions.json, match_overrides.json |
资料来源:ARCHITECTURE.md
导入器进度追踪
所有导入器使用统一的进度文件 .progress.json,包含标准字段:
{
source: string, // 数据源标识
step: string, // 当前步骤
message: string, // 状态消息
current: number, // 当前进度
total: number, // 总数
itemsProcessed: number,
errors: string[],
startedAt: string, // ISO 时间戳
updatedAt: string // ISO 时间戳
}
进度操作函数位于 sources/_shared/progress.js:
startProgress(dataDir, source, initial)— 初始化进度updateProgress(dataDir, source, patch)— 更新进度readProgress(dataDir, source)— 读取进度
资料来源:sources/_shared/progress.js
添加新导入器
添加新数据源的步骤:
- 复制简单导入器作为模板(如
sources/telegram/import.js) - 遵循其文件布局
- 写入
data/<your-source>/ - 在
crm/merge.js中添加合并步骤
资料来源:ARCHITECTURE.md
API 路由体系
crm/server.js 提供完整的 REST API,所有接口前缀为 /api/:
| 方法 | 路径 | 功能 |
|---|---|---|
| GET | /api/contacts | 获取联系人列表 |
| GET | /api/contacts/:id | 获取单个联系人详情 |
| GET | /api/contacts/:id/interactions | 获取联系人交互记录 |
| GET/POST | /api/export | 导入/导出数据 |
| GET | /api/digest | 周报摘要 |
| GET | /api/goals | 目标列表 |
| POST | /api/goals/:id/assign | 分配联系人到目标 |
| GET | /api/goals/:id/pipeline | 目标漏斗视图 |
| GET | /api/goals/:id/retro | 目标回顾 |
| GET | /api/meetings/debriefs/pending | 待处理会议总结 |
| GET/POST | /api/meetings/:id/debrief | 会议总结 |
| GET | /api/sources/:key/progress | 数据源同步进度 |
| GET | /api/sync/progress | 全部数据源进度 |
| GET | /api/notifications | 通知列表 |
| POST | /api/notifications/:type/dismiss | 忽略通知 |
| GET | /api/meta | 元信息(demo 模式、数据目录等) |
资料来源:crm/server.js
数据陈旧性检测
crm/staleness.js 负责检测数据新鲜度,提供两种检测维度:
数据源级别陈旧性
| 陈旧天数 | 严重程度 | 消息 |
|---|---|---|
| 从未同步 | warning | {label} 从未同步 |
| 0 天 | info | {label} 今天已同步 |
| 1 天 | info | {label} 昨天已同步 |
| ≤7 天 | info | {label} {n} 天前同步 |
| ≤30 天 | warning | {label} 导出已 {n} 天 — 需要刷新? |
| >30 天 | error | {label} 导出已 {n} 天 — 数据可能已过时 |
联系人数据置信度
根据来源新鲜度计算联系人数据置信级别:
| 级别 | 条件 |
|---|---|
| high | 有活跃交互且来源新鲜 |
| medium | 有交互但部分来源陈旧 |
| low | 无交互或无来源数据 |
资料来源:crm/staleness.js
AI 后端架构
Minty 刻意避免运行时 LLM 费用,支持两种本地后端:
| 后端 | 配置 | 说明 |
|---|---|---|
| Claude Code CLI | 默认(无配置) | 调用 claude --print,已登录用户免费使用 |
| Ollama | AI_BACKEND=ollama | 完全离线,支持 qwen2.5:7b 等本地模型 |
AI 输出(洞察、摘要、重新联系草稿、查询排名)预计算并缓存于 data/unified/*.json,Web 服务器读取这些静态文件。资料来源:README.md
MCP 集成(Hermes)
Minty 提供 MCP(Model Context Protocol)服务器供 AI Agent 使用,位于 scripts/minty-mcp-server.js:
| 工具 | 功能 |
|---|---|
search_network | 自然语言网络搜索 |
person_context | 查询特定联系人详情 |
workflow_brief | 生成目标导向简报 |
source_health | 检查数据源健康状态 |
// 使用示例
{
"query": "investors in London who know about AI",
"limit": 5
}
Minty 与 Hermes 集成的就绪级别:
| 级别 | 要求 |
|---|---|
| Demo-ready | npm run seed:demo + npm run mcp 可用 |
| Dogfood-ready | npm run memory:refresh 成功,无直接联系方式输出 |
| Hermes-native | 技能已安装,MCP 服务器已注册 |
资料来源:hermes/minty-network-memory/SKILL.md
性能优化要点
大数据集场景下的性能瓶颈通常在合并路径,优化策略:
| 场景 | 建议 |
|---|---|
| 大量联系人 | 优化 crm/merge.js 中的去重算法 |
| 跨源匹配 | 改进 crm/match.js 的 MATCHING.md 规则 |
| UI 响应 | 缓存预计算的 AI 输出 |
| 测试 | 使用 tests/integration/ 的 fixture 性能测试 |
资料来源:ARCHITECTURE.md
贡献指南
开发环境启动
npm run crm # 启动 CRM 服务器(热重载)
npm run seed:demo # 生成演示数据
npm run test # 运行测试套件
代码修改优先级
- 修改数据模型 → 首先编辑
schema.js - 添加新导入器 → 复制
sources/telegram/import.js模板 - 改进匹配算法 → 编辑
crm/match.js,添加tests/fixture - UI 工作 → 编辑
crm/ui.html.js和crm/server.js
资料来源:ARCHITECTURE.md
资料来源:[README.md](https://github.com/sree-sanak/minty/blob/main/README.md)
AI 后端配置
Minty 项目采用本地优先的 AI 策略,不依赖任何云端 API 服务。AI 功能通过 crm/ai.js 模块实现,该模块作为适配器,同时支持 Claude Code CLI 和 Ollama 两种本地推理引擎。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Minty 项目采用本地优先的 AI 策略,不依赖任何云端 API 服务。AI 功能通过 crm/ai.js 模块实现,该模块作为适配器,同时支持 Claude Code CLI 和 Ollama 两种本地推理引擎。
资料来源:ARCHITECTURE.md
架构设计
AI 适配器架构
graph TD
A[用户请求] --> B[crm/server.js]
B --> C{AI 引擎选择}
C -->|Claude Code CLI| D[claude-code-adapter]
C -->|Ollama| E[ollama-adapter]
D --> F[本地 Claude Code 进程]
E --> G[本地 Ollama 服务]
F --> H[结构化响应]
G --> H
H --> I[UI 层渲染]资料来源:ARCHITECTURE.md
设计原则
| 原则 | 说明 |
|---|---|
| 本地化 | 所有 AI 推理在本地执行,无云端数据传输 |
| 隐私优先 | 联系人数据和交互内容不离开用户设备 |
| 离线可用 | 依赖 Ollama 或 Claude Code CLI 的本地安装 |
| 无供应商锁定 | 支持切换不同的本地推理引擎 |
资料来源:ARCHITECTURE.md
MCP 工具集成
网络记忆工具
Minty 通过 MCP(Model Context Protocol)暴露网络记忆能力,供 AI Agent 调用:
{
"tools": {
"search_network": "自然语言搜索联系人",
"person_context": "查询特定人物的关系上下文",
"workflow_brief": "生成目标导向的人物简报",
"source_health": "检查数据源健康状态"
}
}
资料来源:hermes/minty-network-memory/SKILL.md
工具调用示例
// 搜索网络
{ "query": "investors in London who know about AI", "limit": 5 }
// 人物上下文查询
{ "person": "Alice Müller", "limit": 3 }
// 目标简报生成
{ "goal": "Find EU crypto insurance distribution partners", "limit": 5 }
// 数据源健康检查
{ "source": "telegram" }
资料来源:hermes/minty-network-memory/SKILL.md
数据源健康检查
健康状态等级
AI 后端在执行查询前会评估数据源的可信度:
| 状态 | 描述 | AI 可用性 |
|---|---|---|
ready | 数据源正常、可回答问题 | ✅ 可用 |
stale | 数据较旧(超过 7 天未同步) | ⚠️ 有限可用 |
limited | 存在警告(无联系人、无证据等) | ⚠️ 有限可用 |
blocked | 显式请求不可用的数据源 | ❌ 不可用 |
error | 同步错误 | ❌ 不可用 |
资料来源:crm/agent-source-health.js
健康检查流程
graph TD
A[接收源过滤请求] --> B[验证源标识符]
B --> C{源有效?}
C -->|否| D[标记 invalid_source]
C -->|是| E[遍历每个数据源]
E --> F[统计联系人数]
F --> G[统计交互记录数]
G --> H[获取最后同步时间]
H --> I{新鲜度判断}
I -->|fresh| J[status: ready]
I -->|stale| K[status: stale]
I -->|unknown| L[status: limited]
J --> M[生成警告列表]
K --> M
L --> M
D --> M
M --> N[返回 answerable 状态]资料来源:crm/agent-source-health.js
导入进度追踪
AI 功能依赖高质量的数据导入,进度系统为导入过程提供实时反馈:
进度状态模型
{
source: String, // 数据源标识符
step: String, // 当前步骤
message: String, // 人类可读消息
current: Number, // 当前处理项
total: Number, // 总项数
itemsProcessed: Number, // 已处理项数
errors: Array, // 错误列表
startedAt: ISO8601, // 开始时间
updatedAt: ISO8601 // 更新时间
}
资料来源:sources/_shared/progress.js
API 端点
| 端点 | 方法 | 描述 |
|---|---|---|
/api/sources/:key/progress | GET | 获取指定数据源的导入进度 |
/api/sync/progress | GET | 获取所有数据源的同步进度 |
资料来源:ARCHITECTURE.md
数据新鲜度检测
新鲜度阈值
| 条件 | 状态 | 阈值 |
|---|---|---|
| 24 小时内同步 | 新鲜 | fresh |
| 7 天内同步 | 可接受 | stale |
| 超过 7 天 | 过期 | outdated |
资料来源:crm/staleness.js
警告消息示例
"Google Contacts export is 14 days old — data may be outdated"
"Telegram has never synced"
"LinkedIn synced today"
资料来源:crm/staleness.js
摘要生成与目标回顾
每周摘要功能
服务器端 handleGetDigest 处理器读取预生成的摘要文件:
function handleGetDigest(req, res, params, paths) {
try { json(res, JSON.parse(fs.readFileSync(paths.digest, 'utf8'))); }
catch { json(res, null); }
}
资料来源:crm/server.js
目标关联人物排名
AI 系统根据目标关键词对联系人进行相关性排序:
goalSections = goals.map(goal => {
const ranked = rankContactsForGoal(contacts, goal.text, 5);
return {
goalId: goal.id,
goalText: goal.text,
contacts: ranked.map(c => ({
id: c.id,
name: c.name,
company: c.sources?.linkedin?.company || null,
goalRelevance: c.goalRelevance,
meetingBrief: ins ? ins.meetingBrief : null,
}))
};
});
资料来源:crm/server.js
敏感信息保护
数据脱敏机制
进度追踪模块内置敏感信息过滤:
function redactErrorText(value) {
return String(value)
.replace(/^\s*at\s+[^\n]+/gm, '[redacted-stack]')
.replace(/(["'`])[^"'`\n]*[\\/][^"'`\n]*\1/g, '$1[redacted-path]$1')
.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, '[redacted-email]')
.replace(/\bauthorization\s*[:=]\s*Bearer\s+[^\s,;]+/gi, '[redacted-credential]')
// ... 更多脱敏规则
}
资料来源:sources/_shared/progress.js
脱敏规则表
| 模式 | 替换结果 |
|---|---|
| 邮箱地址 | [redacted-email] |
| Bearer 令牌 | Bearer [redacted-credential] |
| API 密钥 | [redacted-credential] |
| 文件路径 | [redacted-path] |
| 堆栈跟踪 | [redacted-stack] |
资料来源:sources/_shared/progress.js
快速开始
前置要求
- 安装 Node.js 20+
- 安装 Claude Code CLI 或 Ollama
- 配置数据源导入
验证 AI 配置
# 启动 MCP 服务器
npm run mcp
# 验证网络记忆功能
npm run agent -- "investors in London"
资料来源:hermes/minty-network-memory/SKILL.md
故障排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| AI 返回空结果 | 数据源未同步 | 运行 npm run sync |
| 源健康检查失败 | 缺少数据源配置 | 检查 .env 配置 |
| 连接超时 | Ollama 服务未启动 | 启动 ollama serve |
| 权限错误 | Claude Code CLI 未授权 | 运行 claude 完成认证 |
相关文档
资料来源:[ARCHITECTURE.md]()
数据源导入
数据源导入是 Minty CRM 的核心功能模块,负责从多种外部平台收集联系人信息和交互记录。每个数据源(Source)都是独立的导入单元,遵循统一的数据写入规范,最终输出到 data/<source/ 目录下的结构化 JSON 文件。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
系统架构
导入器层级结构
┌─────────────────────────────────────────────────────────────┐
│ sources/ 目录结构 │
├─────────────────────────────────────────────────────────────┤
│ whatsapp/export.js 实时 Web 端导入 │
│ linkedin/import.js LinkedIn ZIP 压缩包导入 │
│ linkedin/connect.js LinkedIn 自动同步(实验性) │
│ telegram/import.js Telegram JSON 导出导入 │
│ email/import.js Gmail/IMAP 邮件导入 │
│ google-contacts/import.js Google 通讯录 OAuth 导入 │
│ sms/import.js 短信平台导出导入 │
│ apollo/enrich.js Apollo 联系人丰富化(可选) │
├─────────────────────────────────────────────────────────────┤
│ _shared/progress.js 统一的进度追踪模块 │
└─────────────────────────────────────────────────────────────┘
所有导入器共享 sources/_shared/progress.js 中的进度追踪机制,确保 UI 层能够统一展示各数据源的同步状态。
资料来源:ARCHITECTURE.md
数据流向
graph TD
A[用户启动导入器] --> B[数据源平台]
B --> C[源数据获取]
C --> D[数据解析与标准化]
D --> E[data/<source>/]
E --> F[crm/merge.js]
F --> G[data/unified/]
G --> H[统一联系人视图]
G --> I[交互时间线]资料来源:ARCHITECTURE.md
支持的数据源
| 数据源 | 导入模式 | 认证方式 | 增量支持 | 入口命令 |
|---|---|---|---|---|
| 实时监听 | QR 码配对 | ✅ | npm run whatsapp | |
| 一次性 | 官方数据导出 ZIP | ❌ | npm run linkedin | |
| LinkedIn Sync | 实验性 | 自动化登录 | ✅ | npm run linkedin:connect |
| Telegram | 一次性 | 官方 JSON 导出 | ❌ | npm run telegram |
| Email/Gmail | 增量 | OAuth 2.0 / IMAP | ✅ | OAuth 流程 |
| Google Contacts | 增量 | OAuth 2.0 | ✅ | OAuth 流程 |
| SMS | 一次性 | 平台导出格式 | ❌ | npm run sms |
| Apollo | 可选 | API 密钥 | - | 手动触发 |
资料来源:ARCHITECTURE.md
进度追踪机制
统一进度文件
每个导入器在运行时会向其数据目录写入 .progress.json 文件,记录当前导入进度。
{
"source": "whatsapp",
"step": "messages",
"message": "正在同步 15/32: 产品团队群",
"current": 15,
"total": 32,
"itemsProcessed": 2847,
"startedAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:35:22.456Z"
}
资料来源:sources/_shared/progress.js:1-80
进度步骤定义
| step 值 | 含义 | 典型 message 示例 |
|---|---|---|
init | 初始化 | "Starting…" |
contacts | 正在同步联系人 | "Loading contacts…" |
messages | 正在同步消息/交互 | "Syncing 15/32: 群组名" |
merging | 合并到统一存储 | "Merging into unified store" |
done | 完成 | "Import complete" |
error | 错误 | 错误信息摘要 |
资料来源:sources/_shared/progress.js:50-70
进度状态计算
进度文件中的 active 状态由 step !== 'done' && step !== 'error' 派生而来,用于前端判断同步是否仍在进行中。
WhatsApp 导入
WhatsApp 导入器是唯一采用实时监听模式的源,使用 whatsapp-web.js 库通过 WebSocket 连接手机端应用。
核心流程
- 首次运行:显示 QR 码,用户需在 WhatsApp 手机端扫描
- 会话恢复:后续运行自动复用已存储的会话凭证
- 增量同步:仅拉取上次同步后的新消息
// 关键参数
WHATSAPP_MSG_LIMIT=500 // 单次最多获取消息数(环境变量)
输出文件结构
data/whatsapp/
├── chats.json // 聊天列表元数据
├── contacts.json // 联系人信息
├── metadata.json // 同步会话信息
├── profile_pics/ // 头像缓存目录
└── .progress.json // 进度文件
LinkedIn 导入
ZIP 导出模式
- 用户在 LinkedIn 网站请求数据导出(Settings → Data Privacy → Get a copy of your data)
- 选择 Connections 和 Messages 选项
- 下载 ZIP 文件后拖入 Sources 视图,或指定目录:
LINKEDIN_EXPORT_DIR=/path/to/extracted npm run linkedin
自动同步模式(实验性)
该模式通过自动化浏览器操作实现 ToS 边界附近的登录抓取:
- 使用 headful 浏览器首次登录获取凭证
- 凭证缓存后以 headless 模式复用
- 状态存储在
data/linkedin/目录
资料来源:ARCHITECTURE.md
Telegram 导入
Telegram 导出采用官方 Desktop 客户端的 JSON 格式。
导出步骤
- Telegram Desktop → Settings → Advanced → Export Telegram Data
- 选择 Personal chats 和 Contacts
- 格式选择 JSON
- 将
result.json放入 Sources 视图
TELEGRAM_EXPORT_FILE=/path/to/result.json npm run telegram
解析能力
- 个人聊天记录
- 群组消息(含参与者列表)
- 联系人信息
Email/Gmail 导入
OAuth 认证流程(推荐)
- 用户在 Sources 视图点击 "Connect Gmail"
- 使用 Google OAuth Device Flow 完成授权
- 权限范围为只读访问
需要配置以下环境变量:
GOOGLE_CLIENT_ID=<your-client-id>
GOOGLE_CLIENT_SECRET=<your-client-secret>
IMAP 备选方案
支持任意提供商的 IMAP 协议:
EMAIL_HOST=imap.gmail.com
EMAIL_PORT=993
[email protected]
EMAIL_PASS=app-password
Google Contacts 导入
通过 Google People API 进行 OAuth 增量同步,自动获取用户通讯录中的:
- 姓名
- 电话号码
- 邮箱地址
- 组织信息(公司、职位)
- 地址信息
SMS 导入
SMS 导入器解析平台导出的 XML 格式数据,支持:
- 普通短信(SMS)
- 多媒体消息(MMS)
- 通话记录(Call Log)
解析数据类型
| 类型 | 字段 | 说明 |
|---|---|---|
| SMS/MMS | body, direction, timestamp | 消息内容和方向 |
| MMS | hasMedia, contactName | 含媒体标识 |
| Call Log | callKind, duration | 通话类型和时长 |
资料来源:sources/sms/import.js:60-100
Apollo 联系人丰富化
Apollo 是一个可选的付费数据丰富服务,用于增强现有联系人的公开信息:
- 公司位置
- 职业头衔
- Twitter 链接
- 职业履历
此模块独立于主导入流程,需手动触发:
node sources/apollo/enrich.js
数据合并
merge.js 核心职责
所有导入器完成后,运行 crm/merge.js 执行统一合并:
- 数据标准化:统一电话、邮箱、姓名的格式
- 跨源去重:识别同一人的不同来源记录
- 构建交互时间线:聚合所有源的交互事件
node crm/merge.js
输出文件
data/unified/
├── contacts.json // 统一联系人记录
├── interactions.json // 聚合交互事件
├── match_overrides.json // 手动匹配覆盖
└── group-memberships.json // 群组关系
资料来源:ARCHITECTURE.md
环境变量配置
| 变量名 | 适用源 | 用途 |
|---|---|---|
CRM_DATA_DIR | 全局 | 数据根目录 |
WHATSAPP_MSG_LIMIT | 单次消息拉取上限 | |
LINKEDIN_EXPORT_DIR | ZIP 解压路径 | |
TELEGRAM_EXPORT_FILE | Telegram | JSON 导出文件路径 |
GOOGLE_CLIENT_ID | Gmail/Contacts | OAuth 客户端 ID |
EMAIL_* | IMAP 连接参数 |
命令速查
| 命令 | 功能 |
|---|---|
npm run whatsapp | 启动 WhatsApp 导入器 |
npm run linkedin | 启动 LinkedIn ZIP 导入器 |
npm run telegram | 启动 Telegram 导入器 |
npm run sms | 启动 SMS 导入器 |
npm run crm | 启动 CRM 服务端(含同步 API) |
贡献指南
添加新导入器
- 复制现有简单导入器作为模板(如
sources/telegram/import.js) - 遵循目录结构:
data/<source>/写入 JSON 文件 - 使用
sources/_shared/progress.js报告进度 - 在
crm/merge.js中添加对应的合并逻辑
资料来源:ARCHITECTURE.md
性能优化
当数据集较大时,合并路径通常是性能瓶颈。建议使用 tests/integration/ 中的基于 fixture 的性能测试进行验证。
资料来源:[ARCHITECTURE.md]()
联系人合并与去重
联系人合并与去重是 Minty CRM 的核心功能之一,负责将来自不同数据源(如 Email、LinkedIn、Telegram、Google Contacts 等)的联系人记录整合为统一视图。当用户从多个平台导入数据时,同一个人可能在不同来源中以不同的名字、电话或邮箱形式出现,合并系统通过智能匹配算法识别这些重复记录并将其合并,同时保留各来源的原始信息。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
联系人合并与去重是 Minty CRM 的核心功能之一,负责将来自不同数据源(如 Email、LinkedIn、Telegram、Google Contacts 等)的联系人记录整合为统一视图。当用户从多个平台导入数据时,同一个人可能在不同来源中以不同的名字、电话或邮箱形式出现,合并系统通过智能匹配算法识别这些重复记录并将其合并,同时保留各来源的原始信息。
该模块在架构中处于数据处理的核心位置——所有数据源的导入完成后,最终都会经过合并流程生成 data/unified/contacts.json 和 data/unified/interactions.json,为上层业务功能(如目标追踪、会议总结、人生事件识别)提供统一的联系人数据源。资料来源:ARCHITECTURE.md
核心组件
Minty 的联系人合并与去重系统由以下几个核心文件组成:
| 组件文件 | 职责 | 关键功能 |
|---|---|---|
crm/merge.js | 数据合并主入口 | 加载各源数据、规范化、写入统一存储 |
crm/match.js | 跨源匹配算法 | 根据规则识别潜在重复联系人 |
crm/identity-candidates.js | 身份候选生成 | 生成待匹配的联系人候选对 |
crm/MATCHING.md | 匹配规则规范文档 | 定义匹配逻辑与置信度标准 |
crm/schema.js | 数据模型定义 | 规范 Contact 和 Interaction 的数据结构 |
资料来源:ARCHITECTURE.md
数据流架构
graph TD
A[数据源导入] --> B[sources/email/import.js]
A --> C[sources/linkedin/import.js]
A --> D[sources/telegram/import.js]
A --> E[sources/google-contacts/import.js]
B --> F[data/<source>/]
C --> F
D --> F
E --> F
F --> G[crm/merge.js]
G --> H[match.js 匹配算法]
H --> I[match_overrides.json 人工干预]
I --> G
G --> J[data/unified/contacts.json]
G --> K[data/unified/interactions.json]
J --> L[上层业务功能]
K --> L
L --> M[calendar.js 会议追踪]
L --> N[goal-retro.js 目标回顾]
L --> O[life-events.js 人生事件]
L --> P[digest.js 周报摘要]数据模型
Contact 统一数据结构
合并后的联系人记录包含以下核心字段:
{
id: string, // 唯一标识符
name: string, // 规范化的姓名
phones: string[], // 电话号码数组
emails: string[], // 邮箱数组
资料来源:{ // 各来源的原始数据
[sourceName]: {
name?: string,
phones?: string[],
emails?: string[],
company?: string,
position?: string,
// ... 其他来源特定字段
}
},
relationshipScore: number, // 关系评分 0-100
daysSinceContact: number, // 最后联系天数
activeChannels: string[], // 活跃联系方式
interactionCount: number // 交互次数
}
资料来源:crm/schema.js
Interaction 交互记录结构
{
id: string,
contactId: string,
source: string,
timestamp: string,
type: 'message' | 'meeting' | 'call' | 'email',
subject?: string,
body?: string,
participants?: string[]
}
匹配算法详解
匹配置信度等级
系统采用三级置信度体系判断两个联系人记录是否指向同一人:
| 置信度 | 说明 | 处理方式 | 资料来源 |
|---|---|---|---|
| confirmed | 多个高置信度信号完全吻合 | 自动合并,无需人工确认 | crm/MATCHING.md |
| likely | 存在多个支持信号,证据充分 | 自动合并,打印统计信息 | crm/MATCHING.md |
| possible | 存在一些匹配信号但不够确定 | 跳过合并,列入待审查列表 | crm/MATCHING.md |
匹配信号类型
匹配算法考察以下信号维度:
强信号(权重高):
- 邮箱地址完全匹配
- 电话号码完全匹配
- 多个联系方式组合匹配
中强信号(权重中):
- 姓名相似度(编辑距离)
- 公司名称匹配
- LinkedIn 个人资料 URL 匹配
辅助信号(权重低):
- 地理位置一致性
- 职业/职位相似度
- 共同交互事件
匹配输出示例
[
{
"confidence": "confirmed",
"ids": ["c_0001", "c_0012"],
"reason": "邮箱地址完全一致",
"sources_linked": ["email", "linkedin"]
},
{
"confidence": "likely",
"ids": ["c_0003", "c_0088"],
"reason": "姓名完全匹配,公司一致,LinkedIn 位置匹配",
"sources_linked": ["whatsapp", "linkedin"]
},
{
"confidence": "possible",
"ids": ["c_0105", "c_2341"],
"reason": "名字匹配但该名字非常常见;缺少其他佐证信号",
"sources_linked": ["whatsapp", "linkedin"]
}
]
资料来源:crm/MATCHING.md
合并流程
标准合并流程
graph LR
A[运行各数据源导入器] --> B[npm run email<br/>npm run telegram<br/>npm run linkedin]
B --> C[生成各源原始数据]
C --> D[运行 merge.js]
D --> E{存在 match_overrides?}
E -->|是| F[加载人工干预配置]
E -->|否| G[跳过覆盖加载]
F --> H[按 confirmed/likely<br/>强制合并指定记录]
G --> I[执行匹配算法]
H --> J[生成统一联系人列表]
I --> J
J --> K[写入 unified/contacts.json]
J --> L[写入 unified/interactions.json]
K --> M[生成匹配统计报告]
L --> M关键配置:match_overrides.json
当自动匹配算法无法准确判断,或用户希望手动指定某些记录的合并关系时,可通过 match_overrides.json 进行干预:
{
"confirmed": [
{ "ids": ["c_0001", "c_0012"], "reason": "用户确认为同一人" }
],
"likely": [
{ "ids": ["c_0003", "c_0088"], "reason": "邮箱前缀相同且公司一致" }
],
"possible": [
{ "ids": ["c_0105", "c_2341"], "reason": "待进一步核实" }
]
}
覆盖规则处理逻辑:
| 覆盖类型 | 算法行为 |
|---|---|
| confirmed | 无论算法结果如何,强制将两条记录合并为同一联系人 |
| likely | 将两条记录合并,但在统计报告中标注为"人工确认" |
| possible | 跳过自动合并,标记为需人工审查(通过 npm run review) |
资料来源:crm/MATCHING.md
合并执行命令
基本合并命令
# 标准合并流程
node crm/merge.js
# 带详细输出
npm run merge
# 仅检查匹配状态(不写入)
npm run match:dry-run
完整导入与合并流程
# 1. 导入各数据源
npm run email # 导入 Email 数据
npm run telegram # 导入 Telegram 数据
npm run linkedin # 导入 LinkedIn 数据
# 2. 执行合并
node crm/merge.js
# 3. 查看统计
npm run stats
审查待定匹配
对于置信度为 "possible" 的匹配记录,系统提供交互式审查界面:
npm run review
该命令会列出所有待审查的匹配对,用户可选择确认或拒绝每一条匹配。
资料来源:crm/MATCHING.md
匹配状态管理
进度追踪
合并过程中,系统会通过 sources/_shared/progress.js 模块追踪处理进度:
P.startProgress(DATA_DIR, 'merge', { step: 'init', message: '开始合并…' });
P.updateProgress(DATA_DIR, 'merge', { step: 'matching', message: '执行匹配…', current: 5, total: 10 });
P.updateProgress(DATA_DIR, 'merge', { step: 'merging', message: '合并记录…' });
进度文件存储在 data/.progress/merge.json,包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| step | string | 当前处理阶段 |
| message | string | 状态消息 |
| current | number | 当前进度 |
| total | number | 总任务数 |
| startedAt | string | ISO 时间戳 |
| updatedAt | string | ISO 时间戳 |
| errors | array | 错误列表 |
错误处理
系统内置敏感信息过滤机制,防止在错误日志中泄露凭据或个人信息:
function redactErrorText(value) {
return String(value)
.replace(/^\s*at\s+[^\n]+/gm, '[redacted-stack]')
.replace(/(["'`])[^"'`\n]*[\\/][^"'`\n]*\1/g, '$1[redacted-path]$1')
.replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, '[redacted-email]')
.replace(/\bauthorization\s*[:=]\s*Bearer\s+[^\s,;]+/gi, '[redacted-credential]');
}
资料来源:sources/_shared/progress.js
数据新鲜度与置信度
联系人数据置信度评估
系统会根据数据来源和最后同步时间计算每条联系人的数据置信度:
| 置信度等级 | 条件 | 说明 |
|---|---|---|
| high | 多个活跃来源 + 最近同步 | 数据完整可靠 |
| medium | 单个活跃来源 + 最近同步 | 基本可靠 |
| low | 无交互记录或数据过旧 | 需手动核实 |
function getContactDataConfidence(contact, syncState, now = Date.now()) {
const activeSources = Object.keys(contact.sources || {}).filter(s => contact.sources[s]);
if (activeSources.length === 0) return { level: 'low', reason: '无来源数据' };
// ... 更多评估逻辑
}
资料来源:crm/staleness.js
陈旧数据警告
系统会自动检测数据新鲜度并生成警告:
| 同步状态 | 警告级别 | 用户提示 |
|---|---|---|
| 同步中 | - | - |
| 同步成功(< 24h) | - | "数据最新" |
| 同步成功(1-3天) | warning | "数据可能略旧" |
| 同步成功(> 3天) | error | "数据可能过时" |
| 同步错误 | error | "同步失败,请检查配置" |
扩展开发指南
添加新的数据源导入器
参考 sources/telegram/import.js 的文件结构:
- 创建
sources/<new-source>/import.js - 实现数据抓取和标准化逻辑
- 写入
data/<new-source>/contacts.json - 更新
crm/merge.js添加新数据源加载 - 更新
crm/match.js添加新源的匹配规则
自定义匹配规则
在 crm/match.js 中添加新的匹配信号检测:
// 示例:添加公司域名匹配
function matchByEmailDomain(contactA, contactB) {
const domainsA = contactA.emails.map(e => e.split('@')[1]);
const domainsB = contactB.emails.map(e => e.split('@')[1]);
return domainsA.some(d => domainsB.includes(d));
}
添加测试用例
在 tests/ 目录创建匹配测试:
# 运行匹配相关测试
npm test -- --grep "match"
# 添加新测试文件
# tests/match.test.js
常见问题排查
合并后联系人数量异常减少
可能原因:
- 匹配规则过于激进,将不应合并的记录错误合并
- match_overrides.json 中存在误配置
解决方案:
- 检查
data/unified/中的合并结果 - 审阅
match_overrides.json配置 - 使用
npm run review重新审查匹配决策
预期匹配未被识别
可能原因:
- 数据源格式不规范(如姓名包含特殊字符)
- 缺少共同信号(如双方从未通过邮件交互)
解决方案:
- 规范化导入数据
- 在 match_overrides.json 中添加 confirmed 覆盖
- 手动审查 possible 匹配队列
数据新鲜度显示错误
可能原因:
- 同步状态文件格式不一致
- 未正确写入 lastSyncAt 字段
解决方案:
- 检查
data/unified/sync-state.json - 确保各导入器正确更新同步状态
- 查看
crm/agent-source-health.js诊断输出
相关文档
资料来源:[ARCHITECTURE.md]()
数据存储结构
Minty 项目采用本地优先(Local-first)的架构理念,所有数据均存储在用户本地的文件系统中,不依赖任何云端数据库服务。项目的核心设计原则是"文件系统即数据库",数据通过导入器从各个来源收集,经过去重和合并后,形成统一的视图供上层应用使用。资料来源:[ARCHITECTURE.md]()
继续阅读本节完整说明和来源证据。
概述
Minty 项目采用本地优先(Local-first)的架构理念,所有数据均存储在用户本地的文件系统中,不依赖任何云端数据库服务。项目的核心设计原则是"文件系统即数据库",数据通过导入器从各个来源收集,经过去重和合并后,形成统一的视图供上层应用使用。资料来源:ARCHITECTURE.md
核心设计原则
| 原则 | 说明 |
|---|---|
| 本地优先 | 数据永不离开用户机器,核心功能不涉及任何网络传输 |
| 文件系统即数据库 | 使用 JSON 文件作为持久化存储,无需安装数据库 |
| 增量同步 | 部分导入器支持增量更新,避免重复导出 |
| 原子写入 | 写入操作使用临时文件+重命名确保数据完整性 |
| 可导出加密备份 | 支持生成加密的便携式备份包 |
资料来源:ARCHITECTURE.md
资料来源:[ARCHITECTURE.md]()
MCP 代理集成
MCP(Model Context Protocol)代理集成是 Minty 项目为 AI 代理提供的标准化接口层。通过 MCP 协议,外部代理系统(如 OpenClaw、Claude Code、Ollama)可以直接调用 Minty 的联系人检索和关系管理能力,无需直接访问底层数据文件。 资料来源:[README.md]()
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
MCP(Model Context Protocol)代理集成是 Minty 项目为 AI 代理提供的标准化接口层。通过 MCP 协议,外部代理系统(如 OpenClaw、Claude Code、Ollama)可以直接调用 Minty 的联系人检索和关系管理能力,无需直接访问底层数据文件。 资料来源:README.md
Minty 采用本地优先架构,所有联系人数据存储在本地 data/ 目录中,MCP 服务以独立的 stdio 进程运行,确保数据不离开用户的机器。 资料来源:ARCHITECTURE.md
核心架构
系统组件
graph TD
subgraph 外部代理 ["外部代理系统"]
OC[OpenClaw]
HM[Hermes]
CC[Claude Code CLI]
end
subgraph MCP层 ["MCP 协议层"]
SERVER[scripts/minty-mcp-server.js]
end
subgraph 核心引擎 ["Minty 核心引擎"]
RETRIEVAL[crm/agent-retrieval.js]
MATCH[crm/match.js]
SEARCH[crm/search.js]
end
subgraph 数据存储 ["本地数据存储"]
CONTACTS[data/unified/contacts.json]
INTERACTIONS[data/unified/interactions.json]
end
OC --> SERVER
HM --> SERVER
CC --> SERVER
SERVER --> RETRIEVAL
RETRIEVAL --> MATCH
RETRIEVAL --> SEARCH
MATCH --> CONTACTS
SEARCH --> INTERACTIONSMCP 服务入口
scripts/minty-mcp-server.js 是 MCP 服务的核心入口文件,负责注册所有可用的工具并处理代理请求。服务以 stdio 模式运行,适合与 AI 代理进行本地集成。 资料来源:hermes/minty-network-memory/SKILL.md
可用工具
MCP 服务暴露四个核心工具,供外部代理调用:
| 工具名称 | 功能描述 | 主要参数 |
|---|---|---|
search_network | 自然语言网络搜索 | query, limit, source/sources |
person_context | 查询特定联系人详情 | person, limit |
workflow_brief | 生成目标导向简报 | goal, limit |
source_health | 检查数据源健康状态 | source/sources/query |
search_network
用于自由形式的网络查询,返回排名靠前的联系人及其关联证据。
{
"query": "investors in London who know about AI",
"limit": 5
}
支持按来源过滤:
{
"query": "people I discussed Telegram bots with",
"source": "telegram",
"limit": 5
}
person_context
查询特定联系人的详细信息,包括关系上下文、亲密度评分和证据。
{
"person": "Alice Müller",
"limit": 3
}
workflow_brief
生成以目标为导向的简报,帮助代理找到能够帮助完成特定任务的人。
{
"goal": "Find EU crypto insurance distribution partners",
"limit": 5
}
source_health
在执行来源特定查询前进行预检查,确保数据源处于可用状态。
{ "source": "telegram" }
{ "sources": ["telegram", "slack"] }
{ "query": "who from Telegram knows DeFi?" }
配置与部署
环境变量
| 变量名 | 说明 | 默认值 |
|---|---|---|
CRM_DATA_DIR | 数据目录路径 | ./data |
MINTY_USER_UUID | 用户唯一标识 | 自动生成 |
AI_BACKEND | AI 后端类型 | claude |
AI 后端选择
Minty 支持两种本地 AI 后端:
- Claude Code CLI(默认):调用
claude --print进行推理,免费但会将提示发送至 Anthropic 服务器 - Ollama:通过设置
AI_BACKEND=ollama启用,支持本地模型如qwen2.5:7b,完全离线运行
资料来源:README.md
启动 MCP 服务
# 基础启动
npm run mcp
# 指定数据目录
CRM_DATA_DIR=./data-demo npm run mcp
# 服务模式(守护进程)
npm run service
MINTY_USER_UUID=abc npm run service
与外部代理集成
OpenClaw + Hermes 集成
完整的集成配置文档位于 docs/OPENCLAW_HERMES.md。核心步骤包括:
- 注册
scripts/minty-mcp-server.js为 stdio MCP 服务器 - 配置代理系统连接到本地 MCP 端点
- 设置数据目录环境变量
{
"mcpServers": {
"minty": {
"command": "node",
"args": ["/root/.hermes/workspace/minty/scripts/minty-mcp-server.js"],
"timeout": 60,
"connect_timeout": 20
}
}
}
资料来源:hermes/minty-network-memory/SKILL.md
Claude Code 代理支持
Claude Code 代理可以直接通过 MCP 工具访问联系人网络:
CRM_DATA_DIR=./data-demo npm run agent -- "who can help with crypto insurance"
演示模式
使用演示数据快速验证集成是否正常工作:
npm run seed:demo
npm run mcp
npm run agent -- "investors in London"
资料来源:README.md
就绪状态检查
Minty 提供三个就绪级别用于评估集成状态:
| 级别 | 描述 | 验证命令 |
|---|---|---|
| Demo-ready | 演示数据可用 | npm run seed:demo && npm run mcp |
| Dogfood-ready | 真实本地数据可用 | npm run memory:refresh |
| Hermes-native | 完整集成就绪 | npm run hermes:doctor |
执行健康检查:
npm run hermes:doctor
资料来源:hermes/minty-network-memory/SKILL.md
数据安全与隐私
MCP 服务运行在本地,所有联系人数据存储在用户本地磁盘的 data/ 目录中。服务不进行遥测、不收集分析数据、不与外部服务器通信。 资料来源:README.md
敏感信息处理
在处理联系人数据和生成建议时,MCP 服务会自动过滤以下敏感信息:
- 邮箱地址(显示为
[redacted-email]) - Bearer 令牌和认证凭证
- 文件路径信息
- 堆栈跟踪信息
错误处理与调试
常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| MCP 连接超时 | 服务未启动 | 执行 npm run mcp |
| 数据源返回空结果 | 数据源过期或未导入 | 执行 npm run memory:refresh |
| 认证失败 | 环境变量未设置 | 检查 AI_BACKEND 配置 |
源健康预检
在执行来源特定查询前,始终建议调用 source_health 检查数据源状态:
- Fresh:数据最近有更新
- Evidence-bearing:有足够的交互证据
- Stale:数据过期,需要刷新
- Empty:无数据导入
如果数据源状态为 stale 或 empty,应返回诚实的低置信度回答,而非虚构信息。 资料来源:hermes/minty-network-memory/SKILL.md
扩展开发
添加新工具
在 scripts/minty-mcp-server.js 中注册新工具需要:
- 在工具注册表中添加条目
- 实现工具处理器函数
- 更新
hermes/minty-network-memory/SKILL.md中的文档 - 添加相应的集成测试
工具维护契约
scripts/minty-mcp-server.js 是暴露 MCP 工具的事实来源(source of truth)。任何添加、移除或重命名工具的 PR 必须同步更新相关文档和技能说明。 资料来源:hermes/minty-network-memory/SKILL.md
相关文档
资料来源:[README.md]()
网络查询系统
网络查询系统(Network Query System)是 Minty CRM 的核心检索引擎,负责通过自然语言或结构化查询从用户的人际网络中快速定位相关联系人及其交互记录。该系统整合了来自多个数据源(WhatsApp、LinkedIn、Telegram、Email、Google Contacts 等)的统一数据,提供语义化的网络搜索能力,使用户能够以自然对话的方式回答"我...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
网络查询系统(Network Query System)是 Minty CRM 的核心检索引擎,负责通过自然语言或结构化查询从用户的人际网络中快速定位相关联系人及其交互记录。该系统整合了来自多个数据源(WhatsApp、LinkedIn、Telegram、Email、Google Contacts 等)的统一数据,提供语义化的网络搜索能力,使用户能够以自然对话的方式回答"我和谁讨论过 X 话题"、"在某个活动中见过哪些人"等查询需求。
网络查询系统的设计目标是将散落在不同通讯平台中的碎片化人际关系重新编织成可检索、可分析的网络图谱,支持从简单的人名搜索到复杂的多条件组合查询。资料来源:ARCHITECTURE.md
架构概览
网络查询系统采用分层架构,从底层到顶层依次为:数据索引层、查询解析层、匹配引擎层和 API 接口层。各层职责明确,通过标准化的数据结构进行通信。
graph TD
A[用户查询] --> B[查询解析层<br/>query-reasons.js]
B --> C[自然语言理解<br/>分词/意图识别]
C --> D[混合索引层<br/>hybrid-index.js]
D --> E[匹配引擎层<br/>search.js]
E --> F[结果排序与过滤]
F --> G[API 接口层<br/>network-query.js]
G --> H[返回结果]
I[统一数据存储<br/>data/unified/] --> D
J[交互索引<br/>interactions.json] --> E核心组件职责
| 组件 | 文件路径 | 主要职责 |
|---|---|---|
| 查询解析 | crm/query-reasons.js | 分析查询语句,提取关键词、过滤条件和排序需求 |
| 混合索引 | crm/hybrid-index.js | 构建和维护联系人与交互记录的倒排索引 |
| 搜索匹配 | crm/search.js | 执行关键词匹配、模糊搜索和相关性评分 |
| 网络查询 | crm/network-query.js | 提供自然语言查询接口,处理复杂检索场景 |
| CLI 查询 | crm/query.js | 命令行统计和搜索功能 |
资料来源:ARCHITECTURE.md
查询解析机制
query-reasons.js — 查询意图分析
query-reasons.js 模块负责将用户的自然语言查询转换为结构化的检索条件。该模块通过预定义的正则表达式模式和启发式规则识别查询中的关键成分,包括:
- 人员实体:查询中提到的人名或公司名称
- 时间范围:相对时间("最近一周"、"上个月")或绝对时间
- 来源过滤:指定的数据源(telegram、linkedin、email 等)
- 意图类型:搜索类型(统计信息、联系人列表、交互记录等)
查询解析结果会生成一个结构化的 query reasons 对象,包含提取的关键词列表、过滤条件和权重配置,供下游匹配引擎使用。资料来源:hermes/minty-network-memory/SKILL.md
查询类型分类
| 查询类型 | 示例 | 处理逻辑 |
|---|---|---|
| 自然语言搜索 | "我在伦敦见过的投资人" | 解析实体+来源+时间,组合检索 |
| 来源过滤查询 | "来自 Telegram 的人" | 仅在指定数据源中搜索 |
| 关键词搜索 | "DeFi"、"区块链" | 分词后匹配交互记录 |
| 人员上下文 | "Alice Müller 的相关信息" | 精确匹配 + 关联扩展 |
搜索匹配引擎
search.js — 核心匹配逻辑
search.js 是网络查询系统的匹配引擎核心,负责在已索引的数据中执行高效的相似度匹配和相关性排序。
#### 匹配函数实现
匹配引擎支持三种主要的匹配模式:
function matches(text, clause) {
if (clause.kind === 'phrase') return text.toLowerCase().includes(clause.value);
if (clause.kind === 'prefix') return findPrefix(text, clause.value).length > 0;
// token: case-insensitive substring match of the full token
return text.toLowerCase().includes(clause.value);
}
- phrase(短语匹配):完整匹配查询短语,区分大小写但忽略大小写差异
- prefix(前缀匹配):匹配以查询词开头的文本片段
- token(分词匹配):对查询词进行分词后逐个匹配
资料来源:crm/search.js
#### 偏移量计算
matchOffsets 函数用于计算匹配文本在原始内容中的位置信息,支持高亮显示和上下文提取:
function matchOffsets(text, clause) {
if (clause.kind === 'phrase' || clause.kind === 'token') return findAll(text, clause.value);
if (clause.kind === 'prefix') return findPrefix(text, clause.value);
return [];
}
#### 结果排序策略
搜索结果按综合评分排序,评分相同时按时间戳降序排列:
.sort((a, b) => (b.score - a.score) ||
((new Date(b.timestamp || 0).getTime()) - (new Date(a.timestamp || 0).getTime())));
评分计算综合考虑以下因素:
- 关键词命中次数
- 匹配模式优先级(精确匹配 > 前缀匹配 > 模糊匹配)
- 时间衰减因子(新近交互优先)
- 关系亲密度(relationshipScore)
#### 主题词提取
dominantTokens 函数从文本中提取最具代表性的关键词,用于构建主题索引和支持话题聚合查询:
function dominantTokens(text, opts = {}) {
const freq = {};
const min = opts.min || 2;
const topN = opts.topN || 10;
const words = String(text || '').toLowerCase().match(ALPHA_NUM) || [];
for (const w of words) {
if (w.length < 4 || STOP_WORDS.has(w)) continue;
freq[w] = (freq[w] || 0) + 1;
}
return Object.entries(freq)
.filter(([, n]) => n >= min)
.sort((a, b) => b[1] - a[1])
.slice(0, topN)
.map(([word]) => word);
}
该函数自动过滤停用词和长度小于 4 的词汇,并按词频排序返回 Top N 关键词。资料来源:crm/search.js
混合索引系统
hybrid-index.js — 索引构建与管理
hybrid-index.js 负责构建和维护联系人与交互记录的混合索引。索引采用倒排结构,支持高效的关键词查询和多维度过滤。
#### 索引数据结构
索引系统维护以下核心数据结构:
- 联系人索引:按姓名、公司、职位、标签等字段建立倒排索引
- 交互索引:按时间线组织交互记录,支持时间范围查询
- 来源索引:按数据源分类,支持来源级别的过滤和健康度检测
- 主题索引:基于
dominantTokens提取的主题词构建话题网络
#### 索引构建流程
索引构建是离线过程,通常在数据合并(merge.js)完成后执行。构建流程包括:
- 加载统一数据存储中的
contacts.json和interactions.json - 对每个联系人和交互记录进行分词处理
- 构建各字段的倒排索引
- 计算关联权重和预评分
- 持久化索引文件供运行时加载
自然语言查询接口
network-query.js — 对话式查询 API
network-query.js 模块提供 MCP(Model Context Protocol)接口,支持通过自然语言进行网络查询。该模块封装了底层的搜索能力,提供面向 AI Agent 的高级查询接口。
#### 核心查询工具
| 工具名称 | 功能描述 | 典型参数 |
|---|---|---|
search_network | 自然语言网络搜索 | query, limit, source/sources |
person_context | 人员上下文查询 | person, limit |
workflow_brief | 目标导向简报生成 | goal, limit |
source_health | 数据源健康度检查 | source/sources/query |
资料来源:hermes/minty-network-memory/SKILL.md
#### search_network 查询示例
{
"query": "investors in London who know about AI",
"limit": 5
}
返回结果包含按相关性排序的联系人列表,每个结果包含:
- 证据(evidence):匹配依据和上下文片段
- 亲密度(warmth):关系评分
- 置信度(confidence):数据可信度评估
- 来源诊断(source diagnostics):结果来源分析
- 建议操作(suggested actions):下一步安全建议
#### person_context 查询示例
{
"person": "Alice Müller",
"limit": 3
}
返回指定人员的完整关系上下文,包括:
- 关系历史摘要
- 交互亲密度评分
- 最近交互证据
- 数据新鲜度诊断
#### workflow_brief 目标简报
针对特定目标生成人员推荐简报:
{
"goal": "Find EU crypto insurance distribution partners",
"limit": 5
}
返回结果包含目标相关度最高的联系人列表,每个联系人附带:
- 相关性原因说明
- 数据新鲜度状态
- 安全的下一步行动建议
数据源健康度检测
source_health 工具在执行网络查询前自动检查各数据源的状态,确保查询结果的可靠性:
{ "source": "telegram" }
健康度状态分类:
- demo-ready:可用示例数据
- fresh:数据源状态正常
- stale:数据较旧,可能需要刷新
- empty:数据源为空或未初始化
- unsafe:数据不可靠,建议修复后再使用
资料来源:hermes/minty-network-memory/SKILL.md
命令行查询接口
query.js — CLI 工具
query.js 提供命令行界面的统计和搜索功能,通过以下命令调用:
npm run stats # 显示网络统计信息
npm run search # 执行关键词搜索
CLI 查询工具适合快速获取网络概览和批量数据导出场景,支持以下功能:
- 联系人总数和来源分布统计
- 交互记录数量和时间分布
- 关键词搜索并高亮显示结果
- 导出查询结果为 CSV/JSON 格式
资料来源:ARCHITECTURE.md
数据流与处理管道
查询执行完整流程
sequenceDiagram
participant U as 用户
participant NQ as network-query.js
participant QR as query-reasons.js
participant HI as hybrid-index.js
participant SE as search.js
participant DS as 统一数据存储
U->>NQ: 自然语言查询
NQ->>QR: 解析查询意图
QR-->>NQ: 结构化查询条件
NQ->>HI: 加载/查询索引
HI->>DS: 获取最新数据
DS-->>HI: 数据快照
HI-->>NQ: 候选结果集
NQ->>SE: 执行匹配评分
SE-->>NQ: 排序后结果
NQ-->>U: 返回查询结果与其他模块的交互
网络查询系统与以下模块紧密协作:
| 关联模块 | 交互方式 | 数据依赖 |
|---|---|---|
merge.js | 索引更新触发 | 接收合并后的统一数据 |
staleness.js | 健康度查询 | 使用新鲜度数据校准结果权重 |
server.js | HTTP API 封装 | 提供 /api/search 等端点 |
calendar.js | 日程数据融合 | 查询中加入日历事件上下文 |
数据模型
联系人数据结构
网络查询系统处理的联系人记录包含以下关键字段:
| 字段名 | 类型 | 说明 | 可检索性 |
|---|---|---|---|
id | string | 唯一标识符 | 精确匹配 |
name | string | 姓名 | 分词匹配 |
company | string | 公司名称 | 前缀匹配 |
position | string | 职位 | 分词匹配 |
sources | object | 各数据源原始数据 | 来源过滤 |
relationshipScore | number | 关系评分 0-100 | 范围过滤 |
daysSinceContact | number | 最近联系天数 | 范围过滤 |
activeChannels | string[] | 活跃联系方式 | 包含匹配 |
tags | string[] | 自定义标签 | 精确匹配 |
资料来源:AGENTS.md
交互记录数据结构
| 字段名 | 类型 | 说明 |
|---|---|---|
id | string | 交互记录唯一标识 |
contactId | string | 关联联系人 ID |
source | string | 数据来源(whatsapp/telegram/email等) |
timestamp | ISO string | 交互时间 |
type | string | 交互类型(message/call/meeting) |
body | string | 交互内容正文 |
subject | string | 主题(邮件场景) |
性能优化策略
索引优化
网络查询系统采用以下索引优化策略:
- 增量更新:仅对变更的联系人/交互记录重新索引
- 压缩存储:使用倒排列表压缩减少磁盘占用
- 缓存预热:服务器启动时预加载高频查询索引
- 分片加载:按数据源分片懒加载,平衡内存占用
查询优化
- 早停规则:达到目标结果数后提前终止匹配
- 缓存复用:相同查询条件的结果缓存复用
- 结果分页:避免一次性加载大量结果
- 评分截断:对低分结果进行截断过滤
使用场景示例
场景一:查找特定领域联系人
查询:查找讨论过 DeFi 话题的 Telegram 联系人
{
"query": "DeFi",
"sources": ["telegram"],
"limit": 10
}
系统会:
- 解析关键词 "DeFi"
- 在 Telegram 数据源中检索
- 匹配交互记录中的 DeFi 相关内容
- 按相关性评分和时间排序返回
场景二:人员关系探索
查询:获取特定人员的完整关系上下文
{
"person": "Bob Chen",
"limit": 5
}
返回结果包含该人员的所有交互证据、最近联系时间、共同话题等上下文信息。
场景三:目标导向搜索
查询:为特定目标寻找相关联系人
{
"goal": "Find potential co-founders for AI startup",
"limit": 10
}
系统综合分析所有联系人的背景、交互历史和话题相关性,生成目标相关度排序列表。
总结
网络查询系统是 Minty CRM 智能化能力的核心体现,通过整合多源数据、构建混合索引和提供自然语言接口,使用户能够以直观的方式探索和利用自己的人际网络。该系统具有以下核心特点:
- 多源聚合:统一检索散落在各平台的交互数据
- 语义理解:支持自然语言查询和意图识别
- 智能排序:综合相关度、时效性、亲密度多维度评分
- 健康感知:自动检测数据源状态,保证结果可靠性
- MCP 兼容:提供标准化的 AI Agent 接口支持
通过 network-query.js、search.js、query-reasons.js 和 hybrid-index.js 等模块的协作,网络查询系统为用户提供了从简单关键词搜索到复杂目标导向探索的完整检索能力。
资料来源:[ARCHITECTURE.md](https://github.com/sree-sanak/minty/blob/main/ARCHITECTURE.md)
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
可能影响升级、迁移或版本选择。
用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
可能增加新用户试用和生产接入成本。
假设不成立时,用户拿不到承诺的能力。
Pitfall Log / 踩坑日志
项目:sree-sanak/minty
摘要:发现 14 个潜在踩坑项,其中 1 个为 high/blocking;最高优先级:安装坑 - 来源证据:Audit person-only filters for channel/broadcast/list contacts。
1. 安装坑 · 来源证据:Audit person-only filters for channel/broadcast/list contacts
- 严重度:high
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Audit person-only filters for channel/broadcast/list contacts
- 对用户的影响:可能影响升级、迁移或版本选择。
- 建议检查:来源问题仍为 open,Pack Agent 需要复核是否仍影响当前版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_806464769ad247cd93162d66f18c8d51 | https://github.com/sree-sanak/minty/issues/86 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
2. 身份坑 · 仓库名和安装名不一致
- 严重度:medium
- 证据强度:runtime_trace
- 发现:仓库名
minty与安装入口imap不完全一致。 - 对用户的影响:用户照着仓库名搜索包或照着包名找仓库时容易走错入口。
- 建议检查:在 npm/PyPI/GitHub 上确认包名映射和官方 README 说明。
- 复现命令:
npm install imap - 防护动作:页面必须同时展示 repo 名和真实安装入口,避免用户搜索错包。
- 证据:identity.distribution | github_repo:1217893833 | https://github.com/sree-sanak/minty | repo=minty; install=imap
3. 安装坑 · 来源证据:Replace README screenshot TODO with privacy-safe demo visual
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安装相关的待验证问题:Replace README screenshot TODO with privacy-safe demo visual
- 对用户的影响:可能增加新用户试用和生产接入成本。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_81816548248b4de0a1ace912ebf7ee0e | https://github.com/sree-sanak/minty/issues/97 | 来源讨论提到 npm 相关条件,需在安装/试用前复核。
4. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:1217893833 | https://github.com/sree-sanak/minty | README/documentation is current enough for a first validation pass.
5. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | last_activity_observed missing
6. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium
7. 安全/权限坑 · 存在安全注意事项
- 严重度:medium
- 证据强度:source_linked
- 发现:No sandbox install has been executed yet; downstream must verify before user use.
- 对用户的影响:用户安装前需要知道权限边界和敏感操作。
- 建议检查:转成明确权限清单和安全审查提示。
- 防护动作:安全注意事项必须面向用户前置展示。
- 证据:risks.safety_notes | github_repo:1217893833 | https://github.com/sree-sanak/minty | No sandbox install has been executed yet; downstream must verify before user use.
8. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:1217893833 | https://github.com/sree-sanak/minty | no_demo; severity=medium
9. 安全/权限坑 · 来源证据:Add minimal GitHub Actions smoke CI for npm test
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Add minimal GitHub Actions smoke CI for npm test
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_d6f1f5066d884d66b52f3e8f51ed0899 | https://github.com/sree-sanak/minty/issues/98 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
10. 安全/权限坑 · 来源证据:Avoid returning raw internal error messages from API/UI
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Avoid returning raw internal error messages from API/UI
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_2974d969ccff4c9b960c16ee12639466 | https://github.com/sree-sanak/minty/issues/44 | 来源讨论提到 npm 相关条件,需在安装/试用前复核。
11. 安全/权限坑 · 来源证据:Provision GitHub labels from checked-in labels.json
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Provision GitHub labels from checked-in labels.json
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_1a3ae522d9a7404691d7e3eb4b70b6b1 | https://github.com/sree-sanak/minty/issues/109 | 来源讨论提到 npm 相关条件,需在安装/试用前复核。
12. 安全/权限坑 · 来源证据:Sync failures can mark stale source data as fresh
- 严重度:medium
- 证据强度:source_linked
- 发现:GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题:Sync failures can mark stale source data as fresh
- 对用户的影响:可能影响授权、密钥配置或安全边界。
- 建议检查:来源显示可能已有修复、规避或版本变化,说明书中必须标注适用版本。
- 防护动作:不得脱离来源链接放大为确定性结论;需要标注适用版本和复核状态。
- 证据:community_evidence:github | cevd_3bc92d2124c24b978bf799cc9eff9529 | https://github.com/sree-sanak/minty/issues/200 | 来源讨论提到 node 相关条件,需在安装/试用前复核。
13. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | issue_or_pr_quality=unknown
14. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:1217893833 | https://github.com/sree-sanak/minty | release_recency=unknown
来源:Doramagic 发现、验证与编译记录