-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathSparkAI.js
More file actions
157 lines (139 loc) · 5.77 KB
/
SparkAI.js
File metadata and controls
157 lines (139 loc) · 5.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
* SparkAI 客户端 - 讯飞星火认知大模型接口封装
*
* 功能说明:
* - 封装讯飞星火认知大模型的 API 调用
* - 支持多用户上下文管理
* - 自动维护对话历史记录
* - 提供简洁的问答接口
*
* 相关链接:
* - 服务控制台: https://console.xfyun.cn/services/bm4
* - 私有数据集: https://xinghuo.xfyun.cn/botcenter/private-dataset
*/
import axios from 'axios';
/**
* SparkAI 客户端类
*
* @class SparkAI
* @description 提供与讯飞星火认知大模型服务的交互接口,支持多用户上下文管理
*/
class SparkAI {
/**
* 构造函数
*
* @param {Object} config - 配置对象
* @param {string} config.authKey - 讯飞星火的认证密钥(必需)
* @param {string} [config.baseURL='https://spark-api-open.xf-yun.com'] - API 基础地址
* @throws {Error} 当缺少必需的 authKey 参数时抛出错误
*/
constructor({authKey, baseURL}) {
if (!authKey) {
throw new Error('Missing required configuration parameters.');
}
/** @type {string} 认证密钥 */
this.authKey = authKey;
/** @type {string} API 基础地址 */
this.baseURL = baseURL || 'https://spark-api-open.xf-yun.com';
/** @type {Object<string, Array>} 存储每个用户的对话上下文 */
this.userContexts = {};
}
/**
* 初始化用户上下文
*
* @param {string} userId - 用户唯一标识符
* @description 为新用户创建初始对话上下文,包含系统提示词
*/
initUserContext(userId) {
if (!this.userContexts[userId]) {
this.userContexts[userId] = [
{
role: "system",
content: "你是一名优秀的AI助手,知道最新的互联网内容,善用搜索引擎和github并总结最贴切的结论来回答我提出的每一个问题"
}
];
}
}
/**
* 更新用户上下文
*
* @param {string} userId - 用户唯一标识符
* @param {Object} message - 要添加的消息对象
* @param {string} message.role - 消息角色('user' 或 'assistant')
* @param {string} message.content - 消息内容
* @description 将新消息添加到用户上下文中,并自动管理上下文长度(最多保留20条消息)
*/
updateUserContext(userId, message) {
this.userContexts[userId].push(message);
// 控制上下文长度,保留最新的20条消息(包含系统消息)
if (this.userContexts[userId].length > 20) {
// 保留系统消息和最新的19条消息
const systemMessage = this.userContexts[userId][0];
const recentMessages = this.userContexts[userId].slice(-19);
this.userContexts[userId] = [systemMessage, ...recentMessages];
}
}
/**
* 向讯飞星火 AI 发送问题并获取回答
*
* @param {string} userId - 用户唯一标识符
* @param {string} prompt - 用户的问题或提示
* @param {Object} [options={}] - 可选参数
* @param {number} [options.temperature] - 回答的随机性(0-1)
* @param {number} [options.max_tokens] - 最大回答长度
* @param {string} [options.model] - 使用的模型名称
* @param {number} [options.top_p] - 核采样参数
* @returns {Promise<string>} AI 的回答内容
* @throws {Error} 当 API 调用失败时抛出错误
*
* @example
* const sparkAI = new SparkAI({ authKey: 'your-auth-key' });
* const answer = await sparkAI.ask('user123', '请介绍一下人工智能的发展历程');
* console.log(answer);
*/
async ask(userId, prompt, options = {}) {
// 确保用户上下文已初始化
this.initUserContext(userId);
// 构建请求载荷
const payload = {
model: options.model || '4.0Ultra', // 默认使用 4.0Ultra 模型
messages: this.userContexts[userId].concat([{
role: 'user',
content: prompt
}]),
...options, // 合并其他选项,如 temperature、max_tokens 等
};
// 调试输出请求载荷
console.log('SparkAI API Request Payload:', payload);
try {
// 发送 API 请求
const response = await axios.post(`${this.baseURL}/v1/chat/completions`, payload, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.authKey}`, // Bearer 认证
},
});
// 处理响应数据
if (response.data && response.data.choices && response.data.choices.length > 0) {
const assistantMessage = response.data.choices[0].message;
// 将 AI 的回答添加到用户上下文中
this.updateUserContext(userId, assistantMessage);
return assistantMessage.content;
} else {
throw new Error(
`Error from Spark AI: ${response.data.error || 'No valid response received'}`
);
}
} catch (error) {
// 记录错误并重新抛出
console.error('Error while communicating with Spark AI:', error.message);
// 如果是 axios 错误,提供更详细的错误信息
if (error.response) {
const errorMsg = error.response.data?.error?.message || error.response.statusText;
throw new Error(`Spark AI API Error (${error.response.status}): ${errorMsg}`);
}
throw error;
}
}
}
export default SparkAI;