8.9 KiB
8.9 KiB
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 - 使用示例:
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 - 使用示例:
const matchResult = await aiService.matchJobWithResume(jobData, resumeData, {
user_id: 123,
sn_code: 'DEVICE001'
});
4. batchMatchJobs() - 批量岗位匹配
- 行号: 293-321
- 参数更新: 添加
context = {}参数 - 集成方式: 将 context 传递给
matchJobWithResume() - 特性:
- 并发控制(每批 3 个)
- 自动重试和错误处理
- 每批之间间隔 1 秒防止 API 限流
- 使用示例:
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 - 使用示例:
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 - 使用示例:
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 - 使用示例:
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 tokens(DeepSeek 示例价格)
- 返回: 费用金额(元)
- 可调整: 可根据实际 API 定价修改
pricePerThousand
业务类型分类
| 业务类型 | 说明 | 对应方法 |
|---|---|---|
resume_analysis |
简历竞争力分析 | analyzeResume() |
job_matching |
岗位匹配度评估 | matchJobWithResume() |
chat_generation |
聊天内容生成 | generateChatContent() |
interview_detection |
面试邀约检测 | detectInterviewInvitation() |
sentiment_analysis |
情感分析 | analyzeSentiment() |
chat |
通用聊天 | chat()(直接调用) |
服务类型分类
| 服务类型 | 说明 |
|---|---|
chat |
对话式交互 |
completion |
文本生成/分析 |
embedding |
向量化(未使用) |
Context 参数说明
所有方法支持的 context 参数:
{
user_id: Number, // 用户ID(必填)
sn_code: String, // 设备序列号(可选)
conversation_id: Number, // 会话ID(用于聊天相关)
job_id: Number, // 岗位ID(用于岗位相关)
// ... 其他业务字段
}
向后兼容性
所有 context 参数都是可选的(默认值 {}),因此:
- ✅ 现有代码无需修改即可继续运行
- ✅ 仅在需要 Token 追踪时传递 context
- ✅ 未传递 context 时,相关字段为
null(仍会记录基础信息)
数据库记录字段
每次 AI 调用会记录以下信息到 ai_call_records 表:
{
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
// ✅ 推荐
await aiService.analyzeResume(resumeData, {
user_id: ctx.session.userId,
sn_code: ctx.headers['device-sn']
});
// ❌ 不推荐(无法追踪用户)
await aiService.analyzeResume(resumeData);
2. 为批量操作传递统一 context
const context = {
user_id: 123,
sn_code: 'DEVICE001'
};
// 所有批量调用都会记录相同的 user_id 和 sn_code
await aiService.batchMatchJobs(jobs, resumeData, context);
3. 传递业务关联 ID
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. 监控失败调用
try {
const result = await aiService.analyzeResume(resumeData, context);
} catch (error) {
// 即使调用失败,也会记录到数据库(status='failed')
console.error('AI调用失败,已记录到数据库:', error.message);
}
性能优化
- 异步记录:所有 Token 记录都是异步执行,不会阻塞 AI 调用的返回
- 错误隔离:记录失败仅打印警告日志,不会抛出异常
- 批量优化:
batchMatchJobs()使用并发控制,避免 API 限流
费用计算
当前定价(可调整):
- DeepSeek: ¥0.001 / 1000 tokens
修改定价:编辑 ai_service.js:119
calculateCost(totalTokens) {
const pricePerThousand = 0.001; // 修改此值
return (totalTokens / 1000) * pricePerThousand;
}
统计查询示例
在后台管理界面可以查询:
- 按用户统计 Token 使用量
- 按设备统计
- 按业务类型统计
- 按日期范围统计
- 按模型统计费用
访问:后台管理 → 系统设置 → AI调用记录
测试验证
执行以下命令测试集成:
# 测试简历分析
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 使用情况,可通过后台管理界面查看详细统计数据。