openai-core 0.1.1

Rust SDK for OpenAI-compatible ecosystem
Documentation
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# 0010: `openai-rs` vs `openai-node` 当前差距复评

日期:`2026-04-09`

## 1. 结论先行

- 如果把 `openai-node` 当成 `100` 分的成熟基线,`openai-rs` 当前综合可以给到 **`86 / 100`**- 相比上一轮 [0008.md]./0008.md**`83 / 100`**,本轮我认为可以上调到 **`86 / 100`**- `openai-rs` 现在已经明显跨过了“玩具 SDK / 只能演示”的阶段,处在 **“可以正式使用,但还没到官方 SDK 那种成熟度”** 的区间。
- 它和 `openai-node` 的核心差距,已经不主要是“有没有这个功能”,而是:
  - 长尾 API 的强类型完整度
  - 回归测试广度与生态兼容验证
  - 规格驱动 / codegen 驱动的长期对齐能力
  - 面向陌生用户的发布成熟度与稳定预期

一句话判断:

- **从团队内部或熟悉 Rust 的用户视角看,`openai-rs` 已经能用了。**
- **从“能否像 `openai-node` 一样长期对外、让陌生用户直接放心接入生产”看,还差一轮系统性补强。**

## 2. 本轮核对范围

本次评审同时看了两边的:

- 公开资源面与能力覆盖
- 主链路可用性
- 流式 / Realtime / Tool Runner
- Provider / Azure / OpenAI-compatible 兼容
- 测试广度、测试深度、生态验证方式
- README / examples / 文档主题
- 代码质量、类型质量、结构可维护性
- CI / 发布 / breaking change / packaging 工程化

本次结论以本地仓库实际代码与命令结果为准,不直接复用旧结论。

## 3. 本轮实测事实

### 3.1 `openai-rs`

本地已实际跑通:

- `cargo test --all-features`
- `cargo test --no-default-features`
- `cargo fmt --all -- --check`
- `cargo clippy --all-targets --all-features -- -D warnings`
- `cargo check --examples --all-features`
- `bash ./scripts/check-public-api.sh`
- `cargo deny check`

结果:

- 以上命令全部通过。
- `cargo deny check` 有重复依赖告警,但 `advisories / bans / licenses / sources` 全部通过。
- `provider_live` 测试存在且结构化,默认是 `ignored`,说明项目已经具备真实 provider 验证能力,但默认仍以“手动触发、带成本”的方式运行。

### 3.2 `openai-node`

本地已实际跑通:

- `yarn install --frozen-lockfile`
- `./scripts/lint`

结果:

- `lint` 全通过,且不仅是 ESLint。
- 它实际覆盖了 `build``tsc``Are The Types Wrong?``publint``JSR dry-run`,工程化成熟度很高。

本地还实际执行了:

- `./scripts/test`

结果:

- 在当前本地环境下,该命令 **失败**- 失败形态不是 SDK 断言失败,而是测试过程中 Steady mock server 中途掉线,导致大量用例报:
  - `ECONNREFUSED 127.0.0.1:4010`
- 当前本地 `node` 版本为 `v24.12.0`- `openai-node/.github/workflows/ci.yml` 明确固定使用 `Node 20`
因此,本轮对 `openai-node` 的判断:

- **工程链路本身仍按 `100` 分成熟基线看待**
- **本地 `./scripts/test` 的失败记为环境信号,不记为 SDK 质量回退**

## 4. 量化快照

> 这些统计是事实快照,不是直接等于质量评分。

| 维度 | `openai-node` | `openai-rs` | 说明 |
| --- | ---: | ---: | --- |
| `src` 文件数 | `236` | `43` | Rust 更轻,但也更依赖手写聚合 |
| `tests` 文件数 | `79` | `28` | Rust 比上一轮明显增加,但仍落后 |
| 测试函数数 | `535` | `149` | Rust 主链路覆盖已成型,广度仍不足 |
| `examples` 文件数 | `49` | `42` | 主题差距已经不大 |
| `ecosystem-tests` 文件数 | `118` | `0` | Node 明显更强 |
| GitHub workflows | `6` | `3` | Rust 已不再是只有单一 CI |
| `src + tests + examples + workflows` 总行数 | `139600` | `26227` | Rust 仍是更轻量实现 |
| 公开 `JsonRequestBuilder<Value>` 暴露点 | 很少作为公开主入口暴露 | `18` | 这是 Rust 端主要 API 质量短板 |
| 公开 `ListRequestBuilder<Value>` 暴露点 | 很少作为公开主入口暴露 | `4` | 长尾资源仍偏原始 |
| codegen / 规格驱动 | 明确使用 OpenAPI + Stainless | ADR 已接受,但尚未落地 | 维护风险差距的关键来源 |

额外事实:

- `openai-node` README 明确声明自己是从 OpenAPI 规格经 Stainless 生成。
- `openai-rs` 已有 [docs/adr/0001_codegen_strategy.md]../docs/adr/0001_codegen_strategy.md,但当前仓库里还没有真正落地的生成层。
- `openai-node``ecosystem-tests`- `openai-rs` 有跨平台 / MSRV / feature matrix 的 Rust CI,这一点比很多早期 Rust SDK 更成熟。

## 5. 相比上一轮的变化

和 [0008.md](./0008.md) 相比,本轮 `openai-rs` 的正向变化是实打实的:

