@weisiren000/oiiai 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +359 -27
- package/dist/index.d.mts +1762 -17
- package/dist/index.d.ts +1762 -17
- package/dist/index.js +3154 -797
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3135 -789
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 oiiai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
[](https://www.npmjs.com/package/@weisiren000/oiiai)
|
|
11
11
|
|
|
12
|
-
支持 **OpenRouter** · **Gemini** · **Groq** · **HuggingFace** · **ModelScope**
|
|
12
|
+
支持 **OpenRouter** · **Gemini** · **Groq** · **HuggingFace** · **ModelScope** · **DeepSeek** · **Poe** · **Nova**
|
|
13
13
|
|
|
14
|
-
[📖 详细文档](./docs/providers.md) · [🚀 快速开始](#快速开始) · [💡 示例](#使用示例)
|
|
14
|
+
[📖 详细文档](./docs/providers.md) · [🚀 快速开始](#快速开始) · [💡 示例](#使用示例) · [🔗 Fluent API](#-fluent-api-新)
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -20,10 +20,13 @@
|
|
|
20
20
|
## ✨ 特性
|
|
21
21
|
|
|
22
22
|
- 🔌 **统一接口** - 所有 Provider 使用相同 API,学会一个就会全部
|
|
23
|
+
- 🎯 **Fluent API** - 全新链式调用和预设实例,极简代码完成 AI 调用
|
|
23
24
|
- 🧠 **Reasoning 支持** - 统一的思考模式配置,自动转换各 Provider 格式
|
|
24
25
|
- 🌊 **流式输出** - 支持实时流式响应,区分思考/回答内容
|
|
26
|
+
- 💬 **多轮对话** - 内置对话会话管理,自动维护上下文
|
|
25
27
|
- 📦 **TypeScript** - 完整类型定义,开发体验友好
|
|
26
28
|
- 🔧 **可扩展** - 轻松实现自定义 Provider
|
|
29
|
+
- 🧪 **智能模型检测** - 自动识别思考模型,智能降级处理
|
|
27
30
|
|
|
28
31
|
## 📦 安装
|
|
29
32
|
|
|
@@ -33,16 +36,188 @@ npm install @weisiren000/oiiai
|
|
|
33
36
|
|
|
34
37
|
## 🚀 快速开始
|
|
35
38
|
|
|
39
|
+
### 方式一:Fluent API(推荐 ⭐)
|
|
40
|
+
|
|
41
|
+
最简洁的使用方式,支持预设实例和链式调用:
|
|
42
|
+
|
|
36
43
|
```typescript
|
|
37
|
-
import {
|
|
44
|
+
import { deepseek, openrouter, oiiai } from '@weisiren000/oiiai';
|
|
45
|
+
|
|
46
|
+
// 🎯 预设实例 - 一行代码完成调用
|
|
47
|
+
deepseek.configure({ apiKey: 'your-key' });
|
|
48
|
+
const answer = await deepseek.ask('deepseek-chat', '你好');
|
|
49
|
+
|
|
50
|
+
// 🔗 链式调用 - 灵活配置
|
|
51
|
+
const answer = await oiiai
|
|
52
|
+
.use('deepseek')
|
|
53
|
+
.key('your-key')
|
|
54
|
+
.model('deepseek-chat')
|
|
55
|
+
.system('你是一个友好的助手')
|
|
56
|
+
.temperature(0.7)
|
|
57
|
+
.ask('你好');
|
|
58
|
+
|
|
59
|
+
// 🌊 流式输出
|
|
60
|
+
for await (const chunk of deepseek.stream('deepseek-chat', '写首诗')) {
|
|
61
|
+
process.stdout.write(chunk.text);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 💬 多轮对话
|
|
65
|
+
const chat = deepseek.chat('deepseek-chat');
|
|
66
|
+
await chat.send('你好');
|
|
67
|
+
await chat.send('继续上面的话题');
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 方式二:工厂函数
|
|
71
|
+
|
|
72
|
+
传统方式,适合需要更多控制的场景:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { ai, createProvider } from '@weisiren000/oiiai';
|
|
76
|
+
|
|
77
|
+
// 快捷工厂
|
|
78
|
+
const provider = ai.deepseek('your-api-key');
|
|
79
|
+
const answer = await provider.ask('deepseek-chat', '你好');
|
|
80
|
+
|
|
81
|
+
// 完整配置
|
|
82
|
+
const provider = createProvider({
|
|
83
|
+
provider: 'openrouter',
|
|
84
|
+
apiKey: 'your-api-key',
|
|
85
|
+
baseUrl: 'https://custom.openrouter.ai/api/v1', // 可选
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 🎯 Fluent API(新)
|
|
90
|
+
|
|
91
|
+
全新的 Fluent API 提供两种使用模式:
|
|
38
92
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
93
|
+
### 预设实例
|
|
94
|
+
|
|
95
|
+
预配置的 Provider 实例,开箱即用:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { deepseek, openrouter, gemini, groq } from '@weisiren000/oiiai';
|
|
99
|
+
|
|
100
|
+
// 配置 API Key(二选一)
|
|
101
|
+
deepseek.configure({ apiKey: 'your-key' }); // 显式配置
|
|
102
|
+
openrouter.fromEnv(); // 从环境变量读取 (OPENROUTER_API_KEY)
|
|
43
103
|
|
|
44
104
|
// 简单问答
|
|
45
|
-
const answer = await
|
|
105
|
+
const answer = await deepseek.ask('deepseek-chat', '什么是 TypeScript?');
|
|
106
|
+
|
|
107
|
+
// 带选项的问答
|
|
108
|
+
const answer = await deepseek.ask('deepseek-chat', '解释量子计算', {
|
|
109
|
+
system: '你是一个科学家',
|
|
110
|
+
temperature: 0.7,
|
|
111
|
+
maxTokens: 1000,
|
|
112
|
+
reasoning: { effort: 'high' },
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// 流式输出
|
|
116
|
+
for await (const chunk of deepseek.stream('deepseek-chat', '写一首诗')) {
|
|
117
|
+
if (chunk.type === 'reasoning') {
|
|
118
|
+
console.log('[思考]', chunk.text);
|
|
119
|
+
} else {
|
|
120
|
+
process.stdout.write(chunk.text);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 带回调的流式输出
|
|
125
|
+
await deepseek.streamWithCallbacks('deepseek-chat', '分析这个问题', {
|
|
126
|
+
onReasoning: text => console.log('[思考]', text),
|
|
127
|
+
onContent: text => process.stdout.write(text),
|
|
128
|
+
onDone: result => console.log('\n完成!', result),
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 链式构建器
|
|
133
|
+
|
|
134
|
+
灵活的链式调用,精细控制每个参数:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { oiiai } from '@weisiren000/oiiai';
|
|
138
|
+
|
|
139
|
+
// 基础用法
|
|
140
|
+
const answer = await oiiai
|
|
141
|
+
.use('deepseek')
|
|
142
|
+
.key('your-key')
|
|
143
|
+
.model('deepseek-chat')
|
|
144
|
+
.ask('你好');
|
|
145
|
+
|
|
146
|
+
// 完整配置
|
|
147
|
+
const answer = await oiiai
|
|
148
|
+
.use('openrouter')
|
|
149
|
+
.key('your-key')
|
|
150
|
+
.model('anthropic/claude-sonnet-4')
|
|
151
|
+
.system('你是一个专业的代码助手')
|
|
152
|
+
.temperature(0.7)
|
|
153
|
+
.maxTokens(2000)
|
|
154
|
+
.reasoning({ effort: 'high' })
|
|
155
|
+
.ask('如何实现快速排序?');
|
|
156
|
+
|
|
157
|
+
// 流式输出
|
|
158
|
+
const stream = oiiai
|
|
159
|
+
.use('gemini')
|
|
160
|
+
.key('your-key')
|
|
161
|
+
.model('gemini-2.5-flash')
|
|
162
|
+
.stream()
|
|
163
|
+
.ask('写一个故事');
|
|
164
|
+
|
|
165
|
+
for await (const chunk of stream) {
|
|
166
|
+
process.stdout.write(chunk.text);
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 预设实例与构建器互转
|
|
171
|
+
|
|
172
|
+
从简单开始,需要时再增加复杂度:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { deepseek } from '@weisiren000/oiiai';
|
|
176
|
+
|
|
177
|
+
deepseek.configure({ apiKey: 'your-key' });
|
|
178
|
+
|
|
179
|
+
// 从预设实例获取构建器
|
|
180
|
+
const builder = deepseek.builder('deepseek-chat');
|
|
181
|
+
|
|
182
|
+
// 继续链式配置
|
|
183
|
+
const answer = await builder
|
|
184
|
+
.system('你是一个诗人')
|
|
185
|
+
.temperature(0.9)
|
|
186
|
+
.ask('写一首关于春天的诗');
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 多轮对话
|
|
190
|
+
|
|
191
|
+
内置对话会话管理,自动维护上下文:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { deepseek } from '@weisiren000/oiiai';
|
|
195
|
+
|
|
196
|
+
deepseek.configure({ apiKey: 'your-key' });
|
|
197
|
+
|
|
198
|
+
// 创建对话会话
|
|
199
|
+
const chat = deepseek.chat('deepseek-chat', {
|
|
200
|
+
system: '你是一个友好的助手',
|
|
201
|
+
temperature: 0.7,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// 多轮对话
|
|
205
|
+
const reply1 = await chat.send('你好,我叫小明');
|
|
206
|
+
console.log(reply1); // "你好小明!很高兴认识你..."
|
|
207
|
+
|
|
208
|
+
const reply2 = await chat.send('我叫什么名字?');
|
|
209
|
+
console.log(reply2); // "你叫小明..."
|
|
210
|
+
|
|
211
|
+
// 流式对话
|
|
212
|
+
for await (const chunk of chat.sendStream('给我讲个笑话')) {
|
|
213
|
+
process.stdout.write(chunk.text);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// 查看对话历史
|
|
217
|
+
console.log(chat.getHistory());
|
|
218
|
+
|
|
219
|
+
// 清空历史开始新对话
|
|
220
|
+
chat.clearHistory();
|
|
46
221
|
```
|
|
47
222
|
|
|
48
223
|
## 💡 使用示例
|
|
@@ -112,17 +287,24 @@ console.log('最终答案:', result.content);
|
|
|
112
287
|
|
|
113
288
|
## 🔧 支持的 Provider
|
|
114
289
|
|
|
115
|
-
| Provider | 服务商 | Reasoning 参数 |
|
|
116
|
-
| ------------- | ------------- | ---------------------------- |
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
290
|
+
| Provider | 服务商 | Reasoning 参数 | 支持思考模型 | 环境变量 |
|
|
291
|
+
| ------------- | ------------- | ---------------------------- | ------------ | --------------------- |
|
|
292
|
+
| `deepseek` | DeepSeek | `thinking.type: 'enabled'` | ✅ | `DEEPSEEK_API_KEY` |
|
|
293
|
+
| `openrouter` | OpenRouter | `reasoning.effort` | ✅ | `OPENROUTER_API_KEY` |
|
|
294
|
+
| `gemini` | Google Gemini | `reasoning_effort` | ✅ | `GEMINI_API_KEY` |
|
|
295
|
+
| `groq` | Groq | `reasoning_format: 'parsed'` | ✅ | `GROQ_API_KEY` |
|
|
296
|
+
| `huggingface` | HuggingFace | 取决于具体模型 | ⚠️ 部分模型 | `HUGGINGFACE_API_KEY` |
|
|
297
|
+
| `modelscope` | 魔搭社区 | `enable_thinking` | ✅ | `MODELSCOPE_API_KEY` |
|
|
298
|
+
| `poe` | Poe | `reasoning_effort` | ✅ | `POE_API_KEY` |
|
|
299
|
+
| `nova` | AWS Nova | `reasoningConfig.type` | ✅ | `NOVA_API_KEY` |
|
|
122
300
|
|
|
123
301
|
## 📝 常用模型
|
|
124
302
|
|
|
125
303
|
```typescript
|
|
304
|
+
// DeepSeek
|
|
305
|
+
'deepseek-chat'; // DeepSeek-V3 通用对话
|
|
306
|
+
'deepseek-reasoner'; // DeepSeek-R1 推理模型
|
|
307
|
+
|
|
126
308
|
// OpenRouter
|
|
127
309
|
'openai/gpt-4o';
|
|
128
310
|
'anthropic/claude-sonnet-4';
|
|
@@ -134,32 +316,182 @@ console.log('最终答案:', result.content);
|
|
|
134
316
|
|
|
135
317
|
// Groq
|
|
136
318
|
'llama-3.3-70b-versatile';
|
|
137
|
-
'
|
|
319
|
+
'mixtral-8x7b-32768';
|
|
138
320
|
|
|
139
|
-
//
|
|
140
|
-
'
|
|
141
|
-
'
|
|
321
|
+
// Poe (使用 bot 名称)
|
|
322
|
+
'GPT-4o';
|
|
323
|
+
'Claude-3.5-Sonnet';
|
|
324
|
+
|
|
325
|
+
// AWS Nova
|
|
326
|
+
'nova-2-lite-v1';
|
|
327
|
+
'nova-2-v1';
|
|
328
|
+
'nova-premier-v1';
|
|
142
329
|
```
|
|
143
330
|
|
|
144
|
-
##
|
|
331
|
+
## 🌍 环境变量
|
|
332
|
+
|
|
333
|
+
推荐使用 `.env` 文件管理 API 密钥:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
# .env
|
|
337
|
+
DEEPSEEK_API_KEY=sk-xxx
|
|
338
|
+
OPENROUTER_API_KEY=sk-or-xxx
|
|
339
|
+
GEMINI_API_KEY=xxx
|
|
340
|
+
GROQ_API_KEY=gsk_xxx
|
|
341
|
+
HUGGINGFACE_API_KEY=hf_xxx
|
|
342
|
+
MODELSCOPE_API_KEY=xxx
|
|
343
|
+
POE_API_KEY=xxx
|
|
344
|
+
NOVA_API_KEY=xxx
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
import 'dotenv/config';
|
|
349
|
+
import { deepseek, openrouter } from '@weisiren000/oiiai';
|
|
350
|
+
|
|
351
|
+
// 从环境变量读取配置
|
|
352
|
+
deepseek.fromEnv();
|
|
353
|
+
openrouter.fromEnv();
|
|
354
|
+
|
|
355
|
+
const answer = await deepseek.ask('deepseek-chat', '你好');
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## 🧪 高级用法
|
|
359
|
+
|
|
360
|
+
### 智能模型检测与降级
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
import { ModelDetection, detectByModelName } from '@weisiren000/oiiai';
|
|
364
|
+
|
|
365
|
+
// 基于模型名称模式检测
|
|
366
|
+
const characteristics = detectByModelName('deepseek-r1');
|
|
367
|
+
console.log(characteristics.behavior); // 'thinking-first'
|
|
368
|
+
|
|
369
|
+
// 自定义降级策略
|
|
370
|
+
provider.configureFallback({
|
|
371
|
+
enabled: true,
|
|
372
|
+
returnReasoningAsContent: true,
|
|
373
|
+
extractConclusionFromReasoning: true,
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### 场景化问答
|
|
145
378
|
|
|
146
379
|
```typescript
|
|
147
|
-
|
|
148
|
-
|
|
380
|
+
const answer = await provider.askWithScenario(
|
|
381
|
+
'deepseek-r1',
|
|
382
|
+
'证明勾股定理',
|
|
383
|
+
'math' // 'simple' | 'math' | 'reasoning' | 'fast'
|
|
384
|
+
);
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## 🛠️ 自定义 Provider
|
|
149
388
|
|
|
150
|
-
|
|
389
|
+
### 使用适配器模式(推荐)
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import {
|
|
393
|
+
BaseAdapter,
|
|
394
|
+
ProviderRegistry,
|
|
395
|
+
RequestBuilder,
|
|
396
|
+
StreamProcessor,
|
|
397
|
+
} from '@weisiren000/oiiai';
|
|
398
|
+
|
|
399
|
+
class MyAdapter extends BaseAdapter {
|
|
151
400
|
readonly name = 'my-provider';
|
|
152
401
|
|
|
153
|
-
|
|
154
|
-
|
|
402
|
+
getEndpointUrl(baseUrl: string): string {
|
|
403
|
+
return `${baseUrl}/v1/chat/completions`;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
buildChatRequest(options: ChatOptions): Record<string, unknown> {
|
|
407
|
+
return RequestBuilder.buildChatBody(options);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
parseChatResponse(
|
|
411
|
+
response: Record<string, unknown>,
|
|
412
|
+
model: string
|
|
413
|
+
): ChatResult {
|
|
414
|
+
// 解析响应
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
extractStreamChunk(delta: Record<string, unknown>): StreamChunk | null {
|
|
418
|
+
// 提取流式数据块
|
|
155
419
|
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// 注册并使用
|
|
423
|
+
ProviderRegistry.register(new MyAdapter());
|
|
424
|
+
const provider = createProvider({ provider: 'my-provider', apiKey: 'xxx' });
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## 🏗️ 架构概览
|
|
428
|
+
|
|
429
|
+
```
|
|
430
|
+
┌─────────────────────────────────────────────────────────┐
|
|
431
|
+
│ Fluent API (新) │
|
|
432
|
+
│ 预设实例 / 链式构建器 / 对话会话 │
|
|
433
|
+
├─────────────────────────────────────────────────────────┤
|
|
434
|
+
│ 用户层 (API) │
|
|
435
|
+
│ createProvider / ai 快捷函数 │
|
|
436
|
+
├─────────────────────────────────────────────────────────┤
|
|
437
|
+
│ 注册层 (Registry) │
|
|
438
|
+
│ ProviderRegistry │
|
|
439
|
+
├─────────────────────────────────────────────────────────┤
|
|
440
|
+
│ 适配器层 (Adapter) │
|
|
441
|
+
│ OpenRouterAdapter / GeminiAdapter / GroqAdapter ... │
|
|
442
|
+
├─────────────────────────────────────────────────────────┤
|
|
443
|
+
│ 客户端层 (Client) │
|
|
444
|
+
│ HttpProviderClient │
|
|
445
|
+
├─────────────────────────────────────────────────────────┤
|
|
446
|
+
│ 工具层 (Utils) │
|
|
447
|
+
│ StreamProcessor / RequestBuilder / ConfigValidator │
|
|
448
|
+
└─────────────────────────────────────────────────────────┘
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## ❓ 故障排除
|
|
452
|
+
|
|
453
|
+
### 常见问题
|
|
454
|
+
|
|
455
|
+
**Q: 为什么某些思考模型返回的 `content` 为空?**
|
|
456
|
+
A: 思考模型在低 token 限制下可能只输出 reasoning。启用智能降级策略或增加 `maxTokens` 即可解决。
|
|
457
|
+
|
|
458
|
+
**Q: 如何自定义 API 地址?**
|
|
459
|
+
A: 使用 `baseUrl` 参数:
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
// Fluent API
|
|
463
|
+
deepseek.configure({ apiKey: 'xxx', baseUrl: 'https://custom.api.com' });
|
|
156
464
|
|
|
157
|
-
|
|
158
|
-
|
|
465
|
+
// 或链式调用
|
|
466
|
+
oiiai.use('deepseek').key('xxx').baseUrl('https://custom.api.com');
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Q: 流式输出中如何区分思考和回答?**
|
|
470
|
+
A: 检查 `chunk.type`:`'reasoning'` 表示思考内容,`'content'` 表示最终回答。
|
|
471
|
+
|
|
472
|
+
### 错误处理
|
|
473
|
+
|
|
474
|
+
```typescript
|
|
475
|
+
import { ConfigurationError, APIError } from '@weisiren000/oiiai';
|
|
476
|
+
|
|
477
|
+
try {
|
|
478
|
+
const answer = await deepseek.ask('model', 'question');
|
|
479
|
+
} catch (error) {
|
|
480
|
+
if (error instanceof ConfigurationError) {
|
|
481
|
+
console.error('配置错误:', error.message);
|
|
482
|
+
} else if (error instanceof APIError) {
|
|
483
|
+
console.error('API 错误:', error.message);
|
|
159
484
|
}
|
|
160
485
|
}
|
|
161
486
|
```
|
|
162
487
|
|
|
488
|
+
## 📚 更多文档
|
|
489
|
+
|
|
490
|
+
- [API 参考](./docs/API.md) - 完整的 API 文档
|
|
491
|
+
- [Provider 指南](./docs/providers.md) - 各 Provider 详细说明
|
|
492
|
+
- [快速上手指南](./docs/quickstart.md) - 新手入门教程
|
|
493
|
+
- [贡献指南](./CONTRIBUTING.md) - 如何参与贡献
|
|
494
|
+
|
|
163
495
|
## 📄 License
|
|
164
496
|
|
|
165
497
|
MIT
|