Files
autoAiWorkSys/docs/ai_service_unified.md
张成 68b4db0aee 1
2026-02-01 22:00:19 +08:00

365 lines
8.1 KiB
Markdown
Raw Permalink 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.
# 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
**维护者**: 开发团队