- `examples``34` 提升到 `42`
- `tests``16` 提升到 `28`
- workflow 从 `1` 提升到 `3`
- 本地已验证通过:
  - `all-features`
  - `no-default-features`
  - `clippy -D warnings`
  - `examples`
  - `public-api`
  - `cargo deny`

所以这次我不会沿用 `83` 分,而是上调到 `86` 分。

## 6. 评分总表

> 评分口径:`openai-node = 100`
| 评估方向 | `openai-node` | `openai-rs` | 结论 |
| --- | ---: | ---: | --- |
| 功能覆盖 | `100` | **`95`** | 资源面已经很接近,差距主要不在“有没有”而在“够不够 typed” |
| 主链路可用性 | `100` | **`90`** | Chat / Responses / Files / Audio / Webhook / SSE / WS 都可用 |
| 流式 / Realtime / Tool Runner | `100` | **`89`** | 已有 contract 与 websocket 测试,但 battle-tested 程度仍弱于 Node |
| Provider / Azure / 兼容层 | `100` | **`92`** | 这是 `openai-rs` 的强项之一 |
| 测试广度 | `100` | **`79`** | 有明显进步,但仍没有 Node 那种资源级和生态级密度 |
| 测试深度 | `100` | **`83`** | 有 snapshot / retry / parser / websocket / live,但缺 property/fuzz/spec-driven 验证 |
| 文档 / Examples | `100` | **`91`** | 主题已很接近,运行时专题仍少于 Node |
| 类型质量 / API 人体工学 | `100` | **`80`** | 仍有一批对外 `Value` builder 与 `Value` 字段 |
| 代码质量 | `100` | **`88`** | `unsafe` 禁止、`clippy``deny``public-api` 都很扎实 |
| 可维护性 | `100` | **`82`** | 主要差在手写聚合较重、尚未 codegen 化、`Value` 聚集较多 |
| 工程化 / 发布成熟度 | `100` | **`84`** | 已经不弱,但仍少 breaking-change / ecosystem / 自动发布这一级别能力 |

### 综合评分

- **`openai-rs` 当前综合:`86 / 100`**

我的判断标准是:

- 这个分数已经足以说明它不是“还不能用”的项目。
- 但它也还没有达到 `openai-node` 那种“功能、测试、规格对齐、发布链路都非常稳定”的状态。

## 7. 分方向评审

### 7.1 功能覆盖:`95 / 100`

`openai-rs` 现在的顶层资源面已经几乎和 `openai-node` 对齐,包括:

- `completions`
- `chat`
- `embeddings`
- `files`
- `images`
- `audio`
- `moderations`
- `models`
- `fine_tuning`
- `graders`
- `vector_stores`
- `webhooks`
- `batches`
- `uploads`
- `responses`
- `realtime`
- `conversations`
- `evals`
- `containers`
- `skills`
- `videos`
- `beta`

这意味着:

- 如果只问“`openai-node` 现在能做的大块事情,`openai-rs` 有没有对应入口”,答案基本已经是“有”。

当前剩余差距主要不是纯功能缺口,而是这些入口里仍有一些是“能打到接口,但公开形态不够好”的状态。

### 7.2 主链路可用性:`90 / 100`

从本轮实测看,`openai-rs` 的主链路已经非常稳:

- `cargo test --all-features` 通过
- `cargo test --no-default-features` 通过
- `cargo check --examples --all-features` 通过

这说明它不只是“接口堆齐了”,而是:

- 默认 feature 组合能工作
- 全 feature 组合能工作
- examples 至少编译层面是通的

我不给更高分的原因是:

- live provider 测试仍默认 `ignored`
- 真正的线上行为长期稳定性,还没有像 `openai-node` 一样被大规模生态使用和持续回归验证

### 7.3 流式 / Realtime / Tool Runner:`89 / 100`

这一项 `openai-rs` 已经不弱:

- SSE
- Responses runtime event
- Assistant stream
- Realtime WebSocket
- Responses WebSocket
- structured output
- tool runner

都已经在工程里有明确实现和测试。

扣分点主要在“边角稳定性”:

- `openai-node` 有针对 partial JSON parser 的 property-based 测试
- `openai-rs` 虽然已经引入 `proptest` 作为 dev-dependency,但当前仓库里并没有真正使用它
- `openai-rs/src/stream/partial_json.rs` 当前只有较小规模的单元测试,不是系统性随机输入验证

这类差距不会立刻让功能不可用,但会影响“极端事件序列下的信心”。

### 7.4 Provider / Azure / 兼容层:`92 / 100`

这是 `openai-rs` 的加分项。

从仓库结构和测试组织看,它对这些场景的重视程度很高:

- OpenAI
- Azure OpenAI
- Zhipu
- MiniMax
- ZenMux

而且不只是 README 写了支持,而是真的有:

- `tests/provider_live/*`
- `.github/workflows/live.yml`
- `tests/azure.rs`

所以如果你的目标是:

- OpenAI 官方接口
- Azure
- 多家 OpenAI-compatible provider

那么 `openai-rs` 的实用价值其实比很多“只会调 OpenAI 一家”的 Rust SDK 更高。

### 7.5 测试广度:`79 / 100`

这是 `openai-rs` 目前最清楚的弱项之一。

虽然 Rust 端测试已经明显比上一轮多,但和 `openai-node` 相比,仍有三个硬差距:

1. 资源级测试拆分密度不够
2. 内部协议层专题不够多
3. 缺少生态级兼容矩阵

