This commit is contained in:
张成
2026-02-01 22:00:19 +08:00
parent 933f1618ca
commit 68b4db0aee
8 changed files with 1762 additions and 708 deletions

364
docs/ai_service_unified.md Normal file
View File

@@ -0,0 +1,364 @@
# AI 服务统一说明
**更新时间**: 2025-12-27
---
## 统一后的 AI 服务架构
系统已完成 AI 服务的统一整理,现在只保留一个标准的 AI 服务实现。
---
## 文件位置
### ✅ 保留的文件(唯一 AI 服务实现)
**核心服务:**
- **`api/services/ai_service.js`** - AI 服务主文件(基于阿里云 Qwen 2.5
- **`api/services/ai_call_recorder.js`** - AI 调用记录服务
**导出管理:**
- **`api/services/index.js`** - 服务统一导出
**数据库层:**
- **`api/model/ai_call_records.js`** - AI 调用记录模型
**后台管理:**
- **`api/controller_admin/ai_call_records.js`** - 后台管理 API
**前端界面:**
- **`admin/src/views/system/ai_call_records.vue`** - 管理界面
- **`admin/src/api/system/ai_call_records_server.js`** - API 服务
### ❌ 已删除的文件
- ~~`api/middleware/job/aiService.js`~~ - 已删除(内容已迁移到 `services/ai_service.js`
---
## 使用方式
### 1. 直接引用(推荐)
```javascript
const aiService = require('./services/ai_service');
// 使用 AI 服务
const result = await aiService.analyzeJob(jobInfo, resumeInfo);
```
### 2. 通过服务管理器
```javascript
const { AIService } = require('./services');
// 使用 AI 服务
const result = await AIService.analyzeJob(jobInfo, resumeInfo);
```
---
## AI 服务功能列表
### 核心方法
| 方法 | 说明 | 业务类型 |
|------|------|---------|
| `callAPI(prompt, options)` | 基础 API 调用 | 自定义 |
| `analyzeJob(jobInfo, resumeInfo)` | 岗位智能筛选 | `job_analysis` |
| `generateChatContent(jobInfo, resumeInfo, chatType)` | 生成个性化聊天 | `chat_generation` |
| `analyzeResume(resumeText)` | 简历分析 | `resume_analysis` |
| `generateInterviewInvitation(jobInfo, chatHistory)` | 生成面试邀约 | `interview_invitation` |
| `identifyOutsourcingJob(jobInfo)` | 识别外包岗位 | `outsourcing_detection` |
### 辅助方法
| 方法 | 说明 |
|------|------|
| `recordAiCall(params)` | 记录 AI 调用 |
| `calculateCost(totalTokens)` | 计算调用费用 |
---
## Token 自动记录
所有通过 `callAPI()` 方法的调用都会自动记录以下信息:
- **Token 使用量**prompt_tokens, completion_tokens, total_tokens
- **成本信息**:基于模型计算的费用
- **性能指标**:响应时间(毫秒)
- **状态跟踪**:成功/失败状态
- **业务关联**business_type, reference_id
- **请求追踪**:完整的请求和响应内容
记录过程是异步非阻塞的,不会影响 AI 调用的主流程。
---
## 配置说明
### 环境变量
`.env` 文件中配置:
```bash
# 阿里云 DashScope API Key
AI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxx
# 模型选择(可选)
AI_MODEL=qwen-turbo # qwen-turbo, qwen-plus, qwen-max, qwen-long
```
### 代码配置
```javascript
// 在 config/config.js 中
module.exports = {
ai: {
apiKey: process.env.AI_API_KEY,
model: process.env.AI_MODEL || 'qwen-turbo'
}
}
```
---
## 模型选择
| 模型 | 速度 | 质量 | 成本 | 价格(元/1000 tokens|
|------|------|------|------|---------------------|
| qwen-turbo | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ¥0.003 |
| qwen-plus | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ¥0.004 |
| qwen-max | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ¥0.12 |
| qwen-long | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | - |
---
## 使用示例
### 示例 1岗位分析
```javascript
const aiService = require('./services/ai_service');
const jobInfo = {
companyName: '阿里巴巴',
jobTitle: 'Node.js 高级工程师',
salary: '30-50K',
location: '杭州',
description: '负责后端服务开发...',
skills: 'Node.js, MySQL, Redis'
};
const resumeInfo = {
skills: 'Node.js, JavaScript, MySQL',
experience: '5年后端开发经验',
education: '本科',
expectedSalary: '35K'
};
const result = await aiService.analyzeJob(jobInfo, resumeInfo);
console.log(result.analysis);
```
### 示例 2生成聊天内容
```javascript
const result = await aiService.generateChatContent(
jobInfo,
resumeInfo,
'greeting' // greeting, interview, followup
);
console.log(result.content);
```
### 示例 3简历分析
```javascript
const resumeText = `
姓名:张三
技能Node.js, React, MySQL
工作经验3年全栈开发
...
`;
const result = await aiService.analyzeResume(resumeText);
console.log(result.analysis);
// {
// skillTags: ['Node.js', 'React', 'MySQL'],
// strengths: '...',
// weaknesses: '...',
// careerSuggestion: '...',
// competitiveness: 75
// }
```
### 示例 4自定义 AI 调用
```javascript
const result = await aiService.callAPI(
'请帮我分析这个岗位的发展前景...',
{
systemPrompt: '你是一个职业规划专家...',
temperature: 0.7,
maxTokens: 2000,
user_id: 123,
business_type: 'career_analysis'
}
);
console.log(result.content);
```
---
## 错误处理
AI 服务内置了重试机制(最多 3 次)和错误处理:
```javascript
try {
const result = await aiService.analyzeJob(jobInfo, resumeInfo);
} catch (error) {
console.error('AI 调用失败:', error.message);
// 错误会自动记录到 ai_call_records 表
}
```
---
## 监控与统计
### 查看调用记录
登录后台管理系统:**系统设置** → **AI调用记录**
### 统计信息
- 总调用次数
- Token 总使用量
- 总费用统计
- 平均响应时间
- 成功率
### 编程方式获取统计
```javascript
const AiCallRecorder = require('./services/ai_call_recorder');
// 获取用户统计
const userStats = await AiCallRecorder.getUserTokenStats(userId, {
startDate: new Date('2025-01-01'),
endDate: new Date('2025-12-31')
});
console.log(userStats);
// {
// total_calls: 100,
// total_prompt_tokens: 5000,
// total_completion_tokens: 3000,
// total_tokens: 8000,
// total_cost: 24.00,
// avg_response_time: 1500
// }
```
---
## 注意事项
### 1. API Key 安全
- ❌ 不要将 API Key 硬编码在代码中
- ❌ 不要将 `.env` 文件提交到版本控制
- ✅ 使用环境变量管理 API Key
- ✅ 生产环境使用独立的 API Key
### 2. 成本控制
- 选择合适的模型(开发用 turbo生产用 plus
- 设置合理的 `maxTokens` 限制
- 监控 Token 使用量
- 定期查看费用统计
### 3. 性能优化
- 重试机制已内置3 次)
- 超时设置为 30 秒
- Token 记录是异步的,不阻塞主流程
### 4. 数据隐私
- 请求和响应内容会完整记录到数据库
- 注意敏感信息的处理
- 定期清理历史记录
---
## 迁移指南
如果你的代码之前引用了 `middleware/job/aiService.js`,请修改为:
```javascript
// ❌ 旧代码
const aiService = require('../middleware/job/aiService');
// ✅ 新代码
const aiService = require('../services/ai_service');
```
功能保持完全一致,只是路径发生了变化。
---
## 故障排查
### 问题 1模型未加载
**错误信息:** `Cannot read property 'findAll' of undefined`
**解决方法:**
1. 确认已执行建表 SQL`_sql/create_ai_call_records_table.sql`
2. 重启 Node.js 服务
3. 检查 `api/model/ai_call_records.js` 是否存在
### 问题 2认证失败
**错误信息:** `auth header format should be Bearer sk-...`
**解决方法:**
1. 检查 `.env` 文件中的 `AI_API_KEY`
2. 确认 API Key 格式正确(以 `sk-` 开头)
3. 验证 API Key 有效性
### 问题 3记录失败
**警告信息:** `记录AI调用失败不影响主流程`
**解决方法:**
1. 检查数据库连接
2. 确认 `ai_call_records` 表存在
3. 查看详细错误日志
### 问题 4费用计算不准确
**解决方法:**
1. 检查 `calculateCost()` 方法中的价格配置
2. 根据实际使用的模型调整价格
3. 定期对账单进行核对
---
## 相关文档
- [AI 服务配置说明](ai_service_config.md) - 详细的环境配置指南
- [功能实施总结](implementation_summary.md) - 完整的功能实施文档
- [API 文档](../api/controller_admin/ai_call_records.js) - 后台 API 接口说明
---
**文档版本**: 1.0
**最后更新**: 2025-12-27
**维护者**: 开发团队