语义邮件搜索系统

Lilith Email System是一个集成了Gmail同步守护进程和语义邮件搜索功能的工具,支持隐私感知分类和个人身份信息(PII)脱敏处理。

  • by Agent-Lilith
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 Agent-Lilith/lilith-gmail

使用说明

Lilith电子邮件系统

Gmail同步守护进程+Lilith代理工具,用于语义电子邮件搜索,具有隐私意识分类和PII净化功能。

快速开始

1.数据库(共享Postgres)

此项目使用 共享 PostgreSQL服务器。此应用程序的数据库名称: lilith_emails.

确保共享的Postgres(带pgvector)正在运行。先克隆莉莉丝作曲项目。

2.运行迁移

uv run alembic upgrade head

3.添加Gmail帐户

从下载OAuth客户端机密 Google 云控制台那么:

uv run python main.py add-account path/to/client_secrets.json

4.同步(仅限下载)

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 1

6.运行同步守护程序(发布/子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 <account_id> (要求 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 6201

MCP工具

工具 说明
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。返回一个简短的摘要字符串

所有回复均使用 外部的 隐私:敏感内容被编辑,个人内容被显示为经过净化。