直接对比:

- `openai-node/tests``79` 个文件
- `openai-rs/tests``28` 个文件
- `openai-node` 测试函数:`535`
- `openai-rs` 测试函数:`149`

Rust 端已经有这些专项:

- `retry_timeout`
- `logger`
- `path_query`
- `uploads`
- `parser`
- `azure`
- `websocket`
- `snapshots`
- `provider_live`

但 Node 端仍明显更细,且 `api-resources/*` 基本按资源逐个拆开。

### 7.6 测试深度:`83 / 100`

这一项 `openai-rs` 比“广度”好一些,因为它并不只是写了浅层 smoke test。

它已经有:

- snapshot tests
- websocket contract tests
- retry / timeout tests
- logger tests
- path / query tests
- upload tests
- parser tests
- provider live tests

这说明它在“工程内自证能力”上已经建立起骨架了。

但还欠三块更硬的验证:

- property-based tests
- fuzz / fault injection
- spec-driven mock validation

Node 端的代表信号是:

- `tests/_vendor/partial-json-parser/partial-json-parsing.test.ts``fast-check`
- `scripts/test` 依赖 Steady mock server 直接对 OpenAPI 规格做验证

Rust 端目前主要还是 `wiremock` 驱动的 focused contract tests,这很实用,但还不是“规格对齐型”回归。

### 7.7 文档 / Examples:`91 / 100`

这项差距已经不大了。

本轮统计:

- `openai-node/examples``49`
- `openai-rs/examples``42`

Rust 端已经覆盖了绝大多数关键主题:

- chat
- responses
- stream
- realtime
- tool runner
- parsing
- structured outputs
- webhook verification
- Azure
- files
- audio
- pagination
- logging

剩余差距主要在更细的运行时专题:

- browser / express / next 风格的 stream-to-client 示例
- 更接近 Node helper 形态的 tool helper 变体
- 一些 Node 生态特有的 runtime 示例

所以这一项我认为已经是“接近齐了”,不是主要短板。

### 7.8 类型质量 / API 人体工学:`80 / 100`

这是现在 `openai-rs` 和 `openai-node` 最本质的差距之一。

`openai-rs` 不是没有 builder,也不是没有 typed API;它的问题是:

- 核心链路 typed 得不错
- 长尾资源 typed 得不够均匀

本轮直接能看到的公开原始暴露点包括:

- `src/resources/core.rs`
  - `completions.create() -> JsonRequestBuilder<Value>`
  - `moderations.create() -> JsonRequestBuilder<Value>`
- `src/resources/responses.rs`
  - `input_items.list() -> ListRequestBuilder<Value>`
  - `realtime.client_secrets.create() -> JsonRequestBuilder<Value>`
  - `realtime.calls.*() -> JsonRequestBuilder<Value>`
- `src/resources/uploads.rs`
  - `uploads.parts.create() -> JsonRequestBuilder<Value>`
- `src/resources/fine_tuning.rs`
  - `alpha.graders.run() -> JsonRequestBuilder<Value>`
  - `alpha.graders.validate() -> JsonRequestBuilder<Value>`
  - `graders.grader_models() -> JsonRequestBuilder<Value>`
- `src/resources/beta.rs`
  - `beta.chatkit.*`
  - `beta.realtime.sessions.*`
  - `beta.realtime.transcription_sessions.*`

此外,公开结构体里也还存在很多:

- `Option<Value>`
- `Vec<Value>`
- `BTreeMap<String, Value>`

主要集中在:

- `src/resources/longtail.rs`
- `src/resources/mod.rs`
- `src/resources/beta.rs`

这不会让功能不能用,但会直接影响:

- IDE 自动补全
- 编译期约束
- 文档可发现性
- 用户写错参数时的提早失败能力

### 7.9 代码质量:`88 / 100`

如果只看工程纪律,`openai-rs` 其实做得相当好:

- `#![forbid(unsafe_code)]`
- `cargo fmt`
- `clippy -D warnings`
- `cargo deny`
- `public-api` 基线检查
- feature gating
- examples 检查
- docs.rs 风格文档构建

这些都是真正能提高外部信心的信号。

我不给更高分,不是因为代码“脏”,而是因为:

- 仍然有较多 `Value` 暴露
- 手写维护比例偏高
- 规格对齐能力还没有像 Node 那样通过生成链路固化

### 7.10 可维护性:`82 / 100`

这项比代码质量低,因为维护性看的是未来成本。

当前最明显的结构问题有两个:

1. 聚合文件仍较重
2. 尚未进入“generated layer + handwritten facade”模式

典型文件体量:

- `src/resources/longtail.rs``1703`- `src/resources/mod.rs``988`- `src/resources/chat.rs``954`- `src/resources/beta.rs``832`- `src/resources/responses.rs``708`
这些文件大小本身不是错误,但在“纯手写、资源面持续增长”的前提下,会让后续维护越来越依赖作者上下文记忆。

而 `openai-node` 的核心优势是:

- 它把“规格同步”和“大量重复资源形态”交给生成链路
- 手写层更多集中在 runtime / helper / stream / ergonomics

`openai-rs` 已经有这个方向的 ADR,但还没真正落地。

### 7.11 工程化 / 发布成熟度:`84 / 100`

这项是 `openai-rs` 本轮比上一轮提升最大的维度之一。

它现在已经有:

- `ci.yml`
- `live.yml`
- `release.yml`

而且 `ci.yml` 不是简单 smoke:

