内容
# AI 助手平台
一个全栈、多模型的 AI 助手平台 - 跨 OpenAI、Anthropic Claude 和 Google Gemini 聊天;检索增强生成超过您自己的文档;长期/短期记忆;工具和函数调用;真正的模型上下文协议(MCP)服务器和客户端;多步骤代理;以及与 Google Calendar、Gmail、Telegram、语音和视觉的集成。
使用 **FastAPI**、**SQLite**、**Pydantic v2** 和纯 **HTML/CSS/JS** 构建 - 无需前端构建步骤。
---
## 1. 项目概述
该项目在单个、可读的仓库中演示了端到端的 AI 工程栈:
| 层 | 它展示的内容 |
|---|---|
| 多模型编排 | `llm_providers.py` - 一个接口超过 3 个供应商 SDK |
| RAG | `rag_service.py` - 分段 -> 嵌入 -> 余弦搜索 -> 引用的上下文 |
| 记忆 | `memory_service.py` - 窗口短期 + 持久长期事实 |
| 工具/函数调用 | `tools.py` + 提供者特定的工具调用循环 |
| 代理 | `agents.py` - 计划 -> 执行 -> 观察循环,具有 3 个示例角色 |
| MCP | `mcp_server.py` / `mcp_client.py` - 真实的stdio MCP 服务器 + 客户端 |
| 集成 | Gmail、Calendar(Google OAuth2)、Telegram 机器人、语音(Whisper/TTS)、视觉(GPT-4o/Claude 视觉) |
| 自动化 | 用于 n8n / Zapier / Make 的通用出站 webhook 分发器 |
## 2. 架构
干净、几乎扁平的架构 - 参见 [`ARCHITECTURE.md`](ARCHITECTURE.md) 以获取完整的分解。简而言之:
```
浏览器(Jinja2 模板 + 纯 JS)
│ 使用 JWT 承载令牌的 fetch()
▼
FastAPI 路由器(routes_*.py) ──► 服务层(chat_service、rag_service、...)
│ │
▼ ▼
SQLAlchemy 异步 ORM(models.py) llm_providers.py(OpenAI / Anthropic / Gemini)
│
▼
SQLite(data/app.db)
```
## 3. 文件夹结构
```
ai-assistant-platform/
├── main.py # FastAPI 应用入口
├── config.py # 设置(环境变量)
├── database.py # 异步 SQLAlchemy 引擎/会话
├── models.py # ORM 模型
├── schemas.py # Pydantic 请求/响应模型
├── auth.py # JWT + 密码哈希
├── llm_providers.py # 多模型抽象(OpenAI/Anthropic/Gemini)
├── chat_service.py # 聊天编排(记忆 + RAG + 工具)
├── memory_service.py # 短期/长期记忆
├── rag_service.py # 文档分段/嵌入/搜索
├── tools.py # 工具/函数调用实现
├── code_assistant.py # 代码生成/解释/调试/重构/审查/测试
├── agents.py # 多步骤代理循环
├── mcp_server.py # MCP 服务器(工具、资源、提示)
├── mcp_client.py # MCP 客户端演示
├── google_auth_service.py # 共享 Google OAuth2 流
├── gmail_service.py # Gmail 集成
├── calendar_service.py # Google Calendar 集成
├── telegram_service.py # Telegram 机器人
├── voice_service.py # 语音转文本 / 文本转语音
├── vision_service.py # OCR / 图像标题 / 收据分析
├── file_search_service.py # 元数据 + 语义文件搜索
├── automation_service.py # n8n / Zapier / Make webhook
├── rate_limiter.py # 内存速率限制中间件
├── logging_config.py # 全局日志记录
├── routes_*.py # FastAPI 路由器,每个功能区域一个
├── static/ # CSS + JS(无需构建步骤)
├── templates/ # Jinja2 页面
├── tests/ # pytest 套件
├── docs/ # 附加文档
├── requirements.txt
├── .env.example
├── Start App.bat # Windows 一键启动器
└── Start App (Mac).command # macOS 一键启动器
```
## 4. 技术栈
- **后端:** Python 3.12+、FastAPI、Pydantic v2、SQLAlchemy 2.0(异步)、SQLite
- **AI SDK:** `openai`、`anthropic`、`google-generativeai`、`langchain`
- **身份验证:** JWT(PyJWT)+ bcrypt 密码哈希
- **前端:** HTML5、CSS3(自定义设计系统,无框架)、纯 JS
- **集成:** Google API Python 客户端(Gmail/Calendar)、`python-telegram-bot`、MCP SDK
- **测试:** pytest、pytest-asyncio、httpx
## 5. 安装
### 5.1 先决条件
- Python 3.12 或更新版本
- Git
- (可选)Visual Studio Code
### 5.2 Visual Studio Code 设置
1. 安装 **Python** 扩展(ms-python.python)。
2. 打开存储库文件夹:`File -> Open Folder...`
3. 选择解释器:`Ctrl/Cmd+Shift+P` -> `Python: Select Interpreter` -> 选择下面创建的 `.venv`。
4. 推荐:安装 **Even Better TOML** 和 **SQLite Viewer** 扩展。
### 5.3 Python 安装
从 [python.org](https://www.python.org/downloads/) 下载 Python 3.12+ 并验证:
```bash
python3 --version
```
### 5.4 虚拟环境
```bash
python3 -m venv .venv
# 激活:
# macOS/Linux:
source .venv/bin/activate
# Windows(PowerShell):
.venv\Scripts\Activate.ps1
```
### 5.5 安装依赖项
```bash
pip install -r requirements.txt
```
### 5.6 配置环境变量
```bash
cp .env.example .env
```
编辑 `.env` 并至少填写一个 AI 提供商密钥(参见下文)。`APP_SECRET_KEY` 和 `JWT_SECRET_KEY` 应替换为长随机字符串,以进行任何超出本地测试的测试。
### 5.7 运行 FastAPI
```bash
uvicorn main:app --reload
```
或使用一键启动脚本:
- **Windows:** 双击 `Start App.bat`
- **macOS:** 双击 `Start App (Mac).command`(首次运行:`chmod +x` 它,参见脚本头部)
然后打开 **http://localhost:8000**。
## 6. 配置 AI 提供商
### OpenAI
1. 在 https://platform.openai.com/api-keys 创建密钥
2. 在 `.env` 中设置 `OPENAI_API_KEY`。如有需要,调整 `OPENAI_MODEL`(默认为 `gpt-4o-mini`)。
### Claude(Anthropic)
1. 在 https://console.anthropic.com/ 创建密钥
2. 在 `.env` 中设置 `ANTHROPIC_API_KEY`。如有需要,调整 `ANTHROPIC_MODEL`。
### Gemini(Google)
1. 在 https://aistudio.google.com/app/apikey 创建密钥
2. 在 `.env` 中设置 `GOOGLE_API_KEY`。如有需要,调整 `GEMINI_MODEL`。
您可以配置一个、两个或全部三个 - 聊天 UI 中的模型切换器仅在存在密钥时显示为“已配置”,并且应用程序在任何子集上都运行正常。
## 7. RAG(检索增强生成)
从 **文档** 页面上传 PDF、TXT 或 Markdown 文件。管道:
1. 提取文本(对于 PDF,使用 `pypdf`)
2. 分段(约 800 个字符,120 个重叠)
3. 嵌入每个分段(如果设置了 `OPENAI_API_KEY`,则使用 OpenAI `text-embedding-3-small`,否则使用确定性本地哈希嵌入,以便在没有外部依赖的情况下使用该功能 - 对于演示非常有用)
4. 将分段 + 嵌入存储在 SQLite 中
5. 在查询时,通过余弦相似性检索顶部 K 个最相似的分段,并将它们注入系统提示中,并附带 `[来源 N]` 引用
## 8. 记忆
- **短期记忆:** 会话的最后 20 条消息,原样发送作为上下文。
- **长期记忆:** 在每个用户消息后,由 LLM 确定并存储在 `memory_items` 中的持久性事实(名称、偏好、重复约束);在每个未来会话的系统提示中注入这些事实。您还可以从 **记忆** 页面手动添加/编辑/删除记忆。
## 9. MCP(模型上下文协议)
`mcp_server.py` 是一个真正的、独立的 MCP 服务器,暴露:
- **工具:** `web_search`、`calculator`(与应用内聊天使用的实现相同)
- **资源:** `platform://about`、`platform://changelog`
- **提示:** `summarize_document`、`code_review`
直接运行服务器,或将任何与 MCP 兼容的客户端(Claude Desktop、另一个代理等)指向它:
```bash
python mcp_server.py
```
`mcp_client.py` 是一个工作演示客户端,它将服务器作为子进程启动,通过 stdio 与其通信,并测试所有三个原语:
```bash
python mcp_client.py
```
> **注意:** 基于 stdio 的 MCP 服务器保留 **stdout** 专门用于 JSON-RPC 协议消息。因此,`mcp_server.py` 记录到 **stderr** - 不要通过 Web 应用程序使用的共享 stdout 日志记录器路由其日志记录。
## 10. 自动化(n8n / Zapier / Make)
在 `.env` 中设置 `N8N_WEBHOOK_URL`、`ZAPIER_WEBHOOK_URL` 和/或 `MAKE_WEBHOOK_URL`,然后调用:
```
POST /api/automation/{platform}/trigger?event=my_event
Body: { "any": "json payload" }
```
这将 `{"event": ..., "payload": ...}` 发送到您的配置的 webhook,让您从应用程序的任何位置触发外部工作流。
## 11. 语音
- **语音转文本:** 通过 OpenAI API 的 Whisper(/api/voice/transcribe)
- **文本转语音:** OpenAI TTS(/api/voice/speak)
两者都需要 `OPENAI_API_KEY`。在 **语音** 页面尝试它们(使用浏览器的麦克风通过 `MediaRecorder`)。
## 12. 视觉
OCR、图像标题和收据分析使用 GPT-4o(默认)或 Claude 的视觉功能。在 **视觉** 页面尝试它们。
## 13. 测试
```bash
pytest
```
测试套件使用内存 SQLite 数据库和 httpx 的 ASGI 传输,因此它不需要运行服务器和 API 密钥。它涵盖了身份验证、对话/记忆/提示 CRUD、RAG 分段/嵌入数学和工具调用的安全防护。
## 14. 部署
对于简单的单进程部署:
```bash
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 2
```
将其放在带有 TLS 终止的反向代理(nginx/Caddy)后面。对于超出演示/投资组合部署的任何内容,请替换:
- SQLite -> PostgreSQL(`DATABASE_URL`)
- 内存速率限制器 -> Redis 支持的限制
- 本地文件上传 -> S3 兼容对象存储
## 15. 故障排除
| 症状 | 修复方法 |
|---|---|
| 启动时出现 `ModuleNotFoundError` | 激活虚拟环境,重新运行 `pip install -r requirements.txt` |
| 注册因 bcrypt 错误而失败 | 确保安装了 `bcrypt==4.0.1`(更新的 bcrypt 破坏了 passlib 1.7.4 的后端检测) |
| 聊天显示“未配置” | 在 `.env` 中添加至少一个提供商 API 密钥并重启 |
| Gmail/Calendar 调用返回 400 | 完成 **设置 -> 连接 Gmail/Calendar** 中的 OAuth 流 |
| MCP 客户端挂起或出错 | 在 `mcp_server.py` 中永远不要记录到 stdout - stdout 保留用于协议消息 |
| 端口已被占用 | 更改 `.env` 中的 `APP_PORT`,或停止其他进程 |
## 16. 未来改进
- 用小型局部句子转换器模型替换本地哈希嵌入回退
- 添加基于 WebSocket 的全双工语音流
- 添加每用户速率限制和使用仪表板
- 添加 PostgreSQL + pgvector 以实现生产规模的 RAG
- 为多租户部署添加基于角色的访问控制
---
参见:[`ARCHITECTURE.md`](ARCHITECTURE.md)、[`API_REFERENCE.md`](API_REFERENCE.md)、[`ROADMAP.md`](ROADMAP.md)、[`CONTRIBUTING.md`](CONTRIBUTING.md)、[`SECURITY.md`](SECURITY.md)、[`CHANGELOG.md`](CHANGELOG.md)。