Files
chat-one-service/README.md
2026-04-17 02:32:46 +08:00

203 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# chat-one-service
## TODO当前迭代
- [ ] client-app短信登录 + JWT 鉴权(接入真实短信服务前先 mock
- [ ] client-appChat 会话与消息持久化(接入 Prisma + 数据库)
- [ ] client-app按用户限流与基础风控基于 Redis 后续补上)
- [ ] admin-app邮箱登录与 RBAC角色/权限点基础能力)
- [ ] admin-app平台管理接口增删改查 + 开关 + 权重)
- [ ] admin-app用量统计与简单报表按平台 / 用户聚合)
---
ChatOne 服务端:基于 **NestJS 11** + **Fastify**,整合多厂商大模型对话能力,对外提供统一的 **SSEServer-Sent Events** 流式输出协议,便于 Web / App 接入。
更完整的架构说明见:`docs/project-solution.md`。JWT 最小示例见:`docs/jwt-minimal-nestjs.md`
---
## 技术栈
- **框架**NestJS 11`@nestjs/platform-fastify`
- **HTTP 客户端**`undici`(调用各厂商 OpenAI 兼容接口)
- **配置**`@nestjs/config`(可选环境校验见 `src/config/validation.ts`,默认可在 `AppModule` 中关闭)
- **日志**`nestjs-pino` + `pino-pretty`(开发环境美化输出)
- **文档**Swagger默认路径 `/docs`
- **安全头**`helmet`
---
## 目录结构(概要)
```text
src/
├── main.ts # 入口Fastify + 全局前缀 api + Swagger
├── app.module.ts # 根模块
├── config/ # 配置加载与环境校验
├── apps/
│ ├── client-app/ # 用户端(当前含 Chat SSE
│ ├── admin-app/ # 管理端(占位模块,后续扩展)
│ └── shared-domain/
│ └── ai-gateway/ # 多平台 Provider 与路由
├── prisma/ # Prisma 封装(按需接入数据库时再挂回 AppModule
docs/
├── project-solution.md
└── jwt-minimal-nestjs.md
```
---
## 环境要求
- **Node.js**:建议 20 LTS 及以上
- **包管理**:本项目使用 **Yarn**(存在 `yarn.lock`);亦可用 npm
---
## 安装依赖
```bash
yarn install
```
---
## 环境变量
在项目根目录创建 `.env`(该文件已在 `.gitignore` 中,**不要提交到 Git**)。
### 服务
| 变量 | 说明 | 示例 |
|------|------|------|
| `PORT` | 监听端口 | `3000` |
| `NODE_ENV` | 运行环境 | `development` / `production` |
### 千问DashScope OpenAI 兼容)
| 变量 | 说明 |
|------|------|
| `QWEN_API_KEY` | 千问 API Key |
| `QWEN_BASE_URL` | 可选,默认 `https://dashscope.aliyuncs.com/compatible-mode/v1` |
### DeepSeek
| 变量 | 说明 |
|------|------|
| `DEEPSEEK_API_KEY` | DeepSeek API Key |
| `DEEPSEEK_BASE_URL` | 可选,默认 `https://api.deepseek.com/v1` |
### 火山引擎(方舟 OpenAI 兼容形态,具体以你控制台为准)
| 变量 | 说明 |
|------|------|
| `VOLC_API_KEY` | 火山引擎 API Key |
| `VOLC_BASE_URL` | 可选,默认 `https://ark.cn-beijing.volces.com/api/v3` |
> 说明:当前各 Provider 对上游采用 **非流式** `chat/completions` 调用,由网关将完整回复 **切片** 后以 SSE 推给客户端。后续可升级为上游真流式。
---
## 常用脚本
| 命令 | 说明 |
|------|------|
| `yarn start:dev` | 开发模式(`tsx watch`,改代码自动重启) |
| `yarn build` | TypeScript 编译到 `dist/` |
| `yarn start` | 运行已编译产物 `dist/main.js` |
| `yarn lint` | ESLint需本地配置规则时生效 |
---
## 启动
开发:
```bash
yarn start:dev
```
默认监听:`http://localhost:3000`(可通过 `PORT` 修改)。
生产(先编译再启动):
```bash
yarn build
yarn start
```
---
## API 说明
### Swagger
浏览器打开:`http://localhost:3000/docs`
### 统一 SSE Chat用户端
- **路径**`POST /api/client/v1/chat/completions/stream`
- **Content-Type**`application/json`
- **响应**`text/event-stream`SSE
#### 请求体(示例)
```json
{
"model": "qwen-plus",
"platform": "qwen",
"messages": [
{ "role": "system", "content": "你是一个乐于助人的助手" },
{ "role": "user", "content": "你好" }
]
}
```
- `platform``qwen` | `deepseek` | `volc` | `auto`(或不传,由路由按 `model` 简单匹配)
- `model`:各平台实际模型名或 Endpoint ID火山侧请填你在控制台配置的模型标识
#### SSE 事件约定
| 事件名 | data 字段含义 |
|--------|----------------|
| `meta` | 请求元信息:`requestId``platform``model` |
| `delta` | 文本增量:`{"delta":"..."}` |
| `usage` | Token 用量:`promptTokens` / `completionTokens` / `totalTokens` |
| `done` | 结束:`finishReason` |
#### curl 示例(流式)
```bash
curl -N \
-H "Content-Type: application/json" \
-X POST \
-d '{"platform":"qwen","model":"qwen-plus","messages":[{"role":"user","content":"你是谁"}]}' \
http://localhost:3000/api/client/v1/chat/completions/stream
```
---
## 数据库与 Prisma
仓库内已包含 `src/prisma/` 模块骨架。若尚未准备好 PostgreSQL 或未执行 `prisma generate`,请勿在 `AppModule` 中导入 `PrismaModule`,避免启动时报缺少生成客户端的错误。
接入数据库时的典型步骤:
1. 编写 `prisma/schema.prisma` 并配置 `DATABASE_URL`
2. 执行 `npx prisma generate` / `yarn prisma generate`
3.`src/app.module.ts` 中按需 `imports: [PrismaModule]`
---
## 安全提示
- **切勿**将含真实 Key 的 `.env` 提交到版本库。
- 若密钥曾在公开场合暴露,请在对应云厂商控制台 **轮换 API Key**
---
## 许可证
MIT见仓库根目录 `LICENSE`)。