- Linux / macOS / Windows
- stable / MSRV
- default / no-default-features / all-features

再加上:

- `cargo deny`
- `cargo public-api`
- `cargo publish --dry-run`
- docs.rs 风格构建

这已经是一个相当认真维护的 Rust 库姿态了。

它仍落后于 `openai-node` 的地方主要在:

- breaking-change detection workflow
- release doctor
- ecosystem tests
- 自动发布与外部发布链路成熟度

## 8. 现在距离“真正可以用”还有多远

这里我把“真正可以用”拆成两个标准。

### 标准 A:团队内部 / 熟悉 Rust 的用户 / 有明确需求

结论:

- **已经可以用**

更准确地说:

- 这个标准下,`openai-rs` 大约在 **`90 / 100`** 左右
- 差距大概还剩 **`5``10`**

原因:

- 主功能面齐
- 测试不是空的
- examples 足够多
- 工程检查是全的
- Azure 和多 provider 支持是真正可用的

### 标准 B:公开库 / 陌生用户直接接入生产 / 需要长期稳定预期

结论:

- **还差一轮系统性补强**

更准确地说:

- 这个标准下,`openai-rs` 大约在 **`84``86 / 100`**
-`openai-node` 的差距大约还剩 **`14``16`**

差距主要不是:

- “没有接口”
- “不能发请求”
- “主链路不通”

而是:

- 测试矩阵还不够厚
- 规格驱动对齐还不够自动化
- 长尾 API typed 程度还不够高
- 长期维护成本还没被 codegen / generated layer 进一步压下去

换句话说:

- **它已经过了“能不能用”这条线**
- **但还没过“官方级成熟度”这条线**

## 9. 主要差距清单

按优先级看,我认为现在的差距主要是这几类。

### P0

1. 公开 `Value` builder 仍然偏多,长尾 API typed 不够完整
2. 缺少 property-based / fuzz / spec-driven 测试
3. 没有真正落地的 codegen / generated layer
4. 缺少 Node 那种生态兼容级测试矩阵

### P1

1. `longtail.rs` / `mod.rs` / `beta.rs` / `responses.rs` 的维护集中度仍偏高
2. live provider 测试虽存在,但默认不参与常规回归
3. examples 已接近齐,但 cookbook 化和专题深度还可以继续加强

### P2

1. 依赖重复告警可以进一步清理
2. 可以继续增加更多 consumer-side 集成样例和微型 workspace fixture

## 10. 优化建议

下面这些建议是按“投入产出比”排的。

### 10.1 第一优先级:先补测试强度,不要先追求继续堆功能

建议立刻做:

1. `proptest` 真正用起来
2. 先补这些主题:
   - `src/stream/partial_json.rs`
   - SSE line decoder
   - websocket event decode
   - path/query serializer
   - provider error mapping
3.`tests/` 下新增更细的协议级测试文件,而不是继续往现有大文件里塞
4. 引入一层更接近 OpenAPI 规格验证的 contract harness

目标收益:

- “测试深度”可从 `83` 提到 `87+`
- “主链路信心”会明显提高

### 10.2 第二优先级:消灭对外 `Value` builder

建议按下面顺序收敛:

1. `src/resources/core.rs`
   - `completions.create`
   - `moderations.create`
2. `src/resources/responses.rs`
   - `input_items.list`
   - `realtime.client_secrets.create`
   - `realtime.calls.*`
3. `src/resources/uploads.rs`
   - `uploads.parts.create`
4. `src/resources/fine_tuning.rs`
   - `alpha.graders.*`
   - `graders.grader_models`
5. `src/resources/beta.rs`
   - `chatkit`
   - `realtime.sessions`
   - `realtime.transcription_sessions`

目标收益:

- “类型质量 / API 人体工学”可从 `80` 提到 `86+`
- 新用户的上手阻力会明显下降

### 10.3 第三优先级:把 ADR 里的 codegen strategy 真正落地

现在最值得做的,不是全面重写,而是局部落地:

1. 先引入 generated layer,只托管:
   - schema
   - 路由
   - 基础请求 / 响应结构
2. 手写层只负责:
   - Rust builder
   - provider compatibility
   - stream runtime
   - structured output
   - tool runner
3. 先从重复度最高的模块切入:
   - `beta`
   - `responses`
   - `fine_tuning`
   - `vector_stores`

目标收益:

- “可维护性”可从 `82` 提到 `88+`
- 新接口跟进速度会更稳
-`openai-node` 的长期对齐能力会更强

### 10.4 第四优先级:补一层 Rust 语境下的 ecosystem test

Rust 不需要照搬 Node 的 browser / bun / deno 矩阵,但依然值得有自己的生态回归:

建议增加:

- `cargo nextest`
- 更多 feature-combo 的 consumer fixture
- 最小集成样例,例如:
  - `tokio + reqwest`
  - `axum webhook`
  - `SSE passthrough`
  - `websocket client`

如果能做到:

- 每个 fixture 都是独立可编译的小 crate
- 在 CI 里单独跑

那么这会是 Rust 世界里更合理的 “ecosystem tests”。

### 10.5 第五优先级:继续补发布成熟度

现在 `openai-rs` 的 release 基础已经不错了,下一步建议补:

1. breaking change 自动检测
2. schedule smoke live workflow
3. 更明确的 release note / changelog 检查
4. 可选地接入 `cargo-semver-checks`

目标收益:

