This commit is contained in:
张成
2025-12-27 20:14:40 +08:00
parent 43382668a3
commit 43f7884e52
14 changed files with 1818 additions and 21 deletions

View File

@@ -0,0 +1,310 @@
# AI Service Token 记录集成总结
## 概述
已成功将 Token 使用记录功能集成到 `ai_service.js` 中的所有 AI 调用方法。所有方法现在都会自动记录:
- Token 使用量(输入、输出、总计)
- 调用费用
- 响应时间
- 请求和响应内容
- 调用状态(成功/失败)
## 集成方法列表
### 1. **chat()** - 核心聊天方法
- **行号**: 33-95
- **集成方式**: 内置 Token 记录逻辑
- **记录时机**:
- 成功调用:记录完整 Token 数据和响应内容
- 失败调用:记录错误信息和失败状态
- **特性**:
- 异步记录,不阻塞主流程
- 自动计算费用(基于 DeepSeek 定价)
- 捕获异常防止记录失败影响业务
### 2. **analyzeResume()** - 简历分析
- **行号**: 129-199
- **参数更新**: 添加 `context = {}` 参数
- **业务类型**: `resume_analysis`
- **服务类型**: `completion`
- **reference_id**: `resumeData.id``resumeData.resumeId`
- **使用示例**:
```javascript
const result = await aiService.analyzeResume(resumeData, {
user_id: 123,
sn_code: 'DEVICE001'
});
```
### 3. **matchJobWithResume()** - 岗位匹配度评估
- **行号**: 208-283
- **参数更新**: 添加 `context = {}` 参数
- **业务类型**: `job_matching`
- **服务类型**: `completion`
- **reference_id**: `jobData.id``jobData.jobId`
- **使用示例**:
```javascript
const matchResult = await aiService.matchJobWithResume(jobData, resumeData, {
user_id: 123,
sn_code: 'DEVICE001'
});
```
### 4. **batchMatchJobs()** - 批量岗位匹配
- **行号**: 293-321
- **参数更新**: 添加 `context = {}` 参数
- **集成方式**: 将 context 传递给 `matchJobWithResume()`
- **特性**:
- 并发控制(每批 3 个)
- 自动重试和错误处理
- 每批之间间隔 1 秒防止 API 限流
- **使用示例**:
```javascript
const results = await aiService.batchMatchJobs(jobs, resumeData, {
user_id: 123,
sn_code: 'DEVICE001'
});
```
### 5. **generateChatContent()** - 生成聊天内容
- **行号**: 328-397
- **参数更新**: context 中提取 `user_id``sn_code`
- **业务类型**: `chat_generation`
- **服务类型**: `chat`
- **reference_id**: `jobInfo.jobId``jobInfo.id`
- **使用示例**:
```javascript
const chatContent = await aiService.generateChatContent({
jobInfo: { jobId: 456, jobTitle: 'Node.js开发' },
resumeInfo: resumeData,
chatType: 'greeting',
user_id: 123,
sn_code: 'DEVICE001'
});
```
### 6. **detectInterviewInvitation()** - 面试邀约检测
- **行号**: 405-454
- **参数更新**: 添加 `context = {}` 参数
- **业务类型**: `interview_detection`
- **服务类型**: `completion`
- **reference_id**: `context.conversation_id``context.job_id`
- **使用示例**:
```javascript
const result = await aiService.detectInterviewInvitation(hrMessage, {
user_id: 123,
sn_code: 'DEVICE001',
conversation_id: 789
});
```
### 7. **analyzeSentiment()** - 情感分析
- **行号**: 462-503
- **参数更新**: 添加 `context = {}` 参数
- **业务类型**: `sentiment_analysis`
- **服务类型**: `completion`
- **reference_id**: `context.conversation_id``context.job_id`
- **使用示例**:
```javascript
const sentiment = await aiService.analyzeSentiment(hrMessage, {
user_id: 123,
sn_code: 'DEVICE001',
job_id: 456
});
```
## 辅助方法
### **recordAiCall()** - 记录 AI 调用
- **行号**: 102-109
- **功能**: 调用 `AiCallRecorder.record()` 记录数据
- **异常处理**: 记录失败不影响主流程,仅输出警告日志
### **calculateCost()** - 计算费用
- **行号**: 116-121
- **定价**: ¥0.001 / 1000 tokensDeepSeek 示例价格)
- **返回**: 费用金额(元)
- **可调整**: 可根据实际 API 定价修改 `pricePerThousand`
## 业务类型分类
| 业务类型 | 说明 | 对应方法 |
|---------|------|---------|
| `resume_analysis` | 简历竞争力分析 | analyzeResume() |
| `job_matching` | 岗位匹配度评估 | matchJobWithResume() |
| `chat_generation` | 聊天内容生成 | generateChatContent() |
| `interview_detection` | 面试邀约检测 | detectInterviewInvitation() |
| `sentiment_analysis` | 情感分析 | analyzeSentiment() |
| `chat` | 通用聊天 | chat()(直接调用) |
## 服务类型分类
| 服务类型 | 说明 |
|---------|------|
| `chat` | 对话式交互 |
| `completion` | 文本生成/分析 |
| `embedding` | 向量化(未使用) |
## Context 参数说明
所有方法支持的 context 参数:
```javascript
{
user_id: Number, // 用户ID必填
sn_code: String, // 设备序列号(可选)
conversation_id: Number, // 会话ID用于聊天相关
job_id: Number, // 岗位ID用于岗位相关
// ... 其他业务字段
}
```
## 向后兼容性
所有 context 参数都是**可选的**(默认值 `{}`),因此:
- ✅ 现有代码无需修改即可继续运行
- ✅ 仅在需要 Token 追踪时传递 context
- ✅ 未传递 context 时,相关字段为 `null`(仍会记录基础信息)
## 数据库记录字段
每次 AI 调用会记录以下信息到 `ai_call_records` 表:
```javascript
{
user_id: Number, // 用户ID
sn_code: String, // 设备序列号
service_type: String, // 服务类型chat/completion/embedding
model_name: String, // 模型名称(如 deepseek-chat
prompt_tokens: Number, // 输入Token数
completion_tokens: Number, // 输出Token数
total_tokens: Number, // 总Token数
request_content: String, // 请求内容JSON字符串
response_content: String, // 响应内容
cost_amount: Decimal, // 费用(元)
status: String, // 状态success/failed/timeout
response_time: Number, // 响应时间(毫秒)
error_message: String, // 错误信息(失败时)
api_provider: String, // API提供商deepseek
business_type: String, // 业务类型
reference_id: Number, // 业务关联ID
create_time: DateTime // 创建时间
}
```
## 使用建议
### 1. **始终传递 user_id**
```javascript
// ✅ 推荐
await aiService.analyzeResume(resumeData, {
user_id: ctx.session.userId,
sn_code: ctx.headers['device-sn']
});
// ❌ 不推荐(无法追踪用户)
await aiService.analyzeResume(resumeData);
```
### 2. **为批量操作传递统一 context**
```javascript
const context = {
user_id: 123,
sn_code: 'DEVICE001'
};
// 所有批量调用都会记录相同的 user_id 和 sn_code
await aiService.batchMatchJobs(jobs, resumeData, context);
```
### 3. **传递业务关联 ID**
```javascript
await aiService.matchJobWithResume(jobData, resumeData, {
user_id: 123,
sn_code: 'DEVICE001'
});
// reference_id 会自动设置为 jobData.id 或 jobData.jobId
await aiService.detectInterviewInvitation(message, {
user_id: 123,
conversation_id: 789 // 手动指定会话ID
});
```
### 4. **监控失败调用**
```javascript
try {
const result = await aiService.analyzeResume(resumeData, context);
} catch (error) {
// 即使调用失败也会记录到数据库status='failed'
console.error('AI调用失败已记录到数据库:', error.message);
}
```
## 性能优化
1. **异步记录**:所有 Token 记录都是异步执行,不会阻塞 AI 调用的返回
2. **错误隔离**:记录失败仅打印警告日志,不会抛出异常
3. **批量优化**`batchMatchJobs()` 使用并发控制,避免 API 限流
## 费用计算
当前定价(可调整):
- **DeepSeek**: ¥0.001 / 1000 tokens
修改定价:编辑 [ai_service.js:119](../api/services/ai_service.js#L119)
```javascript
calculateCost(totalTokens) {
const pricePerThousand = 0.001; // 修改此值
return (totalTokens / 1000) * pricePerThousand;
}
```
## 统计查询示例
在后台管理界面可以查询:
- 按用户统计 Token 使用量
- 按设备统计
- 按业务类型统计
- 按日期范围统计
- 按模型统计费用
访问:后台管理 → 系统设置 → AI调用记录
## 测试验证
执行以下命令测试集成:
```bash
# 测试简历分析
node -e "
const aiService = require('./api/services/ai_service.js').getInstance();
aiService.analyzeResume({
fullName: '张三',
workYears: 3,
education: '本科',
skills: ['Node.js', 'Vue.js']
}, {
user_id: 999,
sn_code: 'TEST001'
}).then(console.log);
"
# 查看数据库记录
mysql -u root -p -e "SELECT id, user_id, business_type, total_tokens, cost_amount, status FROM ai_call_records ORDER BY id DESC LIMIT 5;"
```
## 更新日志
**2025-12-27**
- ✅ 集成 AiCallRecorder 到 ai_service.js
- ✅ 更新所有 AI 方法支持 context 参数
- ✅ 实现自动 Token 记录和费用计算
- ✅ 保持向后兼容性context 为可选参数)
- ✅ 添加异步记录和错误隔离机制
---
**集成完成!** 🎉
所有 AI 调用现在都会自动记录 Token 使用情况,可通过后台管理界面查看详细统计数据。