aicodeswitch 4.0.3 → 5.0.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.
Files changed (77) hide show
  1. package/README.md +7 -6
  2. package/UPGRADE.md +5 -6
  3. package/dist/server/coding-plan.js +94 -0
  4. package/dist/server/config-managed-fields.js +1 -0
  5. package/dist/server/conversions/compact.js +613 -0
  6. package/dist/server/conversions/detector.js +70 -0
  7. package/dist/server/conversions/index.js +285 -0
  8. package/dist/server/conversions/pairs/claude-completions/request.js +167 -0
  9. package/dist/server/conversions/pairs/claude-completions/response.js +56 -0
  10. package/dist/server/conversions/pairs/claude-completions/streaming.js +259 -0
  11. package/dist/server/conversions/pairs/claude-gemini/request.js +130 -0
  12. package/dist/server/conversions/pairs/claude-gemini/response.js +65 -0
  13. package/dist/server/conversions/pairs/claude-gemini/streaming.js +199 -0
  14. package/dist/server/conversions/pairs/claude-responses/request.js +190 -0
  15. package/dist/server/conversions/pairs/claude-responses/response.js +89 -0
  16. package/dist/server/conversions/pairs/claude-responses/streaming.js +266 -0
  17. package/dist/server/conversions/pairs/completions-claude/request.js +111 -0
  18. package/dist/server/conversions/pairs/completions-claude/response.js +67 -0
  19. package/dist/server/conversions/pairs/completions-claude/streaming.js +165 -0
  20. package/dist/server/conversions/pairs/completions-gemini/request.js +169 -0
  21. package/dist/server/conversions/pairs/completions-gemini/response.js +70 -0
  22. package/dist/server/conversions/pairs/completions-gemini/streaming.js +132 -0
  23. package/dist/server/conversions/pairs/completions-responses/request.js +149 -0
  24. package/dist/server/conversions/pairs/completions-responses/response.js +74 -0
  25. package/dist/server/conversions/pairs/completions-responses/streaming.js +189 -0
  26. package/dist/server/conversions/pairs/gemini-claude/request.js +118 -0
  27. package/dist/server/conversions/pairs/gemini-claude/response.js +45 -0
  28. package/dist/server/conversions/pairs/gemini-claude/streaming.js +146 -0
  29. package/dist/server/conversions/pairs/gemini-completions/request.js +151 -0
  30. package/dist/server/conversions/pairs/gemini-completions/response.js +54 -0
  31. package/dist/server/conversions/pairs/gemini-completions/streaming.js +108 -0
  32. package/dist/server/conversions/pairs/gemini-responses/request.js +18 -0
  33. package/dist/server/conversions/pairs/gemini-responses/response.js +18 -0
  34. package/dist/server/conversions/pairs/gemini-responses/streaming.js +43 -0
  35. package/dist/server/conversions/pairs/responses-claude/request.js +155 -0
  36. package/dist/server/conversions/pairs/responses-claude/response.js +70 -0
  37. package/dist/server/conversions/pairs/responses-claude/streaming.js +345 -0
  38. package/dist/server/conversions/pairs/responses-completions/request.js +207 -0
  39. package/dist/server/conversions/pairs/responses-completions/response.js +96 -0
  40. package/dist/server/conversions/pairs/responses-completions/streaming.js +344 -0
  41. package/dist/server/conversions/pairs/responses-gemini/request.js +18 -0
  42. package/dist/server/conversions/pairs/responses-gemini/response.js +18 -0
  43. package/dist/server/conversions/pairs/responses-gemini/streaming.js +43 -0
  44. package/dist/server/conversions/pairs/responses-responses/request.js +115 -0
  45. package/dist/server/conversions/pipeline.js +296 -0
  46. package/dist/server/conversions/stream-converter-adapter.js +49 -0
  47. package/dist/server/conversions/thinking/effort.js +61 -0
  48. package/dist/server/conversions/thinking/mapper.js +59 -0
  49. package/dist/server/conversions/thinking/providers.js +76 -0
  50. package/dist/server/conversions/types.js +5 -0
  51. package/dist/server/conversions/url-normalizer.js +58 -0
  52. package/dist/server/conversions/utils/format-mappers.js +57 -0
  53. package/dist/server/conversions/utils/id.js +33 -0
  54. package/dist/server/conversions/utils/stop-reasons.js +95 -0
  55. package/dist/server/conversions/utils/streaming-helpers.js +59 -0
  56. package/dist/server/conversions/utils/tool-schema.js +169 -0
  57. package/dist/server/conversions/utils/usage.js +82 -0
  58. package/dist/server/fs-database.js +465 -135
  59. package/dist/server/main.js +93 -33
  60. package/dist/server/original-config-reader.js +1 -1
  61. package/dist/server/proxy-server.js +1102 -804
  62. package/dist/server/transformers/chunk-collector.js +5 -1
  63. package/dist/server/transformers/streaming.js +6 -3235
  64. package/dist/server/type-migration.js +2 -3
  65. package/dist/server/utils.js +5 -0
  66. package/dist/ui/assets/{index-C7G0whng.css → index-BHR12ImE.css} +1 -1
  67. package/dist/ui/assets/index-DjdBW1yu.js +517 -0
  68. package/dist/ui/index.html +2 -2
  69. package/package.json +1 -1
  70. package/dist/server/transformers/transformers.js +0 -1767
  71. package/dist/ui/assets/index-Nl6yJxrc.js +0 -514
  72. package/schema/claude.schema.md +0 -946
  73. package/schema/deepseek-chat.schema.md +0 -799
  74. package/schema/gemini.schema.md +0 -1408
  75. package/schema/openai-chat-completions.schema.md +0 -1088
  76. package/schema/openai-responses.schema.md +0 -226196
  77. package/schema/stream.md +0 -2592