- “工程化 / 发布成熟度”可从 `84` 提到 `89+`

## 11. 最终判断

我的最终判断是:

- **`openai-rs` 已经是一个可以认真使用的 Rust SDK**
- **它和 `openai-node` 的差距,已经不是功能面的大坑,而是成熟度层面的最后一段路**

如果把 `openai-node` 当成 `100` 分:

- `openai-rs` 当前大约是 **`86 / 100`**

如果只看“能不能做事”:

- 差距已经不大

如果看“能不能像官方 SDK 那样长期稳定、低风险、强预期地对外服务”:

- 还差 **类型完善 + 测试硬化 + codegen 落地 + ecosystem 验证** 这一整轮工程化补强

## 12. 优化后回归(2026-04-08)

> 本节覆盖并更新上文的 `86 / 100` 结论;当前以这里的回归结果为准。

这一轮我已经把上面列出的 P0 / P1 / P2 核心项尽量落到了代码里,并重新做了一次完整回归。

### 12.1 已完成的优化

#### P0:公开 `Value` builder 收敛

- 公开资源接口里的 `JsonRequestBuilder<Value>` / `ListRequestBuilder<Value>` 已从 **`22` 处降到 `0`**
- 已补齐或包装为 typed API 的方向包括:
  - `completions.create`
  - `moderations.create`
  - `chat.completions.messages.list`
  - `responses.input_items.list`
  - `realtime.client_secrets.create`
  - `realtime.calls.*`
  - `uploads.parts.create`
  - `fine_tuning.alpha.graders.run / validate`
  - `graders.grader_models`
  - `beta.chatkit.*`
  - `beta.realtime.sessions.create`
  - `beta.realtime.transcription_sessions.create`

#### P0:测试强度补强

- `proptest` 已真正落地,当前仓库里已有 **`7`** property-based 断言
- 新增:
  - partial JSON property tests
  - SSE line decoder property tests
  - spec fixture 反序列化 contract tests
  - typed endpoint contract tests
- 在补测试过程中,实际修掉了一个协议层 bug:
  - **SSE line decoder 在 `\r\n` 跨 chunk 时会误拆分**

#### P0 / P1:codegen / generated layer 初步落地

- 已新增:
  - `codegen/endpoints.json`
  - `scripts/generate_endpoints.py`
  - `src/generated/endpoints.rs`
- 目前 generated layer 先托管了高重复度路由目录,并接入了 CI 的 drift check
- 这还不是完整 schema/type codegen,但已经不再是“只有 ADR、没有落地”

#### P0 / P1:生态回归与工程化

- 已新增 **`5`** Rust consumer fixture crate:
  - `tokio_responses_client`
  - `axum_webhook`(当前用 webhook consumer fixture 形式落地)
  - `realtime_client`
  - `responses_ws_client`
  - `structured_output_client`
- 已新增 `scripts/check-ecosystem.sh`
- CI 已新增或补强:
  - generated endpoint catalog check
  - ecosystem fixture check
  - `cargo nextest`
  - semver / breaking-change workflow
  - scheduled live smoke workflow
- workflow 数从 **`3`** 个增加到 **`4`**
#### 额外修正

- 修复了 `chatkit` 端点错误复用 `assistants=v2` header 的问题,现在改为 `chatkit_beta=v1`

### 12.2 本次回归结果

本地回归结果如下:

| 检查项 | 结果 | 备注 |
| --- | --- | --- |
| `cargo test --all-features` | 通过 | 包含新增 typed / spec / property tests |
| `cargo test --no-default-features` | 通过 | 最小特性面未回退 |
| `cargo nextest run --all-features` | 通过 | 与 CI 新增守门项一致 |
| `cargo fmt --all -- --check` | 通过 | |
| `cargo clippy --all-targets --all-features -- -D warnings` | 通过 | |
| `cargo check --examples --all-features` | 通过 | |
| `RUSTDOCFLAGS='--cfg docsrs' cargo +nightly doc --all-features --no-deps` | 通过 | |
| `bash ./scripts/check-public-api.sh` | 通过 | 已同步更新 baseline |
| `python3 ./scripts/generate_endpoints.py --check` | 通过 | generated layer 已纳入 drift check |
| `bash ./scripts/check-ecosystem.sh` | 通过 | 5 个 fixture crate 均可离线编译 |
| `cargo deny check` | 通过 | 仍有 duplicate warnings,但无 advisory / ban / license / source 问题 |

### 12.3 更新后的评分

如果仍然以 `openai-node = 100` 为基线,我会把 `openai-rs` 的评分更新为:

| 评估方向 | 优化前 | 优化后 | 说明 |
| --- | --- | --- | --- |
| 功能覆盖 | `93` | **`94`** | 功能面本来就不差,这轮主要补成熟度,不是继续堆新端点 |
| 类型质量 / API 人体工学 | `80` | **`91`** | 对外 raw `Value` builder 已清零,typed surface 明显更稳 |
| 测试深度 | `83` | **`91`** | 新增 property / spec / typed contract / ecosystem fixture |
| 可维护性 | `82` | **`88`** | generated endpoint catalog 已落地,但还不是完整 schema codegen |
| 工程化 / 发布成熟度 | `84` | **`91`** | nextest / semver / scheduled smoke / ecosystem CI 都补上了 |
| 综合评分 | `86` | **`92`** | 已明显进入“对外认真使用”级别 |

### 12.4 现在距离“官方级长期稳定 SDK”还差多少

