Lilith电子邮件系统
Gmail同步守护进程+Lilith代理工具,用于语义电子邮件搜索,具有隐私意识分类和PII净化功能。
快速开始
1.数据库(共享Postgres)
此项目使用 共享 PostgreSQL服务器。此应用程序的数据库名称: lilith_emails.
确保共享的Postgres(带pgvector)正在运行。先克隆莉莉丝作曲项目。
2.运行迁移
uv run alembic upgrade head3.添加Gmail帐户
从下载OAuth客户端机密 Google 云控制台那么:
uv run python main.py add-account path/to/client_secrets.json4.同步(仅限下载)
uv run python main.py sync 1日志显示进度:提取的页面、存储的消息、到目前为止的总数。
5.转换(分类+消毒+嵌入)
同步后运行以生成 privacy_tier, body_redacted,以及从存储的数据中进行多级嵌入(主题、正文或块)。更改模型或逻辑时重新运行(无需重新下载)。
uv run python main.py transform 1清除通过transform命令添加的所有派生列。
uv run python main.py reset-transform 16.运行同步守护程序(发布/子webhook)
uv run python main.py serve当守护进程收到Gmail发布/订阅推送时,它会运行增量同步,然后为该帐户自动转换。
没有公共URL(本地开发): 使用 拉 而不是推。创建拉取订阅,设置 PUBSUB_SUBSCRIPTION 在 .env,然后运行:
gcloud auth application-default login
uv run python main.py watch 1
# In another terminal, poll for notifications (same sync+transform as webhook):
uv run python main.py pull创建拉取订阅(与主题相同的项目):\ gcloud pubsub subscriptions create lilith-emails-pull --topic=gmail-topic --project=lilithsync
使用公共URL: 使用一个 推 订阅(端点=您的公共 /webhook/gmail URL)并运行守护进程 uv run python main.py serve.注册手表一次: uv run python main.py watch (要求 GOOGLE_CLOUD_PROJECT 和 PUBSUB_TOPIC 在 .env).
如果手表返回403: 授予Gmail发布到您的主题的权限:
gcloud pubsub topics add-iam-policy-binding gmail-topic \
--member="serviceAccount:gmail-api-push@system.gserviceaccount.com" \
--role="roles/pubsub.publisher" \
--project=lilithsync在本地测试webhook
您可以在没有Gmail的情况下通过发布模拟的发布/订阅有效负载来触发相同的路径。首先运行完全同步,以便帐户具有 last_history_id,然后启动守护进程并发送:
# Start daemon in another terminal: uv run python main.py serve --port 8000
# Replace YOUR_EMAIL and HISTORY_ID (e.g. from DB: email_accounts.last_history_id)
# Portable (any OS):
python3 -c "
import base64, json, urllib.request
d = base64.b64encode(json.dumps({'emailAddress':'YOUR_EMAIL','historyId':'HISTORY_ID'}).encode()).decode()
urllib.request.urlopen(urllib.request.Request('http://localhost:8000/webhook/gmail', data=json.dumps({'message':{'data':d}}).encode(), headers={'Content-Type':'application/json'}, method='POST'))
print('OK')
"或者使用curl(Linux:使用base64-w0;macOS:使用base64):
B64=$(echo -n '{"emailAddress":"YOUR_EMAIL","historyId":"HISTORY_ID"}' | base64)
curl -s -X POST http://localhost:8000/webhook/gmail -H "Content-Type: application/json" -d "{\"message\":{\"data\":\"$B64\"}}"守护进程将运行增量同步,然后为该帐户进行转换。使用 get-email 或MCP工具来验证新的或更新的行。
配置
环境变量(.env 或外壳):
| 变量 | 描述 |
|---|---|
DATABASE_URL | PostgreSQL连接字符串 |
EMAIL_ENCRYPTION_KEY | OAuth令牌加密的Fernet密钥(python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())") |
GOOGLE_CLOUD_PROJECT | 发布/订阅的GCP项目ID |
EMBEDDING_URL | TEI嵌入服务(默认 http://127.0.0.1:6003);必须暴露 /embed 和 /tokenize |
SPACY_API_URL | 用于NER/PII净化的Spacy API(默认值 http://127.0.0.1:6004) |
FASTTEXT_LANGDETECT_URL | fastText语言检测API(默认 http://127.0.0.1:6005);在净化个人电子邮件之前用于NER语言 |
VLLM_URL | vLLM OpenAI兼容的API(默认值 http://127.0.0.1:6001/v1) |
VLLM_MODEL | 不在功能范围内时聊天完成的模型id(默认值 Qwen3-8B-AWQ) |
转换使用 capabilities.json:run uv run python main.py capabilities 在转换之前,确保文件存在并具有 embedding.max_tokens, vllm.model_id, spacy_api.available,以及 fasttext_langdetect.available。转换时没有环境回退。电子邮件与 transform_completed_at 除非您使用 --force (提示确认);如果转换在运行中失败,这些电子邮件将在下次重试。
MCP服务器(代理工具)
Lilith电子邮件MCP服务器暴露了您转换后的Gmail。
uv run mcp
uv run mcp --transport streamable-http --port 6201MCP工具
| 工具 | 说明 |
|---|---|
emails_search | 按自然语言+可选过滤器(从_email、标签、has_attachments、date_after、date_before、limit)搜索。返回电子邮件字典列表。 |
email_get | 通过Gmail邮件ID获取一封电子邮件。返回电子邮件字典或错误。 |
email_get_thread | 通过thread_id获取线程中的所有消息。返回线程字典 messages 列表。 |
emails_summarize | 总结如下 thread_id 或 email_ids。返回一个简短的摘要字符串 |
所有回复均使用 外部的 隐私:敏感内容被编辑,个人内容被显示为经过净化。