@@ -1,1088 +0,0 @@
1
- # OpenAI API Schema 标准参考
2
-
3
- OpenAI 官方 API 数据格式规范和完整使用指南。包括经典 Completions API、Chat Completions API 和最新 Responses API(实时对话)。
4
-
5
- ## 目录
6
- - [API 概览](#api-概览)
7
- - [Completions API(文本补全)](#completions-api文本补全)
8
- - [Chat Completions API(对话模型)](#chat-completions-api对话模型)
9
- - [Responses API(实时对话)](#responses-api实时对话)
10
- - [模型选择](#模型选择)
11
- - [流式事件](#流式事件)
12
- - [错误处理](#错误处理)
13
- - [快速参考](#快速参考)
14
- - [最佳实践](#最佳实践)
15
-
16
- ---
17
-
18
- ## API 概览
19
-
20
- ### 官方 API 端点
21
-
22
- OpenAI 提供三个主要 API 接口,各有不同的用途:
23
-
24
- | API 类型 | 端点 | 用途 | 状态 |
25
- |---------|------|------|------|
26
- | **Responses API** | `/v1/responses` | 新一代响应接口(推荐) | ✅ 最新标准 |
27
- | **Chat Completions API** | `/v1/chat/completions` | 对话、代码生成 | ✅ 仍可用 |
28
- | **Completions API** | `/v1/completions` | 文本补全(已弃用) | ⚠️ 维护模式 |
29
-
30
- ### API 基础配置
31
-
32
- ```
33
- 基础 URL: https://api.openai.com/v1
34
-
35
- 认证方式:
36
- Authorization: Bearer sk-xxxxx
37
-
38
- x-api-key: sk-xxxxx
39
-
40
- Content-Type: application/json
41
- ```
42
-
43
- ---
44
-
45
- ## Completions API(文本补全)
46
-
47
- ### 概述
48
-
49
- **Completions API** 是 OpenAI 早期的文本生成接口,适用于纯文本补全任务。此 API 已不推荐用于新项目,推荐使用 Chat Completions API。
50
-
51
- ### 请求格式
52
-
53
- ```typescript
54
- POST /v1/completions
55
- Host: api.openai.com
56
- Authorization: Bearer sk-xxx
57
- Content-Type: application/json
58
-
59
- {
60
- // ===== 必需字段 =====
61
- "model": string, // 模型ID (例: gpt-3.5-turbo-instruct)
62
- "prompt": string | string[], // 输入提示词,支持数组批量
63
-
64
- // ===== 常用可选字段 =====
65
- "max_tokens"?: number, // 最大输出长度,默认16
66
- "temperature"?: number, // 0.0-2.0,采样温度
67
- "top_p"?: number, // 0.0-1.0,核采样
68
- "frequency_penalty"?: number, // -2.0-2.0,频率惩罚
69
- "presence_penalty"?: number, // -2.0-2.0,出现惩罚
70
- "best_of"?: number, // 生成n个补全,返回最佳的
71
- "echo"?: boolean, // 回显输入提示词
72
- "stop"?: string | string[], // 停止序列
73
- "stream"?: boolean, // 是否流式响应
74
- "suffix"?: string, // 补全文本的后缀
75
- "logit_bias"?: object, // 调整特定token的概率
76
- "n"?: number // 生成多少个补全,默认1
77
- }
78
- ```
79
-
80
- ### 请求示例
81
-
82
- ```bash
83
- curl -X POST https://api.openai.com/v1/completions \
84
- -H "Authorization: Bearer sk-xxx" \
85
- -H "Content-Type: application/json" \
86
- -d '{
87
- "model": "gpt-3.5-turbo-instruct",
88
- "prompt": "将这个句子翻译为英文:'你好世界'",
89
- "max_tokens": 100,
90
- "temperature": 0.7
91
- }'
92
- ```
93
-
94
- ### 响应格式
95
-
96
- ```json
97
- {
98
- "id": "cmpl-8R8e...",
99
- "object": "text_completion",
100
- "created": 1699000000,
101
- "model": "gpt-3.5-turbo-instruct",
102
- "choices": [
103
- {
104
- "text": "\nHello, world!",
105
- "index": 0,
106
- "logprobs": null,
107
- "finish_reason": "length" | "stop" | "content_filter"
108
- }
109
- ],
110
- "usage": {
111
- "prompt_tokens": 15,
112
- "completion_tokens": 10,
113
- "total_tokens": 25
114
- }
115
- }
116
- ```
117
-
118
- ### 参数说明
119
-
120
- - **max_tokens**: 补全的最大token数。设置越高,响应越长但成本更高
121
- - **temperature**: 越低越稳定(0)、越高越随机(2)
122
- - **best_of**: 生成多个补全并返回最佳的,n必须≤best_of
123
- - **suffix**: 在补全后附加的文本
124
-
125
- ---
126
-
127
- ## Chat Completions API(对话模型)
128
-
129
- ### 概述
130
-
131
- **Chat Completions API** 是 OpenAI 推荐的通用 API,支持多轮对话、系统提示、函数调用等高级功能。
132
-
133
- ### 请求格式
134
-
135
- ```typescript
136
- POST /v1/chat/completions
137
- Host: api.openai.com
138
- Authorization: Bearer sk-xxx
139
- Content-Type: application/json
140
-
141
- {
142
- // ===== 必需字段 =====
143
- "model": string, // 模型ID
144
- "messages": Array<Message>, // 消息历史
145
-
146
- // ===== 常用可选字段 =====
147
- "temperature"?: number, // 0-2,采样温度
148
- "top_p"?: number, // 0-1,核采样
149
- "max_tokens"?: number, // 最大输出长度
150
- "frequency_penalty"?: number, // -2-2,频率惩罚
151
- "presence_penalty"?: number, // -2-2,出现惩罚
152
- "stream"?: boolean, // 是否流式响应
153
- "stop"?: string | string[], // 停止序列
154
- "seed"?: number, // 随机种子,确保可复现
155
- "top_logprobs"?: number, // 返回每个位置的概率分布
156
- "logprobs"?: boolean, // 是否返回log概率
157
- "user"?: string, // 终端用户标识,用于滥用检测
158
- "tools"?: Tool[], // 函数定义
159
- "tool_choice"?: "auto" | "required" | object, // 工具调用策略
160
- "function_call"?: "auto" | { "name": string }, // 函数调用(已弃用)
161
- "functions"?: Function[], // 函数定义(已弃用)
162
- "response_format"?: object, // 响应格式(JSON模式)
163
- "logit_bias"?: object // 调整特定token概率
164
- }
165
- ```
166
-
167
- ### 消息格式
168
-
169
- ```typescript
170
- interface Message {
171
- role: "system" | "user" | "assistant" | "tool";
172
- content: string | ContentBlock[];
173
- name?: string; // 消息发送者名字
174
- tool_call_id?: string; // tool响应时必需
175
- tool_calls?: ToolCall[]; // assistant消息中的工具调用
176
- }
177
-
178
- type ContentBlock =
179
- | TextContent
180
- | ImageContent
181
- | ToolCallContent
182
- | ToolResultContent;
183
-
184
- // 文本内容
185
- interface TextContent {
186
- type: "text";
187
- text: string;
188
- }
189
-
190
- // 图像内容(仅vision模型支持)
191
- interface ImageContent {
192
- type: "image_url";
193
- image_url: {
194
- url: string; // URL或data:URI
195
- detail?: "low" | "high" | "auto"; // 图像详细程度
196
- };
197
- }
198
-
199
- // 工具调用
200
- interface ToolCallContent {
201
- type: "tool_call";
202
- id: string;
203
- function: {
204
- name: string;
205
- arguments: string; // JSON字符串
206
- };
207
- }
208
-
209
- // 工具结果
210
- interface ToolResultContent {
211
- type: "tool_result";
212
- tool_use_id: string;
213
- content: string;
214
- is_error?: boolean;
215
- }
216
- ```
217
-
218
- ### 工具定义格式
219
-
220
- ```typescript
221
- interface Tool {
222
- type: "function";
223
- function: {
224
- name: string; // 函数名
225
- description: string; // 功能描述
226
- parameters: {
227
- type: "object";
228
- properties: {
229
- [key: string]: {
230
- type: string; // string, number, boolean, array等
231
- description: string; // 参数说明
232
- enum?: string[]; // 可选值列表
233
- items?: object; // 数组项的类型
234
- };
235
- };
236
- required: string[]; // 必需参数列表
237
- };
238
- strict?: boolean; // 严格模式(GPT-4 Turbo+)
239
- };
240
- }
241
- ```
242
-
243
- ### 请求示例
244
-
245
- ```bash
246
- curl -X POST https://api.openai.com/v1/chat/completions \
247
- -H "Authorization: Bearer sk-xxx" \
248
- -H "Content-Type: application/json" \
249
- -d '{
250
- "model": "gpt-4-turbo",
251
- "messages": [
252
- {
253
- "role": "system",
254
- "content": "You are a helpful assistant."
255
- },
256
- {
257
- "role": "user",
258
- "content": "What is 2+2?"
259
- }
260
- ],
261
- "max_tokens": 100,
262
- "temperature": 0.7
263
- }'
264
- ```
265
-
266
- ### 多轮对话示例
267
-
268
- ```bash
269
- curl -X POST https://api.openai.com/v1/chat/completions \
270
- -H "Authorization: Bearer sk-xxx" \
271
- -d '{
272
- "model": "gpt-4-turbo",
273
- "messages": [
274
- {
275
- "role": "system",
276
- "content": "You are a Python expert."
277
- },
278
- {
279
- "role": "user",
280
- "content": "如何读取文件?"
281
- },
282
- {
283
- "role": "assistant",
284
- "content": "在Python中,你可以使用 open() 函数..."
285
- },
286
- {
287
- "role": "user",
288
- "content": "写一个例子"
289
- }
290
- ]
291
- }'
292
- ```
293
-
294
- ### 函数调用示例
295
-
296
- ```bash
297
- curl -X POST https://api.openai.com/v1/chat/completions \
298
- -H "Authorization: Bearer sk-xxx" \
299
- -d '{
300
- "model": "gpt-4-turbo",
301
- "messages": [
302
- {
303
- "role": "user",
304
- "content": "旧金山现在的天气如何?"
305
- }
306
- ],
307
- "tools": [
308
- {
309
- "type": "function",
310
- "function": {
311
- "name": "get_weather",
312
- "description": "获取指定城市的天气信息",
313
- "parameters": {
314
- "type": "object",
315
- "properties": {
316
- "location": {
317
- "type": "string",
318
- "description": "城市名称"
319
- }
320
- },
321
- "required": ["location"]
322
- }
323
- }
324
- }
325
- ],
326
- "tool_choice": "auto"
327
- }'
328
- ```
329
-
330
- ### 响应格式
331
-
332
- ```json
333
- {
334
- "id": "chatcmpl-8R8e...",
335
- "object": "chat.completion",
336
- "created": 1699000000,
337
- "model": "gpt-4-turbo",
338
- "choices": [
339
- {
340
- "index": 0,
341
- "message": {
342
- "role": "assistant",
343
- "content": "2 + 2 = 4"
344
- },
345
- "finish_reason": "stop" | "length" | "tool_calls" | "content_filter"
346
- }
347
- ],
348
- "usage": {
349
- "prompt_tokens": 20,
350
- "completion_tokens": 10,
351
- "total_tokens": 30
352
- },
353
- "system_fingerprint": "fp_a8d8f..."
354
- }
355
- ```
356
-
357
- ### 工具调用响应示例
358
-
359
- ```json
360
- {
361
- "choices": [
362
- {
363
- "message": {
364
- "role": "assistant",
365
- "content": null,
366
- "tool_calls": [
367
- {
368
- "id": "call_abc123",
369
- "type": "function",
370
- "function": {
371
- "name": "get_weather",
372
- "arguments": "{\"location\": \"San Francisco\"}"
373
- }
374
- }
375
- ]
376
- },
377
- "finish_reason": "tool_calls"
378
- }
379
- ]
380
- }
381
- ```
382
-
383
- ### JSON 响应格式
384
-
385
- ```bash
386
- # 强制JSON输出
387
- curl -X POST https://api.openai.com/v1/chat/completions \
388
- -d '{
389
- "model": "gpt-4-turbo",
390
- "messages": [
391
- {
392
- "role": "user",
393
- "content": "生成一个JSON格式的用户信息"
394
- }
395
- ],
396
- "response_format": {
397
- "type": "json_object"
398
- }
399
- }'
400
- ```
401
-
402
- ## 流式事件
403
-
404
- ### 流式响应启用
405
-
406
- 在请求中添加:
407
- ```json
408
- {"stream": true}
409
- ```
410
-
411
- ### Chat Completions 流式事件
412
-
413
- #### 响应开始
414
-
415
- ```
416
- data: {"id":"chatcmpl-8R8e...","object":"chat.completion.chunk","created":1699000000,"model":"gpt-4-turbo","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
417
- ```
418
-
419
- #### 内容增量
420
-
421
- ```
422
- data: {"choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
423
- data: {"choices":[{"index":0,"delta":{"content":" world"},"finish_reason":null}]}
424
- ```
425
-
426
- #### 工具调用开始
427
-
428
- ```
429
- data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_abc","type":"function","function":{"name":"get_weather","arguments":""}}]},"finish_reason":null}]}
430
- ```
431
-
432
- #### 工具调用参数增量
433
-
434
- ```
435
- data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"loca"}}]},"finish_reason":null}]}
436
- data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"tion\":\"SF"}}]},"finish_reason":null}]}
437
- ```
438
-
439
- #### 响应结束
440
-
441
- ```
442
- data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
443
-
444
- data: [DONE]
445
- ```
446
-
447
- ### 流式请求示例
448
-
449
- ```bash
450
- curl -X POST https://api.openai.com/v1/chat/completions \
451
- -H "Authorization: Bearer sk-xxx" \
452
- -H "Content-Type: application/json" \
453
- -d '{
454
- "model": "gpt-4-turbo",
455
- "messages": [
456
- {"role": "user", "content": "请写一首春天的诗"}
457
- ],
458
- "stream": true
459
- }'
460
- ```
461
-
462
- ### Python 流式处理示例
463
-
464
- ```python
465
- import openai
466
-
467
- with openai.OpenAI(api_key="sk-xxx") as client:
468
- with client.chat.completions.stream(
469
- model="gpt-4-turbo",
470
- messages=[
471
- {"role": "user", "content": "写一首诗"}
472
- ]
473
- ) as stream:
474
- for text in stream.text_stream:
475
- print(text, end="", flush=True)
476
- ```
477
-
478
- ---
479
-
480
- ## 错误处理
481
-
482
- ### 错误响应格式
483
-
484
- ```json
485
- {
486
- "error": {
487
- "message": "错误描述信息",
488
- "type": "error_type",
489
- "param": "参数名称",
490
- "code": "invalid_api_key"
491
- }
492
- }
493
- ```
494
-
495
- ### 常见错误
496
-
497
- | HTTP 状态 | 错误类型 | 原因 | 处理方案 |
498
- |---------|--------|------|--------|
499
- | 400 | invalid_request_error | 参数错误或格式不合法 | 检查请求格式、参数值范围 |
500
- | 401 | authentication_error | API Key 无效或过期 | 更新有效的 API Key |
501
- | 403 | permission_error | 账户没有权限访问该模型 | 检查账户权限和模型可用性 |
502
- | 429 | rate_limit_error | 超过速率限制 | 实施指数退避重试 |
503
- | 500 | server_error | OpenAI 服务器错误 | 重试请求 |
504
- | 503 | service_unavailable_error | 服务暂时不可用 | 稍后重试 |
505
-
506
- ### 错误响应示例
507
-
508
- ```json
509
- {
510
- "error": {
511
- "message": "The model `gpt-4` does not exist",
512
- "type": "invalid_request_error",
513
- "param": "model",
514
- "code": "model_not_found"
515
- }
516
- }
517
- ```
518
-
519
- ### 重试策略
520
-
521
- ```typescript
522
- async function requestWithRetry(
523
- requestFn: () => Promise<any>,
524
- maxRetries: number = 3
525
- ): Promise<any> {
526
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
527
- try {
528
- return await requestFn();
529
- } catch (error: any) {
530
- const status = error.status;
531
- const isRetryable = status === 429 || status >= 500;
532
-
533
- if (!isRetryable || attempt === maxRetries) {
534
- throw error;
535
- }
536
-
537
- // 指数退避:第一次等待1秒,第二次2秒,第三次4秒
538
- const delay = Math.pow(2, attempt - 1) * 1000;
539
- await new Promise(resolve => setTimeout(resolve, delay));
540
- }
541
- }
542
- }
543
- ```
544
-
545
- ---
546
-
547
- ## 快速参考
548
-
549
- ### 常用参数速查
550
-
551
- | 参数 | 范围 | 默认值 | 说明 |
552
- |-----|------|--------|------|
553
- | temperature | 0-2 | 1 | 采样温度,越低越稳定,越高越随机 |
554
- | top_p | 0-1 | 1 | 核采样,与temperature互斥或同用 |
555
- | max_tokens | 1-上限 | - | 最大输出长度 |
556
- | frequency_penalty | -2-2 | 0 | 频率惩罚,减少重复词汇 |
557
- | presence_penalty | -2-2 | 0 | 出现惩罚,鼓励新话题 |
558
- | stream | true/false | false | 是否流式响应 |
559
- | stop | 字符串数组 | - | 停止生成的序列 |
560
- | seed | 整数 | - | 随机种子,确保输出可复现 |
561
-
562
- ### 认证方式
563
-
564
- ```bash
565
- # 方式1:Authorization头(推荐)
566
- Authorization: Bearer sk-xxx
567
-
568
- # 方式2:API Key头
569
- x-api-key: sk-xxx
570
-
571
- # Realtime API 还需要Beta头
572
- OpenAI-Beta: realtime=v1
573
- ```
574
-
575
- ---
576
-
577
- ## 最佳实践
578
-
579
- ### 1. API 选择指南
580
-
581
- ```typescript
582
- // ✅ Chat Completions API(简单对话)
583
- // - 轻量级对话接口
584
- // - 支持函数调用和 Vision
585
- // - 当不需要内置工具和后台处理时使用
586
-
587
- POST /v1/chat/completions
588
- ```
589
-
590
- ### 2. 模型选择原则
591
-
592
- ```typescript
593
- // ✅ 首选 gpt-4o(新项目推荐)
594
- // - 最佳性能/成本比
595
- // - 支持所有高级功能
596
- // - 速度和质量平衡
597
-
598
- // ✅ 成本敏感用 gpt-4o-mini
599
- // - 成本最低
600
- // - 足以处理大多数任务
601
- // - 吞吐量最高
602
-
603
- // ✅ 复杂推理用 gpt-4-turbo
604
- // - 最强推理能力
605
- // - 上下文最大
606
-
607
- // ⚠️ 避免使用 gpt-3.5-turbo
608
- // 除非有明确的遗留兼容性需求
609
- ```
610
-
611
- ### 3. 成本优化
612
-
613
- ```typescript
614
- // 估算请求成本
615
- function estimateCost(
616
- inputTokens: number,
617
- outputTokens: number,
618
- model: string
619
- ) {
620
- const prices = {
621
- 'gpt-4-turbo': { input: 0.01, output: 0.03 },
622
- 'gpt-4o': { input: 0.005, output: 0.015 },
623
- 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },
624
- 'gpt-3.5-turbo': { input: 0.0005, output: 0.0015 }
625
- };
626
-
627
- const price = prices[model];
628
- return (
629
- (inputTokens * price.input + outputTokens * price.output) / 1000000
630
- );
631
- }
632
-
633
- // 优化策略
634
- // 1. 减少重复请求 - 缓存常见查询
635
- // 2. 使用 mini 模型处理简单任务
636
- // 3. 限制 max_tokens 避免冗长响应
637
- // 4. 批量处理而非逐个请求
638
- ```
639
-
640
- ### 4. 错误处理核心清单
641
-
642
- ```typescript
643
- ✅ 捕获所有异常,检查 error.status
644
- ✅ 区分可重试错误(429, 5xx)和不可重试(401, 403)
645
- ✅ 实施指数退避重试策略
646
- ✅ 为流式响应监听每个事件的错误
647
- ✅ 设置合理的请求超时(30-60秒)
648
- ✅ 记录错误详情便于调试
649
- ✅ 对于 429 应优先增加延迟而非重试
650
- ```
651
-
652
- ### 5. 流式 vs 非流式
653
-
654
- ```typescript
655
- // 使用流式响应:
656
- // ✅ 长响应(预期>500 tokens)
657
- // ✅ 需要实时反馈的交互式应用
658
- // ✅ 用户体验优先
659
-
660
- if (expectedLength > 500 || needsRealtimeFeedback) {
661
- stream: true
662
- }
663
-
664
- // 使用非流式响应:
665
- // ✅ 短响应(<100 tokens)
666
- // ✅ 需要完整响应后处理
667
- // ✅ 简单的后端任务
668
-
669
- if (expectedLength < 100 && canWaitForComplete) {
670
- stream: false
671
- }
672
- ```
673
-
674
- ### 6. 函数调用最佳实践
675
-
676
- ```typescript
677
- // ✅ 定义清晰的函数描述
678
- function: {
679
- name: "calculate_distance",
680
- description: "计算两点间的直线距离(单位:公里)",
681
- parameters: {
682
- type: "object",
683
- properties: {
684
- lat1: { type: "number", description: "第一点纬度" },
685
- lon1: { type: "number", description: "第一点经度" },
686
- lat2: { type: "number", description: "第二点纬度" },
687
- lon2: { type: "number", description: "第二点经度" }
688
- },
689
- required: ["lat1", "lon1", "lat2", "lon2"]
690
- }
691
- }
692
-
693
- // ✅ 处理连续调用
694
- for (let turn = 0; turn < maxTurns; turn++) {
695
- const response = await makeRequest();
696
-
697
- if (response.finish_reason !== 'tool_calls') break;
698
-
699
- // 执行所有函数调用
700
- const toolResults = await Promise.all(
701
- response.tool_calls.map(call => executeTool(call))
702
- );
703
-
704
- // 添加结果到消息历史继续对话
705
- messages.push({
706
- role: 'assistant',
707
- content: response.content
708
- });
709
-
710
- messages.push({
711
- role: 'user',
712
- content: toolResults.map(r => ({
713
- type: 'tool_result',
714
- tool_use_id: r.id,
715
- content: r.output
716
- }))
717
- });
718
- }
719
- ```
720
-
721
- ### 7. Vision(图像识别)最佳实践
722
-
723
- ```typescript
724
- // ✅ 使用 detail 参数控制分析粒度
725
- {
726
- type: "image_url",
727
- image_url: {
728
- url: "https://example.com/image.jpg",
729
- detail: "high" // low(快速)/auto(自适应)/high(详细)
730
- }
731
- }
732
-
733
- // ✅ Base64 用于小图像或私密图像
734
- {
735
- type: "image_url",
736
- image_url: {
737
- url: "data:image/jpeg;base64,iVBORw0KGgo..."
738
- }
739
- }
740
-
741
- // ✅ URL 用于公开网络图像
742
- {
743
- type: "image_url",
744
- image_url: {
745
- url: "https://example.com/large-image.jpg"
746
- }
747
- }
748
- ```
749
-
750
- ### 8. 系统提示词工程
751
-
752
- ```typescript
753
- // ✅ 清晰的角色定义和约束
754
- system: `你是一个专业的 Python 代码审查助手。
755
- 对于每个代码片段,你需要:
756
- 1. 识别潜在的性能问题
757
- 2. 指出不遵循 PEP8 的地方
758
- 3. 建议安全改进
759
- 4. 提供重构建议
760
-
761
- 使用简洁、专业的语言。
762
- 每个问题都要提供具体代码示例。`
763
-
764
- // ✅ 避免过度冗长或模糊的指令
765
- // ❌ system: "你是一个助手,帮助人们" // 太模糊
766
- // ✅ system: "你是一个...[具体职责]" // 清晰具体
767
- ```
768
-
769
- ### 9. 速率限制处理
770
-
771
- ```typescript
772
- // OpenAI API 速率限制:
773
- // - 同时连接数:有限制
774
- // - RPM(每分钟请求):有限制
775
- // - TPM(每分钟 token):有限制
776
-
777
- // 应对策略
778
- function throttledRequest(delay: number = 100) {
779
- return new Promise(resolve => {
780
- setTimeout(resolve, delay);
781
- });
782
- }
783
-
784
- async function smartRequest(requestFn) {
785
- while (true) {
786
- try {
787
- return await requestFn();
788
- } catch (error) {
789
- if (error.status === 429) {
790
- // 从响应头读取重试时间
791
- const retryAfter =
792
- error.headers?.['retry-after'] || '60';
793
- await throttledRequest(parseInt(retryAfter) * 1000);
794
- } else {
795
- throw error;
796
- }
797
- }
798
- }
799
- }
800
- ```
801
-
802
- ### 10. 监控和日志
803
-
804
- ```typescript
805
- interface RequestMetrics {
806
- model: string;
807
- inputTokens: number;
808
- outputTokens: number;
809
- totalTokens: number;
810
- responseTime: number; // 毫秒
811
- finishReason: string;
812
- status: 'success' | 'error';
813
- timestamp: Date;
814
- costEstimate: number; // 美元
815
- responseCount?: number; // Responses API 生成的响应数量
816
- }
817
-
818
- // 定期分析
819
- const analytics = {
820
- avgTokensPerRequest: totalTokens / requestCount,
821
- avgResponseTime: totalTime / requestCount,
822
- successRate: successCount / totalCount,
823
- estimatedMonthlyCost: estimateCost(totalTokens)
824
- };
825
-
826
- console.log('成本分析:', analytics);
827
- ```
828
-
829
- ---
830
-
831
- ## 代码示例库
832
-
833
- ### Node.js / TypeScript 基础示例
834
-
835
- ```typescript
836
- import OpenAI from "openai";
837
-
838
- const openai = new OpenAI({
839
- apiKey: process.env.OPENAI_API_KEY,
840
- });
841
-
842
- async function main() {
843
- const message = await openai.chat.completions.create({
844
- model: "gpt-4o",
845
- messages: [
846
- {
847
- role: "user",
848
- content: "What is the capital of France?",
849
- },
850
- ],
851
- });
852
-
853
- console.log(message.choices[0].message.content);
854
- }
855
-
856
- main();
857
- ```
858
-
859
- ### Python 流式示例
860
-
861
- ```python
862
- from openai import OpenAI
863
-
864
- client = OpenAI(api_key="sk-xxx")
865
-
866
- with client.chat.completions.stream(
867
- model="gpt-4o",
868
- messages=[
869
- {"role": "user", "content": "Write a poem about spring"}
870
- ],
871
- ) as stream:
872
- for text in stream.text_stream:
873
- print(text, end="", flush=True)
874
- ```
875
-
876
- ### JavaScript 函数调用示例
877
-
878
- ```javascript
879
- const OpenAI = require("openai").default;
880
-
881
- const openai = new OpenAI({ apiKey: "sk-xxx" });
882
-
883
- async function main() {
884
- const tools = [
885
- {
886
- type: "function",
887
- function: {
888
- name: "get_weather",
889
- description: "Get weather information for a location",
890
- parameters: {
891
- type: "object",
892
- properties: {
893
- location: {
894
- type: "string",
895
- description: "City name",
896
- },
897
- unit: {
898
- type: "string",
899
- enum: ["celsius", "fahrenheit"],
900
- default: "celsius",
901
- },
902
- },
903
- required: ["location"],
904
- },
905
- },
906
- },
907
- ];
908
-
909
- const messages = [
910
- { role: "user", content: "What is the weather in Paris?" },
911
- ];
912
-
913
- const response = await openai.chat.completions.create({
914
- model: "gpt-4o",
915
- messages: messages,
916
- tools: tools,
917
- tool_choice: "auto",
918
- });
919
-
920
- const toolCall = response.choices[0].message.tool_calls?.[0];
921
- if (toolCall?.function.name === "get_weather") {
922
- console.log("Function called:", toolCall.function.name);
923
- console.log("Arguments:", toolCall.function.arguments);
924
- }
925
- }
926
-
927
- main();
928
- ```
929
-
930
- ### Responses API 使用示例 - TypeScript
931
-
932
- ```typescript
933
- import OpenAI from "openai";
934
-
935
- const openai = new OpenAI({
936
- apiKey: process.env.OPENAI_API_KEY,
937
- });
938
-
939
- // 基础文本请求
940
- async function basicRequest() {
941
- const response = await openai.beta.responses.create({
942
- model: "gpt-4o",
943
- input: "Tell me a bedtime story about a unicorn."
944
- });
945
-
946
- console.log(response.output[0].content[0].text);
947
- }
948
-
949
- // 多轮对话
950
- async function multiTurnConversation() {
951
- // 第一个请求
952
- const response1 = await openai.beta.responses.create({
953
- model: "gpt-4o",
954
- input: "What is Python?"
955
- });
956
-
957
- console.log("Assistant:", response1.output[0].content[0].text);
958
-
959
- // 第二个请求,引用第一个响应
960
- const response2 = await openai.beta.responses.create({
961
- model: "gpt-4o",
962
- input: "Give me a practical example",
963
- previous_response_id: response1.id
964
- });
965
-
966
- console.log("Assistant:", response2.output[0].content[0].text);
967
- }
968
-
969
- // 使用网络搜索
970
- async function webSearch() {
971
- const response = await openai.beta.responses.create({
972
- model: "gpt-4o",
973
- input: "What is the latest news about AI?",
974
- tools: [
975
- {
976
- type: "web_search"
977
- }
978
- ]
979
- });
980
-
981
- console.log(response.output[0].content[0].text);
982
- }
983
-
984
- // 后台处理
985
- async function backgroundProcessing() {
986
- const response = await openai.beta.responses.create({
987
- model: "gpt-4o",
988
- input: "Process this large dataset",
989
- background: true,
990
- store: true
991
- });
992
-
993
- console.log("Response ID:", response.id);
994
- console.log("Status:", response.status);
995
-
996
- // 稍后获取结果
997
- await new Promise(r => setTimeout(r, 5000));
998
- const completed = await openai.beta.responses.retrieve(response.id);
999
- console.log("Completed:", completed.status);
1000
- }
1001
-
1002
- // 函数调用
1003
- async function functionCalling() {
1004
- const response = await openai.beta.responses.create({
1005
- model: "gpt-4o",
1006
- input: "What is the weather in Paris?",
1007
- tools: [
1008
- {
1009
- type: "function",
1010
- function: {
1011
- name: "get_weather",
1012
- description: "Get weather information",
1013
- parameters: {
1014
- type: "object",
1015
- properties: {
1016
- city: {
1017
- type: "string",
1018
- description: "City name"
1019
- }
1020
- },
1021
- required: ["city"]
1022
- }
1023
- }
1024
- }
1025
- ]
1026
- });
1027
-
1028
- if (response.output[0].content[0].type === "tool_use") {
1029
- console.log("Function called:", response.output[0].content[0].name);
1030
- }
1031
- }
1032
-
1033
- basicRequest();
1034
- ```
1035
-
1036
- ### Responses API 流式示例
1037
-
1038
- ```typescript
1039
- import OpenAI from "openai";
1040
-
1041
- const openai = new OpenAI({
1042
- apiKey: process.env.OPENAI_API_KEY,
1043
- });
1044
-
1045
- async function streamingResponse() {
1046
- const response = await openai.beta.responses.stream({
1047
- model: "gpt-4o",
1048
- input: "Write a poem about spring"
1049
- });
1050
-
1051
- for await (const event of response) {
1052
- if (event.type === 'response.output_item.delta') {
1053
- if (event.delta.content?.type === 'text') {
1054
- process.stdout.write(event.delta.content.text);
1055
- }
1056
- }
1057
- }
1058
- }
1059
-
1060
- streamingResponse();
1061
- ```
1062
-
1063
- ### Responses API 对话压缩
1064
-
1065
- ```typescript
1066
- // 当对话变得很长时,可以压缩以节省 token
1067
- const compacted = await openai.beta.responses.compact({
1068
- model: "gpt-5",
1069
- input: [
1070
- {
1071
- role: "user",
1072
- content: "Create a landing page"
1073
- },
1074
- {
1075
- type: "message",
1076
- role: "assistant",
1077
- content: [
1078
- {
1079
- type: "output_text",
1080
- text: "Here is a landing page..."
1081
- }
1082
- ]
1083
- }
1084
- ]
1085
- });
1086
-
1087
- console.log("Compacted response:", compacted.id);
1088
- ```