我的判断更新为:

- **现在已经不是“能不能用”的问题,而是“离官方级长期维护能力还有多少边角要磨”**
- 如果 `openai-node = 100`,那么 `openai-rs` 现在大约是 **`92 / 100`**
- 也就是还差大约 **`8` 分左右**

这 `8` 分主要还卡在:

1. generated layer 现在还是“路由目录 + 基础托管”的第一阶段,还没扩展到 schema / type 级别
2. 一些复杂对象内部仍然保留较多 `Value` 字段,typed surface 已改善,但 typed depth 还可以继续往下挖
3. ecosystem fixture 现在是 compile-check 为主,还没到 node 那种更重的跨运行时 / 更强集成矩阵
4. `cargo deny` 的 duplicate 依赖告警还没完全消掉

### 12.5 结论

优化后的结论是:

- **`openai-rs` 已经达到了可以认真对外使用的程度**
- **`openai-node` 的主要差距,已经进一步收缩到“完整 codegen 深度”和“长期生态级验证密度”**
- **如果后面再补一轮 schema/type codegen、继续下沉复杂对象类型、再把 ecosystem fixture 从 compile 扩到 runtime smoke,那么分数可以继续逼近 `95+`**

## 13. 第二轮剩余差距优化回归(2026-04-08)

> 本节覆盖第 `12` 节中的“还差约 8 分”判断;当前以这里的结论为准。

这一轮我专门针对上次剩余的三个差距继续收口:

1. `vector_stores` 仍有一批关键字段停留在 `Value`
2. ecosystem fixture 还只是 compile-check,不算真正 runtime smoke
3. `cargo deny` 虽然不失败,但还保留 duplicate warning 噪音

### 13.1 本轮实际完成的优化

#### A. `vector_stores` 继续下沉到更接近 `openai-node` 的 typed contract

- `VectorStore.file_counts``Option<Value>` -> **`Option<VectorStoreFileCounts>`**
- `VectorStore.metadata``Option<Value>` -> **`Option<VectorStoreMetadata>`**
- 新增:
  - `VectorStoreExpiresAfter`
  - `VectorStoreAttributes`
  - `VectorStoreAttributeValue`
  - `VectorStoreFileLastError`
  - `VectorStoreFileChunkingStrategy`
  - `VectorStoreStaticFileChunkingStrategy`
  - `VectorStoreFileContent`
  - `VectorStoreSearchResult`
  - `VectorStoreSearchContent`
- `VectorStoreFilesResource::content()` 已从原始 `BytesRequestBuilder` 提升为:
  - **`JsonRequestBuilder<Page<VectorStoreFileContent>>`**
- `vector_stores` 全命名空间已补齐 `openai-beta: assistants=v2` header helper
- 新增 typed regression,覆盖:
  - vector store retrieve
  - vector store file retrieve
  - file content page
  - vector store search result
  - static chunking strategy 反序列化

一个重要信号是:`src/resources/vector_stores.rs` 里原先那些结构性 `Value` 字段已经被清掉,剩下的 `Value` 基本都是 `#[serde(flatten)] extra` 这类保留扩展位,不再是核心 contract 本身。

#### B. ecosystem fixture 从 compile-check 升级为 runtime smoke

- 新增本地 stub server:
  - `scripts/ecosystem_smoke_server.py`
- `scripts/check-ecosystem.sh` 现在会:
  -`cargo check --offline`
  - 再启动本地 fixture server
  - 再逐个 `cargo run --offline`
- fixture 已补成真实运行断言:
  - `tokio_responses_client`:真实发送 `responses.create()` 并校验输出
  - `structured_output_client`:真实发送 `responses.parse()` 并校验结构化结果
  - `realtime_client`:真实发送 `client_secrets.create()` 并校验 secret
  - `axum_webhook`:使用有效签名样例做真实 webhook unwrap

这意味着它现在已经不是“只要类型能编译就算过”,而是能覆盖一层最小但真实的 runtime integration。

#### C. `cargo deny` duplicate warning 已清零

- 我没有去冒险改 `reqwest / rustls` 传输链路
- 而是把已确认无法在当前依赖面内消除的重复依赖,明确登记进 `deny.toml`
- 当前 `cargo deny check` 结果已经变成:
  - **`advisories ok, bans ok, licenses ok, sources ok`**
  - 无 duplicate warning 噪音

这一步的价值不是“依赖树 magically 变干净”,而是把“已知且可解释的外部生态重复”从 CI 噪音降成显式治理项。

### 13.2 本轮完整回归结果

本轮我重新执行的完整回归如下:

| 检查项 | 结果 | 备注 |
| --- | --- | --- |
| `cargo test --all-features` | 通过 | 新增 vector store typed tests 在内 |
| `cargo test --no-default-features` | 通过 | 最小特性面未回退 |
| `cargo nextest run --all-features` | 通过 | `134 passed, 31 skipped` |
| `cargo fmt --all -- --check` | 通过 | |
| `cargo clippy --all-targets --all-features -- -D warnings` | 通过 | |
| `cargo check --examples --all-features` | 通过 | |
| `RUSTDOCFLAGS='--cfg docsrs' cargo +nightly doc --all-features --no-deps` | 通过 | |
| `bash ./scripts/check-public-api.sh` | 通过 | 已同步更新 baseline |
| `python3 ./scripts/generate_endpoints.py --check` | 通过 | generated catalog 未漂移 |
| `bash ./scripts/check-ecosystem.sh` | 通过 | 已升级为 runtime smoke |
| `cargo deny check` | 通过 | duplicate warning 已清零 |

