mingpan 0.1.0__tar.gz
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.
- mingpan-0.1.0/PKG-INFO +190 -0
- mingpan-0.1.0/README.md +169 -0
- mingpan-0.1.0/mingpan/__init__.py +65 -0
- mingpan-0.1.0/mingpan/client.py +293 -0
- mingpan-0.1.0/mingpan/errors.py +99 -0
- mingpan-0.1.0/mingpan/py.typed +0 -0
- mingpan-0.1.0/mingpan/questions.py +73 -0
- mingpan-0.1.0/mingpan/types.py +222 -0
- mingpan-0.1.0/mingpan.egg-info/PKG-INFO +190 -0
- mingpan-0.1.0/mingpan.egg-info/SOURCES.txt +13 -0
- mingpan-0.1.0/mingpan.egg-info/dependency_links.txt +1 -0
- mingpan-0.1.0/mingpan.egg-info/top_level.txt +1 -0
- mingpan-0.1.0/pyproject.toml +40 -0
- mingpan-0.1.0/setup.cfg +4 -0
- mingpan-0.1.0/tests/test_sdk.py +325 -0
mingpan-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mingpan
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 明判(MingPan)Python SDK —— 三原语判断接口的类型安全客户端
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://mingpan.oneapis.cn
|
|
7
|
+
Project-URL: Documentation, https://mingpan.oneapis.cn/docs
|
|
8
|
+
Keywords: mingpan,jev,judge,llm,type-safe,routing
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# 明判 Python SDK
|
|
23
|
+
|
|
24
|
+
明判(MingPan)三原语判断接口的 Python 客户端。**运行时零依赖**(只用标准库 `urllib`),
|
|
25
|
+
`pip install` 后即可调用,不引入任何版本冲突。
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install mingpan
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**零运行时依赖** —— 装完不会引入任何第三方包(只用标准库 `urllib`)。
|
|
32
|
+
需要跟仓库里最新未发版的改动时,从源码目录装:`pip install ./sdk/python`。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 快速开始
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from mingpan import Client, choice, score, noul
|
|
40
|
+
|
|
41
|
+
client = Client(api_key="sk-xxx") # 控制台「API Key」页创建
|
|
42
|
+
|
|
43
|
+
result = client.judge(
|
|
44
|
+
state="工单:客户反映发票抬头开错,要求尽快重开,语气着急。",
|
|
45
|
+
questions={
|
|
46
|
+
"intent": choice({"售后": "退换货、维修", "物流": "发货与配送", "计费": "账单与退款"}),
|
|
47
|
+
"urgency": score(["平静", "略不满", "明显不满", "情绪激烈", "准备投诉"]),
|
|
48
|
+
"is_vip": noul("该用户是 VIP 客户"),
|
|
49
|
+
},
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
result.choice("intent").choice # '计费' —— str,不是 dict 里捞出来的
|
|
53
|
+
result.score("urgency").score # 1.5 —— float,0-based 加权
|
|
54
|
+
result.noul("is_vip").is_true(0.6) # False
|
|
55
|
+
result.usage.input_tokens # 391 —— 计费依据
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 三个原语
|
|
59
|
+
|
|
60
|
+
| 原语 | 构造 | 返回 | 说明 |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| `choice` | `choice({"标签": "说明"})` | `choice`(str) / `confidence` / `probabilities` | 从候选中选唯一答案。**`criteria` 是对象**,1–255 项 |
|
|
63
|
+
| `score` | `score(["低", "中", "高"])` | `score`(float) / `confidence` / `probabilities` / `legend` | 放到有序量级上打分。**`criteria` 是数组**,2–10 级,从低到高 |
|
|
64
|
+
| `noul` | `noul("命题正文")` | `noul`(float 0–1) | 判断命题是否成立。**没有 `confidence`** |
|
|
65
|
+
|
|
66
|
+
几个必须知道的事实:
|
|
67
|
+
|
|
68
|
+
- **`score` 是 0-based 浮点**。`score=1.5` 表示重心落在第 2 级(序号 1)附近 ——
|
|
69
|
+
不是「1.5 分 / 满分 5 分」。别拿它当整数用。
|
|
70
|
+
- **`noul` 没有 `confidence`**。SDK 如实不提供该属性:读它会 `AttributeError`,
|
|
71
|
+
而不是悄悄给个 `0.0` 让你的路由代码走错分支。
|
|
72
|
+
- **`criteria` 的说明会进模型**。`{"计费": "账单与退款"}` 的判定质量明显高于
|
|
73
|
+
`["计费"]`。只给标签时模型只能靠字面猜;说明才是准确率的来源。
|
|
74
|
+
- **只有 `input_tokens` 计费**。`output_tokens` 会返回(实测 58–67,不是 0),
|
|
75
|
+
但不在计费式里。
|
|
76
|
+
|
|
77
|
+
## 类型安全
|
|
78
|
+
|
|
79
|
+
`answers` 与 `questions` 同构,但 SDK 会按原语类型**派发成不同的类**,
|
|
80
|
+
取值器对类型不符直接报错:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
result.noul("is_vip") # NoulAnswer
|
|
84
|
+
result.choice("is_vip") # ✗ TypeMismatchError: 实际类型是 noul,不能用 result.choice() 取值
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
这比「字典下标 + `.get()`」安全得多:类型错了在**调用点**就炸,
|
|
88
|
+
而不是在几十行之外的 `NoneType has no attribute` 处炸。
|
|
89
|
+
|
|
90
|
+
## 错误处理
|
|
91
|
+
|
|
92
|
+
每类失败对应一个可分别捕获的类型:
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from mingpan import (
|
|
96
|
+
AuthenticationError, InvalidRequestError,
|
|
97
|
+
RateLimitError, ServiceUnavailableError, TransportError,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
result = client.judge(state=state, questions=questions)
|
|
102
|
+
except AuthenticationError: # 401/403:Key 无效、过期、无权。重试无意义
|
|
103
|
+
rotate_key()
|
|
104
|
+
except InvalidRequestError as e: # 400/422:参数不符。message 通常直接给出正确写法
|
|
105
|
+
print(e.message) # → "Choice criteria must contain between 1 and 255 options"
|
|
106
|
+
except RateLimitError: # 429:退避重试,或改用 judge_batch 降低并发
|
|
107
|
+
backoff()
|
|
108
|
+
except ServiceUnavailableError: # 5xx:不计费,可退避重试
|
|
109
|
+
backoff()
|
|
110
|
+
except TransportError: # 网络层:连不上/DNS/超时,检查网络或代理
|
|
111
|
+
pass
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`InvalidRequestError` 的 message 是最有价值的错误信息 ——
|
|
115
|
+
上游的校验错误会直接说出**正确字段名与取值范围**,照着改即可,不必翻文档。
|
|
116
|
+
|
|
117
|
+
## 并发与批量
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# 单次异步(不阻塞事件循环)
|
|
121
|
+
result = await client.judge_async(state=state, questions=questions)
|
|
122
|
+
|
|
123
|
+
# 多个 state 共享同一套 questions,并发发送,结果按下标对应
|
|
124
|
+
results = client.judge_batch(
|
|
125
|
+
states=[t1, t2, t3],
|
|
126
|
+
questions=questions,
|
|
127
|
+
max_workers=8, # 别调太高:先撞上游限流,换来一批 429
|
|
128
|
+
return_exceptions=True, # 单条失败作为异常对象返回,不中断整批
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 把 confidence 接进你的代码
|
|
133
|
+
|
|
134
|
+
三原语的输出可以拼成一条可测试、可审计的路由链路:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
r = client.judge(state=ticket, questions={
|
|
138
|
+
"intent": choice({"退款": "要退款", "咨询": "问问题", "投诉": "表达不满"}),
|
|
139
|
+
"urgency": score(["平静", "略不满", "明显不满", "情绪激烈", "准备投诉"]),
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
# 置信度足够 + 情绪不高 → 自动执行;否则转人工
|
|
143
|
+
if r.choice("intent").confidence >= 0.85 and r.score("urgency").score < 2.0:
|
|
144
|
+
auto_execute(r.choice("intent").choice)
|
|
145
|
+
elif r.choice("intent").confidence >= 0.5:
|
|
146
|
+
queue_for_human(r)
|
|
147
|
+
else:
|
|
148
|
+
escalate(r) # 低置信:转大模型或人工
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
阈值按**业务误判成本**定,不是按模型表现定 —— 退款错判的代价和分类错标的代价不一样。
|
|
152
|
+
路由决策本身是普通代码,所以它能被单测、能被 review、能进审计日志。
|
|
153
|
+
|
|
154
|
+
## 自建网关
|
|
155
|
+
|
|
156
|
+
默认走明判的正式入口(`https://mingpan.oneapis.cn/v1/judge`)。
|
|
157
|
+
如果判断能力挂在自己的网关上,直接指向那里即可:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
client = Client(
|
|
161
|
+
api_key="sk-xxx",
|
|
162
|
+
base_url="https://your-gateway.example.com",
|
|
163
|
+
path="/typesafe/v1/systemone", # 插件自有路由,路径与 BFF 不同
|
|
164
|
+
)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
⚠️ 不同网关实例的插件 key 与路由路径可能不同(`/typesafe/v1/systemone` vs
|
|
168
|
+
`/jev/v1/systemone`),照抄另一台的路径会得到 404 或「SPA 兜底返回 HTML」。
|
|
169
|
+
客户端遇到 HTML 响应会明确提示「请检查地址是否正确」,而不是报一句
|
|
170
|
+
含糊的解析失败。
|
|
171
|
+
|
|
172
|
+
## 代理说明
|
|
173
|
+
|
|
174
|
+
SDK 默认沿用环境变量里的 `HTTP_PROXY` / `HTTPS_PROXY`(企业网络下通常必须)。
|
|
175
|
+
想绕过本机代理:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
client = Client(api_key="sk-xxx", use_env_proxy=False)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
代理配错时的典型症状是「同一个 Key 在 `curl` 里能通、在脚本里连不上」——
|
|
182
|
+
遇到这种情况先怀疑代理,再怀疑 Key。
|
|
183
|
+
|
|
184
|
+
## 开发
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
cd sdk/python
|
|
188
|
+
python tests/test_sdk.py # 离线:59 项,不联网
|
|
189
|
+
MINGPAN_TEST_KEY=sk-xxx python tests/test_sdk.py --live # 真实调用(会产生费用)
|
|
190
|
+
```
|
mingpan-0.1.0/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# 明判 Python SDK
|
|
2
|
+
|
|
3
|
+
明判(MingPan)三原语判断接口的 Python 客户端。**运行时零依赖**(只用标准库 `urllib`),
|
|
4
|
+
`pip install` 后即可调用,不引入任何版本冲突。
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pip install mingpan
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
**零运行时依赖** —— 装完不会引入任何第三方包(只用标准库 `urllib`)。
|
|
11
|
+
需要跟仓库里最新未发版的改动时,从源码目录装:`pip install ./sdk/python`。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 快速开始
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from mingpan import Client, choice, score, noul
|
|
19
|
+
|
|
20
|
+
client = Client(api_key="sk-xxx") # 控制台「API Key」页创建
|
|
21
|
+
|
|
22
|
+
result = client.judge(
|
|
23
|
+
state="工单:客户反映发票抬头开错,要求尽快重开,语气着急。",
|
|
24
|
+
questions={
|
|
25
|
+
"intent": choice({"售后": "退换货、维修", "物流": "发货与配送", "计费": "账单与退款"}),
|
|
26
|
+
"urgency": score(["平静", "略不满", "明显不满", "情绪激烈", "准备投诉"]),
|
|
27
|
+
"is_vip": noul("该用户是 VIP 客户"),
|
|
28
|
+
},
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
result.choice("intent").choice # '计费' —— str,不是 dict 里捞出来的
|
|
32
|
+
result.score("urgency").score # 1.5 —— float,0-based 加权
|
|
33
|
+
result.noul("is_vip").is_true(0.6) # False
|
|
34
|
+
result.usage.input_tokens # 391 —— 计费依据
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 三个原语
|
|
38
|
+
|
|
39
|
+
| 原语 | 构造 | 返回 | 说明 |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| `choice` | `choice({"标签": "说明"})` | `choice`(str) / `confidence` / `probabilities` | 从候选中选唯一答案。**`criteria` 是对象**,1–255 项 |
|
|
42
|
+
| `score` | `score(["低", "中", "高"])` | `score`(float) / `confidence` / `probabilities` / `legend` | 放到有序量级上打分。**`criteria` 是数组**,2–10 级,从低到高 |
|
|
43
|
+
| `noul` | `noul("命题正文")` | `noul`(float 0–1) | 判断命题是否成立。**没有 `confidence`** |
|
|
44
|
+
|
|
45
|
+
几个必须知道的事实:
|
|
46
|
+
|
|
47
|
+
- **`score` 是 0-based 浮点**。`score=1.5` 表示重心落在第 2 级(序号 1)附近 ——
|
|
48
|
+
不是「1.5 分 / 满分 5 分」。别拿它当整数用。
|
|
49
|
+
- **`noul` 没有 `confidence`**。SDK 如实不提供该属性:读它会 `AttributeError`,
|
|
50
|
+
而不是悄悄给个 `0.0` 让你的路由代码走错分支。
|
|
51
|
+
- **`criteria` 的说明会进模型**。`{"计费": "账单与退款"}` 的判定质量明显高于
|
|
52
|
+
`["计费"]`。只给标签时模型只能靠字面猜;说明才是准确率的来源。
|
|
53
|
+
- **只有 `input_tokens` 计费**。`output_tokens` 会返回(实测 58–67,不是 0),
|
|
54
|
+
但不在计费式里。
|
|
55
|
+
|
|
56
|
+
## 类型安全
|
|
57
|
+
|
|
58
|
+
`answers` 与 `questions` 同构,但 SDK 会按原语类型**派发成不同的类**,
|
|
59
|
+
取值器对类型不符直接报错:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
result.noul("is_vip") # NoulAnswer
|
|
63
|
+
result.choice("is_vip") # ✗ TypeMismatchError: 实际类型是 noul,不能用 result.choice() 取值
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
这比「字典下标 + `.get()`」安全得多:类型错了在**调用点**就炸,
|
|
67
|
+
而不是在几十行之外的 `NoneType has no attribute` 处炸。
|
|
68
|
+
|
|
69
|
+
## 错误处理
|
|
70
|
+
|
|
71
|
+
每类失败对应一个可分别捕获的类型:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from mingpan import (
|
|
75
|
+
AuthenticationError, InvalidRequestError,
|
|
76
|
+
RateLimitError, ServiceUnavailableError, TransportError,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
result = client.judge(state=state, questions=questions)
|
|
81
|
+
except AuthenticationError: # 401/403:Key 无效、过期、无权。重试无意义
|
|
82
|
+
rotate_key()
|
|
83
|
+
except InvalidRequestError as e: # 400/422:参数不符。message 通常直接给出正确写法
|
|
84
|
+
print(e.message) # → "Choice criteria must contain between 1 and 255 options"
|
|
85
|
+
except RateLimitError: # 429:退避重试,或改用 judge_batch 降低并发
|
|
86
|
+
backoff()
|
|
87
|
+
except ServiceUnavailableError: # 5xx:不计费,可退避重试
|
|
88
|
+
backoff()
|
|
89
|
+
except TransportError: # 网络层:连不上/DNS/超时,检查网络或代理
|
|
90
|
+
pass
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`InvalidRequestError` 的 message 是最有价值的错误信息 ——
|
|
94
|
+
上游的校验错误会直接说出**正确字段名与取值范围**,照着改即可,不必翻文档。
|
|
95
|
+
|
|
96
|
+
## 并发与批量
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
# 单次异步(不阻塞事件循环)
|
|
100
|
+
result = await client.judge_async(state=state, questions=questions)
|
|
101
|
+
|
|
102
|
+
# 多个 state 共享同一套 questions,并发发送,结果按下标对应
|
|
103
|
+
results = client.judge_batch(
|
|
104
|
+
states=[t1, t2, t3],
|
|
105
|
+
questions=questions,
|
|
106
|
+
max_workers=8, # 别调太高:先撞上游限流,换来一批 429
|
|
107
|
+
return_exceptions=True, # 单条失败作为异常对象返回,不中断整批
|
|
108
|
+
)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 把 confidence 接进你的代码
|
|
112
|
+
|
|
113
|
+
三原语的输出可以拼成一条可测试、可审计的路由链路:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
r = client.judge(state=ticket, questions={
|
|
117
|
+
"intent": choice({"退款": "要退款", "咨询": "问问题", "投诉": "表达不满"}),
|
|
118
|
+
"urgency": score(["平静", "略不满", "明显不满", "情绪激烈", "准备投诉"]),
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
# 置信度足够 + 情绪不高 → 自动执行;否则转人工
|
|
122
|
+
if r.choice("intent").confidence >= 0.85 and r.score("urgency").score < 2.0:
|
|
123
|
+
auto_execute(r.choice("intent").choice)
|
|
124
|
+
elif r.choice("intent").confidence >= 0.5:
|
|
125
|
+
queue_for_human(r)
|
|
126
|
+
else:
|
|
127
|
+
escalate(r) # 低置信:转大模型或人工
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
阈值按**业务误判成本**定,不是按模型表现定 —— 退款错判的代价和分类错标的代价不一样。
|
|
131
|
+
路由决策本身是普通代码,所以它能被单测、能被 review、能进审计日志。
|
|
132
|
+
|
|
133
|
+
## 自建网关
|
|
134
|
+
|
|
135
|
+
默认走明判的正式入口(`https://mingpan.oneapis.cn/v1/judge`)。
|
|
136
|
+
如果判断能力挂在自己的网关上,直接指向那里即可:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
client = Client(
|
|
140
|
+
api_key="sk-xxx",
|
|
141
|
+
base_url="https://your-gateway.example.com",
|
|
142
|
+
path="/typesafe/v1/systemone", # 插件自有路由,路径与 BFF 不同
|
|
143
|
+
)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
⚠️ 不同网关实例的插件 key 与路由路径可能不同(`/typesafe/v1/systemone` vs
|
|
147
|
+
`/jev/v1/systemone`),照抄另一台的路径会得到 404 或「SPA 兜底返回 HTML」。
|
|
148
|
+
客户端遇到 HTML 响应会明确提示「请检查地址是否正确」,而不是报一句
|
|
149
|
+
含糊的解析失败。
|
|
150
|
+
|
|
151
|
+
## 代理说明
|
|
152
|
+
|
|
153
|
+
SDK 默认沿用环境变量里的 `HTTP_PROXY` / `HTTPS_PROXY`(企业网络下通常必须)。
|
|
154
|
+
想绕过本机代理:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
client = Client(api_key="sk-xxx", use_env_proxy=False)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
代理配错时的典型症状是「同一个 Key 在 `curl` 里能通、在脚本里连不上」——
|
|
161
|
+
遇到这种情况先怀疑代理,再怀疑 Key。
|
|
162
|
+
|
|
163
|
+
## 开发
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
cd sdk/python
|
|
167
|
+
python tests/test_sdk.py # 离线:59 项,不联网
|
|
168
|
+
MINGPAN_TEST_KEY=sk-xxx python tests/test_sdk.py --live # 真实调用(会产生费用)
|
|
169
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""明判(MingPan)Python SDK —— 三原语判断接口的类型安全客户端。
|
|
2
|
+
|
|
3
|
+
from mingpan import Client, choice, score, noul
|
|
4
|
+
|
|
5
|
+
client = Client(api_key="sk-xxx") # 控制台创建
|
|
6
|
+
result = client.judge(
|
|
7
|
+
state="工单:客户反映发票抬头开错,要求尽快重开,语气着急。",
|
|
8
|
+
questions={
|
|
9
|
+
"intent": choice({"售后": "退换货", "物流": "发货配送", "计费": "账单退款"}),
|
|
10
|
+
"urgency": score(["平静", "略不满", "明显不满", "情绪激烈", "准备投诉"]),
|
|
11
|
+
"is_vip": noul("该用户是 VIP 客户"),
|
|
12
|
+
},
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
result.choice("intent").choice # '计费'
|
|
16
|
+
result.score("urgency").score # 1.5
|
|
17
|
+
result.noul("is_vip").noul # 0.58
|
|
18
|
+
|
|
19
|
+
三个原语的响应形状不同,SDK 如实分派成三个类 —— 尤其 noul **没有 confidence**,
|
|
20
|
+
所以 `NoulAnswer` 上没有这个属性。别指望它「统一」:给不存在的字段补 0.0
|
|
21
|
+
只会让路由代码静默走错分支。
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from .client import DEFAULT_BASE_URL, DEFAULT_MODEL, DEFAULT_PATH, Client
|
|
25
|
+
from .errors import (
|
|
26
|
+
AuthenticationError,
|
|
27
|
+
InvalidRequestError,
|
|
28
|
+
MingpanError,
|
|
29
|
+
RateLimitError,
|
|
30
|
+
ServiceUnavailableError,
|
|
31
|
+
TransportError,
|
|
32
|
+
TypeMismatchError,
|
|
33
|
+
)
|
|
34
|
+
from .questions import choice, noul, score
|
|
35
|
+
from .types import Answer, ChoiceAnswer, JudgeResult, NoulAnswer, ScoreAnswer, Usage
|
|
36
|
+
|
|
37
|
+
__version__ = "0.1.0"
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
# 客户端
|
|
41
|
+
"Client",
|
|
42
|
+
"DEFAULT_BASE_URL",
|
|
43
|
+
"DEFAULT_MODEL",
|
|
44
|
+
"DEFAULT_PATH",
|
|
45
|
+
# 原语构造
|
|
46
|
+
"choice",
|
|
47
|
+
"score",
|
|
48
|
+
"noul",
|
|
49
|
+
# 结果类型
|
|
50
|
+
"JudgeResult",
|
|
51
|
+
"ChoiceAnswer",
|
|
52
|
+
"ScoreAnswer",
|
|
53
|
+
"NoulAnswer",
|
|
54
|
+
"Answer",
|
|
55
|
+
"Usage",
|
|
56
|
+
# 异常
|
|
57
|
+
"MingpanError",
|
|
58
|
+
"TransportError",
|
|
59
|
+
"AuthenticationError",
|
|
60
|
+
"InvalidRequestError",
|
|
61
|
+
"RateLimitError",
|
|
62
|
+
"ServiceUnavailableError",
|
|
63
|
+
"TypeMismatchError",
|
|
64
|
+
"__version__",
|
|
65
|
+
]
|