# AIChatAgent **Repository Path**: coder-springxu/aichat-agent ## Basic Information - **Project Name**: AIChatAgent - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-20 - **Last Updated**: 2026-06-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AI Chat Agent 一个对接本地大语言模型(LLM)、支持流式响应的 AI 聊天应用。Monorepo 架构,前后端分离。支持 **多后端引擎切换**(Ollama / MLX)。 ## 📁 项目结构 ``` AIChatAgent/ ├── app/ # 🖥️ 前端 Web App (React + Vite) │ ├── src/ # TypeScript 源代码 │ │ ├── components/ # UI 组件 (7 个核心组件) │ │ │ ├── ChatContainer/ ← 主聊天容器 │ │ │ ├── MessageList/ ← 消息列表 (含虚拟滚动) │ │ │ ├── MessageItem/ ← 单条消息气泡 │ │ │ ├── InputArea/ ← 输入框区域 │ │ │ ├── StreamingIndicator/ ← 流式加载指示器 │ │ │ ├── SessionSidebar/ ← 会话侧边栏 (搜索+删除) │ │ │ └── VirtualMessageList/ ← 高性能虚拟列表 │ │ ├── hooks/ # 自定义 Hooks │ │ │ ├── useChat.ts ← 状态管理 Hook │ │ │ ├── useStreaming.ts ← 流式响应 Hook │ │ │ └── useKeyboardShortcuts ← 快捷键 Hook │ │ ├── lib/ # API 客户端、模型适配器 │ │ │ ├── apiClient.ts ← Axios (拦截器+重试) │ │ │ ├── config.ts ← Vite 环境变量映射 │ │ │ └── models/ ← LLM 适配器层 │ │ ├── store/ # Context + Reducer 状态管理 │ │ │ ├── index.tsx ← StoreProvider (IndexedDB持久化) │ │ │ ├── chatReducer.ts ← Reducer 逻辑 │ │ │ └── initialLoad.ts ← 数据恢复逻辑 │ │ ├── types/ # TypeScript 类型定义 │ │ ├── utils/ # 工具函数 │ │ │ ├── db.ts ← IndexedDB CRUD │ │ │ ├── storage.ts ← localStorage 封装 │ │ │ ├── sessionHelper.ts ← 会话辅助函数 │ │ │ └── exportHelper.ts ← 导出/导入功能 │ │ ├── App.tsx ← 根组件 (含 StoreProvider) │ │ ├── main.tsx ← 入口文件 │ │ └── index.css ← Tailwind + 全局样式 │ ├── tests/ # Vitest 测试 (13 个文件) │ ├── public/ # 静态资源 │ ├── package.json # 依赖 + 脚本 │ ├── vite.config.js # Vite (含 API 代理 → :3001) │ ├── vitest.config.ts # 测试配置 │ ├── tsconfig.json # TypeScript (单文件, 含 path alias) │ └── tailwind.config.js # Tailwind CSS 自定义主题 ├── service/ # 🛠️ 后端 API Gateway (Node.js + Express) │ ├── src/ │ │ ├── server.ts ← Express 入口 (+ CORS) │ │ ├── config.ts ← 环境变量配置 + Provider 工厂 │ │ ├── types.ts ← 共享类型定义 │ │ ├── models/ │ │ │ ├── index.ts ← ModelProvider 接口 + 工厂函数 │ │ │ ├── ollama.ts ← Ollama HTTP client (SSE 流式) │ │ │ └── mlx.ts ← MLX HTTP client (OpenAI 兼容 API) │ │ ├── routes/ │ │ │ └── chat.ts ← /api/chat/* 路由组 │ │ ├── lib/ │ │ │ └── tokenCounter.ts ← Token 估算工具 │ │ ├── store/ │ │ │ └── sessionStore.ts ← 会话持久化存储 │ │ ├── middleware/ │ │ │ ├── errorHandler.ts │ │ │ └── requestLogger.ts │ │ └── logger.ts ← 文件日志系统 │ ├── package.json │ ├── tsconfig.json │ └── .env.example # Ollama + Service 配置 ├── doc/ # 📐 架构设计 + 技术方案文档 │ ├── AI 聊天应用技术栈.md │ ├── 应用实施方案.md │ └── 应用架构设计.md ├── package.json # Root monorepo (workspaces) ├── AGENTS.md # AI Agent 工作规范 └── .gitignore # 根级别忽略规则 ``` ## ✨ 核心特性 - 🚀 **实时流式响应** — SSE 协议实现打字机效果 - 🔄 **多后端引擎** — 支持 Ollama / MLX 切换(通过 MODEL_PROVIDER 配置) - 💾 **持久化存储** — IndexedDB + localStorage 双层保障 - 🌙 **明暗主题切换** — Tailwind dark mode (sidebar toggle) - ⌨️ **键盘快捷键** — `⌘K`新建、`Esc`聚焦、`⌘+Shift+Enter`停止 - 📊 **会话管理** — 搜索、删除、多会话切换 - 📤 **导出功能** — JSON / Markdown / TXT 格式 - ⚡ **高性能渲染** — VirtualMessageList 虚拟滚动 - 🧪 **测试覆盖** — Vitest + RTL (13 个测试文件) ## 🚀 快速开始 ### 1. 安装依赖 ```bash cd AIChatAgent npm install # 根 workspace + app + service 全部安装 ``` ### 2. 配置环境变量 ```bash # 复制配置模板 cp service/.env.example service/.env ``` 编辑 `service/.env`,至少配置后端引擎和模型: ```bash # 选择后端引擎:ollama 或 mlx(见下方详细说明) MODEL_PROVIDER=ollama # Ollama 配置(MODEL_PROVIDER=ollama 时) VITE_OLLAMA_BASE_URL=http://localhost:11434 VITE_DEFAULT_MODEL=qwen3.6:latest # MLX 配置(MODEL_PROVIDER=mlx 时) # MLX_BASE_URL=http://localhost:8080 # DEFAULT_MODEL=your-model-name ``` ### 3. 启动本地 LLM #### 使用 Ollama ```bash brew install ollama # macOS ollama pull qwen3.6:latest ollama serve # 默认 http://localhost:11434 ``` #### 使用 MLX (Apple Silicon) ```bash # 启动 MLX 服务(假设已有 MLX 服务端) # 默认地址 http://localhost:8080 ``` ### 4. 启动服务 ```bash # 方式一:并行启动前后端(推荐) npm run dev # service@3001 + app@5173 (自动代理) # 方式二:单独启动 npm run dev:service # 仅后端 API Gateway npm run dev:app # 仅前端 Dev Server ``` ### 5. 构建生产版本 ```bash npm run build # app + service 同时构建 ``` ## ⚙️ 配置 MODEL_PROVIDER(多后端引擎切换) `MODEL_PROVIDER` 环境变量用于选择 AI 后端引擎,当前支持两种 Provider。 ### 可选值 | 值 | 说明 | 默认端口 | |---|---|---| | `ollama` | **Ollama 后端**(默认值) | `11434` | | `mlx` | **MLX 后端**(Apple Silicon 优化,OpenAI 兼容 API) | `8080` | ### 配置方式 **方式一:通过 `.env` 文件** 编辑 `service/.env`,设置 `MODEL_PROVIDER`: ```bash # 使用 MLX 后端 MODEL_PROVIDER=mlx # 或使用 Ollama 后端(默认,也可以注释掉此行) # MODEL_PROVIDER=ollama ``` **方式二:通过命令行环境变量** ```bash # 以 MLX 后端启动 MODEL_PROVIDER=mlx npm run dev # 以 Ollama 后端启动(不设置时默认) npm run dev ``` ### Provider 专属配置项 #### Ollama(`MODEL_PROVIDER=ollama`) | 环境变量 | 默认值 | 说明 | |---|---|---| | `VITE_OLLAMA_BASE_URL` | `http://localhost:11434` | Ollama 服务地址 | | `VITE_DEFAULT_MODEL` | `qwen3.6:latest` | 默认模型名称 | ```bash # service/.env 示例 MODEL_PROVIDER=ollama VITE_OLLAMA_BASE_URL=http://localhost:11434 VITE_DEFAULT_MODEL=qwen3.6:latest ``` #### MLX(`MODEL_PROVIDER=mlx`) | 环境变量 | 默认值 | 说明 | |---|---|---| | `MLX_BASE_URL` | `http://localhost:8080` | MLX 服务地址(OpenAI 兼容 API) | | `DEFAULT_MODEL` | `default_model` | 默认模型名称 | ```bash # service/.env 示例 MODEL_PROVIDER=mlx MLX_BASE_URL=http://localhost:8080 DEFAULT_MODEL=your-model-name ``` ### 公共配置项 以下配置对所有 Provider 生效: | 环境变量 | 默认值 | 说明 | |---|---|---| | `TEMPERATURE` | `0.7` | 生成温度 (0~2) | | `MAX_TOKENS` | `2048` | 最大生成 Token 数 | | `SYSTEM_PROMPT` | (空) | 系统提示词 | | `PORT` | `3001` | 后端服务端口 | | `STREAMING_TIMEOUT` | `60000` | 流式超时时间 (ms) | ### 验证当前 Provider 启动服务后,通过健康检查接口确认: ```bash curl http://localhost:3001/api/chat/health ``` 响应中包含 `provider` 字段和当前后端地址: ```json { "status": "healthy", "provider": "mlx", "url": "http://localhost:8080", "models": ["your-model-name"], "uptime": 1234, "requestCount": 1 } ``` 也可通过 `/api/chat/config` 查看当前配置: ```bash curl http://localhost:3001/api/chat/config # { "success": true, "provider": "mlx", "model": "...", "temperature": 0.7, "maxTokens": 2048 } ``` ### Token 用量说明 不同 Provider 汇报 Token 数据的方式不同: - **MLX**:返回精确的 Token 计数,包括 `prompt_tokens_details.cached_tokens`(缓存命中数)。数据直接转发到前端,无需估算。 - **Ollama**:当返回的 `prompt_tokens=0` 时,后端会自动根据上下文估算 Token 用量作为补充。 ## 🛠️ 技术栈 | 层级 | 技术选型 | |------|----------| | **前端** | React 18 + TypeScript (strict) + Vite 6 + Tailwind CSS | | **状态管理** | React Context API + useReducer (IndexedDB持久化) | | **HTTP 客户端** | Axios (请求/响应拦截器 + 指数退避重试) | | **后端** | Node.js + Express 5 (TypeScript, ESM) | | **LLM 集成** | Ollama REST API / MLX OpenAI 兼容 API(SSE 流式) | | **持久化** | IndexedDB (大容量) + localStorage (快速恢复) | | **测试** | Vitest + React Testing Library (≥80% coverage) | | **代码质量** | ESLint 9 (flat config) + Prettier + Husky | ## ⌨️ 键盘快捷键 | 快捷键 | 功能 | |--------|------| | `⌘/Ctrl + K` | 新建对话 | | `Enter` | 发送消息 | | `Shift + Enter` | 输入框换行 | | `⌘/Ctrl + Shift + Enter` | 停止 AI 生成 | | `Esc` | 聚焦/离开输入框 | ## 🧪 测试 ```bash # App 层 (组件 + reducer + 工具函数) cd app && npm test # 运行所有测试 cd app && npm run test:coverage # 含覆盖率报告 # Service 层 (后续补充 Express integration tests) cd service && npm test ``` ## 🏗️ API 接口 (service) | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/chat/health` | 后端健康检查(含 provider 信息) | | GET | `/api/chat/config` | 获取当前模型配置 | | PUT | `/api/chat/config` | 动态更新模型参数(model/temperature/maxTokens) | | GET | `/api/chat/models` | 列出可用模型 | | POST | `/api/chat/stream` | SSE 流式生成(逐 chunk 推送) | | POST | `/api/chat/generate` | 非流式生成(返回完整 content) | | POST | `/api/chat/sessions` | 创建会话 | | GET | `/api/chat/sessions` | 列出/搜索会话 | | GET | `/api/chat/sessions/:id` | 获取单条会话 | | DELETE | `/api/chat/sessions/:id` | 删除会话 | | POST | `/api/chat/sync-messages` | 同步前端消息到后端 | ### 流式响应格式 ``` // POST /api/chat/stream Request: { sessionId, message, systemPrompt?, model?, temperature?, maxTokens?, historyMessages? } Response (SSE): data: {"type":"chunk","content":"这是"} ← 内容块 data: {"type":"reasoning","content":"思考中"} ← 推理过程(如支持) data: {"type":"token_usage","data":{"promptTokens":50,"completionTokens":30,"totalTokens":80}} data: {"type":"session","data":{...}} ← 更新后的会话数据 data: [DONE] ← 结束标志 ``` ## 📐 架构设计 ``` ┌──────────────┐ ┌──────────────┐ ┌─────────────────┐ │ React App │────▶│ Express │────▶│ Ollama / MLX │ │ (app/) │◀────│ Gateway │ │ (本地 LLM) │ │ │ │ (service/) │ │ │ │ SSE + WebSSE│ │ │ └─────────────────┘ └──────────────┘ └──────────────┘ Provider 切换: service/.env → MODEL_PROVIDER=ollama|mlx 数据存储: IndexedDB (浏览器) + Session Store (服务端) ``` ## 🔒 安全提示 - API Key / Ollama URL 存于 `.env`,**不要**提交到版本控制 - Ollama 默认仅监听 `localhost:11434`,不对外暴露 - MLX 默认仅监听 `localhost:8080`,不对外暴露 - React JSX 自动转义 (XSS 防护) - IndexedDB 数据仅存储在本机浏览器中 ## 📦 License MIT