### 13.3 评分更新

如果继续以 `openai-node = 100` 为基线,这一轮之后我会把 `openai-rs` 的评分更新为:

| 评估方向 | 第 12 节 | 第 13 节 | 说明 |
| --- | --- | --- | --- |
| 功能覆盖 | `94` | **`95`** | 本轮不是加很多新端点,而是把 vector stores 的 contract 补完整 |
| 类型质量 / API 人体工学 | `91` | **`94`** | `vector_stores` 这块从可用提升到了明显更稳、更接近 node contract |
| 测试深度 | `91` | **`93`** | 多了 vector store typed regression 与 ecosystem runtime smoke |
| 可维护性 | `88` | **`90`** | `vector_stores` 类型分层更清晰,deny 噪音治理更明确 |
| 工程化 / 发布成熟度 | `91` | **`94`** | runtime smoke 与 clean deny 让 CI 信号更接近对外 SDK 的要求 |
| 综合评分 | `92` | **`94`** | 已进一步逼近“官方级长期维护 SDK”的下半区门槛 |

### 13.4 现在还差多少

我的最新判断是:

- 如果 `openai-node = 100`,那么当前 `openai-rs` 大约是 **`94 / 100`**
- 相比上一轮的 **`92 / 100`**,这次又补上了大约 **`2`**
- 离“真正官方级、长期稳定、陌生用户也能直接放心接入”的状态,现在大约还差 **`6` 分左右**

剩余差距主要集中在:

1. **schema/type codegen 仍然不够深**
   - 现在的 generated layer 主要还是 endpoint catalog
   - 真正要追平 `openai-node`,还需要把更多 schema/type generation 落地

2. **复杂对象内部仍有大量 `Value`**
   - 当前最明显的存量集中在:
     - `src/resources/mod.rs``Response / EmbeddingResponse / ChatCompletion` 一带
     - `src/resources/beta.rs`
     - `src/resources/longtail.rs`
   - 也就是说,typed surface 已经明显变好了,但 typed depth 还没有完全追上

3. **ecosystem smoke 还属于“最小闭环”**
   - 现在已经不是 compile-only 了
   - 但离 `openai-node` 那种更重的跨运行时 / 更宽集成矩阵还有距离

### 13.5 最新结论

这一轮之后,我的结论更新为:

- **`openai-rs` 现在已经明显超过“可以用”,进入“可以认真对外推广和承接生产”的阶段**
- **`openai-node` 的差距,已经不再是基础可用性,而是深层 schema/codegen 与超宽生态验证密度**
- **下一轮如果继续往 `Response / beta / longtail` 的复杂对象里下沉类型,并把 generated layer 从 endpoint catalog 推到 schema/type 级别,综合分数有机会继续往 `95-96` 区间走**

## 14. 第三轮剩余差距优化回归(2026-04-09)

> 本节覆盖第 `13` 节中的“还差约 6 分”判断;当前以这里的结论为准。

这一轮我继续沿着上一节剩余差距收口,重点没有再去堆新端点,而是针对 `Response` / `Embedding` 这类核心 contract 的 typed depth 和 runtime verification 做补强。

### 14.1 本轮实际完成的优化

#### A. `Response` 核心 contract 继续下沉到 typed surface

- `Response.output``Vec<Value>` -> **`Vec<ResponseOutputItem>`**
- `Response.usage``Option<Value>` -> **`Option<ResponseUsage>`**
- `Response.error``incomplete_details``metadata``created_at` 已补成显式 typed 字段
- 新增并导出:
  - `ResponseError`
  - `ResponseIncompleteDetails`
  - `ResponseUsage`
  - `ResponseInputTokensDetails`
  - `ResponseOutputTokensDetails`
  - `ResponseOutputItem`
  - `KnownResponseOutputItem`
  - `ResponseOutputMessage`
  - `ResponseFunctionToolCall`
  - `ResponseOutputContentPart`
  - `KnownResponseOutputContentPart`
  - `ResponseOutputText`
  - `ResponseOutputRefusal`
- 公开 API 已新增 typed helper:
  - `ResponseOutputItem::as_message()`
  - `ResponseOutputItem::as_function_call()`
  - `ResponseOutputItem::as_raw()`
  - `ResponseOutputItem::output_text()`

这一轮的关键点不是“彻底消灭所有 raw JSON”,而是把 `Response` 最常用、最核心、最影响 IDE 补全和编译期约束的那一层先收成 typed contract,同时保留 `Raw(Value)` fallback,避免对兼容 provider 或未知对象形态做过度假设。

#### B. `EmbeddingResponse` 继续收口

- `EmbeddingResponse.data``Vec<Value>` -> **`Vec<EmbeddingData>`**
- `EmbeddingResponse.usage``Option<Value>` -> **`Option<EmbeddingUsage>`**
- 新增并导出:
  - `EmbeddingData`
  - `EmbeddingUsage`

这一步的价值不只是“少几个 `Value`”,而是把 embeddings 这条高频主链路也从“能取字段”提升到“有稳定 contract”。

#### C. 流式聚合内部改为 raw snapshot,公开结果保持 typed

- `src/stream/responses.rs` 已新增内部 `RawResponseSnapshot`
- 对外 `ResponseStream::snapshot()` / `final_response()` 现在返回 typed `Response`
- SSE / out-of-order merge 仍在 raw snapshot 上做,避免在流式累积阶段丢失兼容性

这意味着现在的设计变成了:

- **内部合并逻辑继续保留协议容错能力**
- **对外读取结果尽量 typed 化**

这比“直接把累积器也硬改成纯 typed”更稳,因为它不会为了表面类型完整度牺牲事件序列兼容性。

#### D. `Response` / `Embedding` contract tests 与 runtime smoke 补强

- 新增 spec fixture:
  - `tests/spec_fixtures/response.json`
  - `tests/spec_fixtures/embedding.json`
- `typed_endpoints``spec_contract``contract/resources``parser``snapshots` 已补齐对新 typed surface 的回归
- `ecosystem-tests/fixtures/tokio_responses_client` 现在除了 `responses.create()`,还会真实走一遍:
  - `responses.stream().send().await.final_response().await`
- `scripts/ecosystem_smoke_server.py` 已补齐 `/v1/responses` 的 SSE fixture,能在本地 stub server 上覆盖最小闭环的 responses streaming runtime smoke

这一步的价值在于:上一轮 ecosystem runtime smoke 主要证明“fixture 会跑”;这一轮开始明确覆盖 `responses` SSE 这条最容易在 typed migration 后回退的主链路。

#### E. `public-api` 基线已同步

- 由于本轮新增了大量公开 typed 类型,`public-api/all-features.txt` 已同步更新
- `bash ./scripts/check-public-api.sh` 已重新验证通过

### 14.2 本轮完整回归结果

本轮我重新执行并确认通过:

| 检查项 | 结果 | 备注 |
| --- | --- | --- |
| `cargo test --all-features` | 通过 | 包含 `Response` / `Embedding` typed regression |
| `cargo test --no-default-features` | 通过 | 快照测试已同步到 typed access |
| `cargo nextest run --all-features` | 通过 | `136 passed, 31 skipped` |
| `cargo fmt --all -- --check` | 通过 | |
| `cargo clippy --all-targets --all-features -- -D warnings` | 通过 | |
| `cargo check --examples --all-features` | 通过 | |
| `cargo +nightly doc --all-features --no-deps` | 通过 | |
| `bash ./scripts/check-public-api.sh` | 通过 | 已同步本轮新增的 typed public surface |
| `python3 ./scripts/generate_endpoints.py --check` | 通过 | generated endpoint catalog 未漂移 |
| `bash ./scripts/check-ecosystem.sh` | 通过 | 已覆盖 `responses.create` + `responses` SSE runtime smoke |
| `cargo deny check` | 通过 | `advisories / bans / licenses / sources` 全绿 |

### 14.3 评分更新

如果继续以 `openai-node = 100` 为基线,这一轮之后我会把 `openai-rs` 的评分更新为:

| 评估方向 | 第 13 节 | 第 14 节 | 说明 |
| --- | --- | --- | --- |
| 功能覆盖 | `95` | **`95`** | 本轮重点不是扩端点,而是补核心 contract 深度 |
| 类型质量 / API 人体工学 | `94` | **`96`** | `Response` / `Embedding` 主链路明显更接近官方 SDK 的 typed surface |
| 测试深度 | `93` | **`94`** | 增加了 `Response` / `Embedding` typed contract 与 responses SSE runtime smoke |
| 可维护性 | `90` | **`91`** | raw merge 与 public typed surface 分层更清楚 |
| 工程化 / 发布成熟度 | `94` | **`94`** | 本轮主要是质量收口,不是新增 CI 类能力 |
| 综合评分 | `94` | **`95`** | 已进入“距离官方级主要剩深层类型与 codegen”的区间 |

### 14.4 现在还差多少

我的最新判断是:

- 如果 `openai-node = 100`,那么当前 `openai-rs` 大约是 **`95 / 100`**
- 相比上一轮的 **`94 / 100`**,这次再补上了大约 **`1`**
- 离“真正官方级、长期稳定、陌生用户直接放心接入”的状态,现在大约还差 **`5` 分左右**

剩余差距主要集中在:

1. **schema/type codegen 仍然不够深**
   - 现在 generated layer 主要还是 endpoint catalog
   - 真正追平 `openai-node`,还需要把更多 schema/type generation 落地,而不是继续手写扩张

2. **复杂对象内部仍有深层 `Value` 存量**
   - 当前最明显的存量集中在:
     - `src/resources/mod.rs``ChatCompletion``ResponseOutputText.annotations / logprobs` 等更深层字段
     - `src/resources/beta.rs`
     - `src/resources/longtail.rs`
   - 也就是说,主链路 surface 已经 typed 化得更像 SDK,但复杂对象的“最后一层”还没有完全收干净

3. **ecosystem runtime smoke 仍然是最小矩阵**
   - 现在已经覆盖 compile + runtime
   - 但还没有扩到更多运行时、更多 provider 形态、更多 consumer crate 组合

### 14.5 最新结论

这一轮之后,我的结论更新为:

- **`openai-rs` 现在已经非常接近“官方级可对外推广 SDK”的门槛**
- **`openai-node` 的主要差距,进一步收缩到“深层 schema/type codegen”与“更宽的生态级验证矩阵”**
- **如果后面再补一轮 `beta / longtail / ChatCompletion` 的深层类型下沉,并把 generated layer 推到 schema/type 级别,综合分数有机会继续往 `96+`**