sdpy-kit 0.7.4__tar.gz → 0.8.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.
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/PKG-INFO +78 -32
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/README.md +1651 -1611
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/__init__.py +98 -98
- sdpy_kit-0.8.0/kit/ai/__init__.py +110 -0
- sdpy_kit-0.8.0/kit/ai/_internal/__init__.py +27 -0
- {sdpy_kit-0.7.4/kit/ai → sdpy_kit-0.8.0/kit/ai/_internal}/failover.py +490 -440
- {sdpy_kit-0.7.4/kit/ai → sdpy_kit-0.8.0/kit/ai/_internal}/rerank_transport.py +137 -138
- {sdpy_kit-0.7.4/kit/ai → sdpy_kit-0.8.0/kit/ai/_internal}/sdk_client.py +463 -383
- sdpy_kit-0.7.4/kit/ai/_service_base.py → sdpy_kit-0.8.0/kit/ai/_internal/service_base.py +1 -1
- {sdpy_kit-0.7.4/kit/ai → sdpy_kit-0.8.0/kit/ai/_internal}/types.py +1 -1
- sdpy_kit-0.8.0/kit/ai/agent/__init__.py +127 -0
- sdpy_kit-0.8.0/kit/ai/agent/approval.py +66 -0
- sdpy_kit-0.8.0/kit/ai/agent/errors.py +119 -0
- sdpy_kit-0.8.0/kit/ai/agent/loop.py +622 -0
- sdpy_kit-0.8.0/kit/ai/agent/mcp.py +266 -0
- sdpy_kit-0.8.0/kit/ai/agent/registry.py +199 -0
- sdpy_kit-0.8.0/kit/ai/agent/session.py +150 -0
- sdpy_kit-0.8.0/kit/ai/agent/skill.py +362 -0
- sdpy_kit-0.8.0/kit/ai/agent/types.py +157 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/chat_service.py +719 -615
- sdpy_kit-0.8.0/kit/ai/decision/__init__.py +57 -0
- sdpy_kit-0.7.4/kit/decima_kit.py → sdpy_kit-0.8.0/kit/ai/decision/decima.py +853 -853
- sdpy_kit-0.7.4/kit/laya_kit.py → sdpy_kit-0.8.0/kit/ai/decision/laya.py +552 -552
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/embedding_service.py +198 -206
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/image_service.py +84 -101
- sdpy_kit-0.8.0/kit/ai/messages.py +105 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/model_client.py +62 -62
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/rerank_service.py +136 -136
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/runner.py +1127 -1127
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/pyproject.toml +12 -1
- sdpy_kit-0.7.4/kit/ai/__init__.py +0 -49
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/.gitignore +0 -0
- {sdpy_kit-0.7.4/kit/ai → sdpy_kit-0.8.0/kit/ai/_internal}/pool.py +0 -0
- /sdpy_kit-0.7.4/kit/ai/_retry_after.py → /sdpy_kit-0.8.0/kit/ai/_internal/retry_after.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/exceptions.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/model_builder.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/ai/profiles.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/common_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/config/__init__.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/config/kit_config.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/config/log_config.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/crawl/__init__.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/crawl/article_io.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/crawl/article_models.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/crawl/deepseek_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/crawl/web_article_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/crawl/wx_article_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/__init__.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/audit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/base_db_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/crud.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/engine.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/exceptions.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/models/__init__.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/models/base.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/mysql_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/pg_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/query.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/session.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/sqlite_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/db/transaction.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/docs/__init__.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/docs/anydoc_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/docs/docx_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/docs/marker_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/docs/md2doc_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/docs/mineru_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/docs/rc_docparser_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/file_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/license_kit.py +0 -0
- {sdpy_kit-0.7.4 → sdpy_kit-0.8.0}/kit/redis_kit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sdpy-kit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: SDPY Kit——统一数据库访问层(PG/MySQL/SQLite)与 AI/Redis/文件/文档/向量工具集
|
|
5
5
|
Author-email: Clark <changhongyuan@126.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -22,6 +22,12 @@ Requires-Dist: pydantic-settings>=2.16.1
|
|
|
22
22
|
Requires-Dist: pydantic>=2.14.1
|
|
23
23
|
Requires-Dist: sqlalchemy~=2.0.54
|
|
24
24
|
Requires-Dist: sqlmodel>=0.0.48
|
|
25
|
+
Provides-Extra: agent
|
|
26
|
+
Requires-Dist: fastmcp-slim[client]<5,>=4.1.7; extra == 'agent'
|
|
27
|
+
Requires-Dist: httpx>=0.28.1; extra == 'agent'
|
|
28
|
+
Requires-Dist: openai<4,>=3.44; extra == 'agent'
|
|
29
|
+
Requires-Dist: python-dotenv>=1.2.4; extra == 'agent'
|
|
30
|
+
Requires-Dist: pyyaml>=6.0.3; extra == 'agent'
|
|
25
31
|
Provides-Extra: ai
|
|
26
32
|
Requires-Dist: httpx>=0.28.1; extra == 'ai'
|
|
27
33
|
Requires-Dist: openai<4,>=3.44; extra == 'ai'
|
|
@@ -97,6 +103,7 @@ SDPY 统一工具集(Kit 体系),供 Python 项目开箱即用:
|
|
|
97
103
|
| `kit.config` | `get_settings` / `get_default_logger` | 配置单例与统一日志 | 无 |
|
|
98
104
|
| `kit.db` | `SQLiteKit` / `PgKit` / `MySqlKit` / `CRUDBase` | 统一 CRUD、原生 SQL、原生表操作、事务、表管理 | `pg` / `mysql` / `sqliteai` |
|
|
99
105
|
| `kit.ai` | `AI`(同步门面)/ 4 个原生异步 Service | 对话 / 向量化 / 重排序 / 文生图 | `ai` |
|
|
106
|
+
| `kit.ai.agent` | `Agent` / `ToolRegistry` / `SkillRegistry` / `McpServerConfig` / `Session` | MCP client(HTTP / stdio)+ Skill 包加载 + 模型驱动工具循环 | `agent` |
|
|
100
107
|
| `kit.redis_kit` | `RedisKit` | Redis string / hash / list / set / zset | `redis` |
|
|
101
108
|
| `kit.file_kit` | `FileKit` | 文件与目录读写、移动、遍历 | 无 |
|
|
102
109
|
| `kit.common_kit` | `CommonKit` | 雪花 ID、时间戳 ID、时间格式化 | 无 |
|
|
@@ -107,8 +114,8 @@ SDPY 统一工具集(Kit 体系),供 Python 项目开箱即用:
|
|
|
107
114
|
| `kit.docs.md2doc_kit` | `Md2DocKit` | Markdown → Word / PDF / HTML(含图片) | `md2doc` |
|
|
108
115
|
| `kit.docs.mineru_kit` | `MinerUKit` | MinerU 文档解析(精准 + Agent 轻量) | `mineru` |
|
|
109
116
|
| `kit.docs.marker_kit` | `MarkerKit` | 本地解析(PDF / 图片 → Markdown + Images);**0.7.0 起暂停发布**,需要请用 `sdpy-kit==0.6.10` | — |
|
|
110
|
-
| `kit.
|
|
111
|
-
| `kit.
|
|
117
|
+
| `kit.ai.decision.laya` | `LayaKit` | 类型化决策:choice / multi_choice 多选 / score / noul,另含 decide 多字段 / decide_batch 批量 / predict_long 长文本 | `laya` |
|
|
118
|
+
| `kit.ai.decision.decima` | `DecimaKit` | 决策模型:choice / score / noul / multi_choice(原生 rank);选项乱序不变、置信度可门控;另含 predict / predict_long / brief / choice_batch(方法名与 `LayaKit` 对齐) | `decima` |
|
|
112
119
|
| `kit.crawl.article_models` | `ArticleInfo` / `ArticleResult` / `SavedOutput` 等 | 文章抓取通用模型(三个 `*ArticleKit` 共用,含 `reason` 分类与非致命 `warnings`) | 无 |
|
|
113
120
|
| `kit.crawl.article_io` | `resolve_stem` / `save_article` 等 | 落盘公共层(目录命名 / 图片本地化 / YAML 头 / `meta.json`),三个 `*ArticleKit` 共用 | 无 |
|
|
114
121
|
| `kit.crawl.wx_article_kit` | `WxArticleKit` | 微信公众号文章 → Markdown + 图片转存 | 无 |
|
|
@@ -140,8 +147,48 @@ uv add sdpy-kit
|
|
|
140
147
|
| `laya` | LayaKit 类型化决策(laya + torch,本地小模型 choice / multi_choice / score / noul;支持多字段 / 批量 / 长文本) | `pip install "sdpy-kit[laya]"` |
|
|
141
148
|
| `decima` | DecimaKit 决策模型(decima-ai + onnxruntime,**无 torch**;选项乱序不变、置信度可门控;磁盘约 137 MB) | `pip install "sdpy-kit[decima]"` |
|
|
142
149
|
| `web-article` | WebArticleKit 通用网页文章抓取转存(trafilatura,纯 HTTP 无浏览器) | `pip install "sdpy-kit[web-article]"` |
|
|
150
|
+
| `agent` | Agent 能力:MCP client(fastmcp-slim)+ Skill 加载 + 工具循环(含 ai 三项依赖与 pyyaml) | `pip install "sdpy-kit[agent]"` |
|
|
143
151
|
| `recommended` | 常用能力集合(DB / 缓存 / AI / 文档 / 抓取);不含重依赖(laya / decima)与 Marker(0.7.0 起暂停发布) | `pip install "sdpy-kit[recommended]"` |
|
|
144
152
|
|
|
153
|
+
## Agent 快速开始(extra `agent`)
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
import asyncio
|
|
157
|
+
|
|
158
|
+
from kit.ai.agent import Agent, McpServerConfig, SkillRegistry
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
async def main() -> None:
|
|
162
|
+
skills = SkillRegistry()
|
|
163
|
+
skills.load("./skills") # 一级子目录含 SKILL.md 即注册
|
|
164
|
+
|
|
165
|
+
agent = Agent(
|
|
166
|
+
skills=skills,
|
|
167
|
+
servers=[
|
|
168
|
+
McpServerConfig(
|
|
169
|
+
name="filesystem",
|
|
170
|
+
transport="stdio",
|
|
171
|
+
command="npx",
|
|
172
|
+
args=["-y", "@modelcontextprotocol/server-filesystem", "./data"],
|
|
173
|
+
)
|
|
174
|
+
],
|
|
175
|
+
system_prompt="你是一个谨慎的文档助手。",
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
async with agent: # 建连一次,可多次 run()
|
|
179
|
+
result = await agent.run("总结 data 目录里的文件")
|
|
180
|
+
print(result.text)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
asyncio.run(main())
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
- 模型档案沿用 `kit.ai`(`config/ai_models.json`),首轮可 failover,成功后锁定档案;
|
|
187
|
+
- Skill 只读工具:`read_skill` / `list_skill_files` / `read_skill_file`(路径越界拒绝);
|
|
188
|
+
- MCP 工具默认放行,skill 脚本默认拒绝;可用 `DenyAllApproval` 整体收紧;
|
|
189
|
+
- `timeout` / `max_turns` / `tool_timeout` 控制总预算与轮次;
|
|
190
|
+
- 完整说明见 `docs/agents/modules/agent-kit.md`(仓库内)。
|
|
191
|
+
|
|
145
192
|
## 配置(.env)
|
|
146
193
|
|
|
147
194
|
kit 通过 pydantic-settings 读取项目根目录 `.env`;**同名真实环境变量优先于 `.env`**。全部变量都有默认值,按需覆盖即可。
|
|
@@ -278,7 +325,7 @@ SQLITE_DB_PATH=./data/sqlite.db
|
|
|
278
325
|
|
|
279
326
|
> 这四项由 kit 在**导入 marker 之前**经 `os.environ.setdefault` 应用:仅当用户未显式设置对应环境变量时生效,不覆盖显式配置。
|
|
280
327
|
|
|
281
|
-
**Laya** → `kit.
|
|
328
|
+
**Laya** → `kit.ai.decision.laya`
|
|
282
329
|
|
|
283
330
|
| 环境变量 | 默认值 | 作用 |
|
|
284
331
|
|----------|--------|------|
|
|
@@ -299,7 +346,7 @@ SQLITE_DB_PATH=./data/sqlite.db
|
|
|
299
346
|
> `LAYA_HF_*` 同样由 kit 在**导入 laya 之前**经 `os.environ.setdefault` 应用,不覆盖显式配置;
|
|
300
347
|
> `LAYA_MODEL` / `LAYA_DEVICE` / `LAYA_PRELOAD` / `LAYA_MAX_LOADED` 由 `Settings` 读取(进程内缓存,改后需重启进程)。
|
|
301
348
|
|
|
302
|
-
**Decima** → `kit.
|
|
349
|
+
**Decima** → `kit.ai.decision.decima`
|
|
303
350
|
|
|
304
351
|
| 环境变量 | 默认值 | 作用 |
|
|
305
352
|
|----------|--------|------|
|
|
@@ -360,8 +407,8 @@ SQLITE_DB_PATH=./data/sqlite.db
|
|
|
360
407
|
|----------|----------|
|
|
361
408
|
| `LOG_*`、`DB_*`、`MYSQL_*`、`REDIS_*`、`FILE_STORAGE_ROOT`、`MINERU_*`、`MARKER_MODE` | `get_settings()` 带 `lru_cache`,进程内首次读取后固定 → **重启进程**(或调用 `AI.reload_config()`,它会顺带清空该缓存) |
|
|
362
409
|
| `MARKER_HF_ENDPOINT` / `MARKER_HF_DISABLE_XET` / `MARKER_LLAMA_CPP_BINARY` | 仅在 `import kit.docs.marker_kit` 时经 `os.environ.setdefault` 应用 → 改动需**重启进程**重新导入模块 |
|
|
363
|
-
| `LAYA_HF_ENDPOINT` / `LAYA_HF_DISABLE_XET` | 仅在 `import kit.
|
|
364
|
-
| `DECIMA_HF_ENDPOINT` / `HF_HUB_DISABLE_XET` | 仅在 `import kit.
|
|
410
|
+
| `LAYA_HF_ENDPOINT` / `LAYA_HF_DISABLE_XET` | 仅在 `import kit.ai.decision.laya` 时经 `os.environ.setdefault` 应用 → 改动需**重启进程**重新导入模块 |
|
|
411
|
+
| `DECIMA_HF_ENDPOINT` / `HF_HUB_DISABLE_XET` | 仅在 `import kit.ai.decision.decima` 时经 `os.environ.setdefault` 应用 → 改动需**重启进程**重新导入模块 |
|
|
365
412
|
| AI 密钥写在 `.env` 里 | `.env` 只在加载档案时注入一次 → 重启,或 `AI.reload_config(reload_file=True)` |
|
|
366
413
|
| AI 密钥由自己写入 `os.environ` | `AI.reload_config()`(默认 `reload_file=False`,只重读 `os.environ`) |
|
|
367
414
|
| `ai_models.json`(增删档案、换 model) | `AI.reload_config(reload_file=True)` |
|
|
@@ -821,11 +868,11 @@ page = qb.paginate(page=1, per_page=20) # {"items", "total", ...}
|
|
|
821
868
|
### 1. 同步门面 `AI`(推荐)
|
|
822
869
|
|
|
823
870
|
```python
|
|
824
|
-
from kit.ai
|
|
871
|
+
from kit.ai import AI, shutdown
|
|
825
872
|
|
|
826
|
-
text = AI.
|
|
873
|
+
text = AI.chat_once("用一句话介绍 Python") # 单轮对话
|
|
827
874
|
hits = AI.rerank("水声通信", ["文档A", "文档B"], top_n=2) # 重排序
|
|
828
|
-
url = AI.
|
|
875
|
+
url = AI.image("一只在写代码的猫") # 文生图
|
|
829
876
|
AI.use("chat", "glm") # 切换当前档案(进程内长期生效)
|
|
830
877
|
print(AI.available("chat")) # 查看各档案状态快照
|
|
831
878
|
shutdown() # 应用退出前释放资源(幂等)
|
|
@@ -833,13 +880,13 @@ shutdown() # 应用退出前
|
|
|
833
880
|
|
|
834
881
|
| 分组 | 方法 | 说明 |
|
|
835
882
|
|------|------|------|
|
|
836
|
-
| chat | `
|
|
837
|
-
| chat | `
|
|
883
|
+
| chat | `chat_once(prompt, *, max_tokens=None, thinking=None, json_mode=None, response_format=None, stats=None) -> str` | 单轮对话(仅 user 消息) |
|
|
884
|
+
| chat | `chat(messages, *, max_tokens=None, thinking=None, json_mode=None, response_format=None, stats=None) -> str` | 多轮对话,`messages` 为 `[{"role": "user", "content": "..."}]` |
|
|
838
885
|
| chat | `chat_stream(messages, *, max_tokens=None, thinking=None, json_mode=None, response_format=None) -> Iterator[str]` | 同步流式逐 token 迭代器(建议 `with` 使用);结束后可读 `reasoning_chars` / `content_chars` / `finish_reason` / `requested_max_tokens` / `truncated` / `empty_kind` / `thinking_applied` / `json_mode_applied` |
|
|
839
|
-
| embedding | `
|
|
840
|
-
| embedding | `
|
|
886
|
+
| embedding | `create(text) -> list[float]` | 单文本向量化 |
|
|
887
|
+
| embedding | `create_batch(texts) -> list[list[float]]` | 批量向量化 |
|
|
841
888
|
| rerank | `rerank(query, documents, top_n=None) -> list[RerankHit]` | 返回 `RerankHit`(`index` / `score` / `document`)降序列表;**`top_n` 是返回条数上限,由 kit 本地裁剪**(服务端返回超量也按分数截断),`top_n=None` 返回全部命中,`top_n<=0` 直接返回空列表 |
|
|
842
|
-
| image | `
|
|
889
|
+
| image | `image(prompt, *, size=None, n=1, return_base64=False, ratio=None) -> ImageResult` | 文生图,返回 `ImageResult`(`url` / `b64` 至少一个非空) |
|
|
843
890
|
| 管理 | `use(model_type, profile) -> None` | 切换该类型当前档案(`chat` / `embedding` / `rerank` / `image`) |
|
|
844
891
|
| 管理 | `available(model_type) -> list[ProfileStatus]` | 各档案状态快照(含未配置密钥与被剔除者);**类型未在 `ai_models.json` 中配置时返回 `[]`**(不再抛异常),类型名非法抛 `AIModelTypeNotConfiguredError`(`AIConfigError` 子类) |
|
|
845
892
|
| 管理 | `reload_config(*, model_type=None, reload_file=False, probe=True, immediate=False) -> ReloadResult` | 配置热重载,改密钥 / 档案后无需重启;同时清空思考/结构化输出的告警去重表(修正档案后同一原因会重新提示) |
|
|
@@ -848,7 +895,7 @@ shutdown() # 应用退出前
|
|
|
848
895
|
判断某类型是否已配置用 `if not AI.available(t)`,不要靠捕获异常:
|
|
849
896
|
|
|
850
897
|
```python
|
|
851
|
-
from kit.ai
|
|
898
|
+
from kit.ai import AI
|
|
852
899
|
|
|
853
900
|
profiles = AI.available("image") # ai_models.json 无 image 段 → []
|
|
854
901
|
if not profiles:
|
|
@@ -860,7 +907,7 @@ current = next((p for p in profiles if p.current), None)
|
|
|
860
907
|
> `AI.available(t)[0]` 在类型未配置时会抛 `IndexError`,请改用上面的判空写法。
|
|
861
908
|
|
|
862
909
|
```python
|
|
863
|
-
from kit.ai
|
|
910
|
+
from kit.ai import AI
|
|
864
911
|
|
|
865
912
|
with AI.chat_stream([{"role": "user", "content": "写一首短诗"}]) as stream:
|
|
866
913
|
for token in stream: # 逐 token 消费
|
|
@@ -915,9 +962,9 @@ if not body:
|
|
|
915
962
|
同一档案下按调用点切换思考(入库抽取关、章节生成开),不必复制档案:
|
|
916
963
|
|
|
917
964
|
```python
|
|
918
|
-
AI.
|
|
919
|
-
AI.
|
|
920
|
-
AI.
|
|
965
|
+
AI.chat(messages, thinking=False) # 关闭思考
|
|
966
|
+
AI.chat(messages, thinking=True) # 开启思考
|
|
967
|
+
AI.chat(messages) # None:不干预(按档案 thinking.default;未配置则请求体逐字节不变)
|
|
921
968
|
```
|
|
922
969
|
|
|
923
970
|
kit 不认识任何厂商字段名,请求体字段由档案 `thinking` 声明翻译(见「ai_models.json 可选字段」)。
|
|
@@ -941,7 +988,7 @@ kit 不认识任何厂商字段名,请求体字段由档案 `thinking` 声明
|
|
|
941
988
|
只要「合法 JSON 对象」用 `json_mode=True`;要约束字段用协议的 `response_format` 原样透传:
|
|
942
989
|
|
|
943
990
|
```python
|
|
944
|
-
answer = AI.
|
|
991
|
+
answer = AI.chat(messages, json_mode=True) # 要求返回 JSON 对象
|
|
945
992
|
|
|
946
993
|
fmt = {
|
|
947
994
|
"type": "json_schema",
|
|
@@ -956,7 +1003,7 @@ fmt = {
|
|
|
956
1003
|
},
|
|
957
1004
|
},
|
|
958
1005
|
}
|
|
959
|
-
answer = AI.
|
|
1006
|
+
answer = AI.chat(messages, response_format=fmt) # 严格模式:schema 由你负责
|
|
960
1007
|
```
|
|
961
1008
|
|
|
962
1009
|
- **缺省即注入(开箱即用)**:档案未声明 `structured_output` 时,`json_mode=True` 按 OpenAI 兼容默认写
|
|
@@ -977,7 +1024,7 @@ answer = AI.chat_ask(messages, response_format=fmt) # 严格模式:schema
|
|
|
977
1024
|
from kit.ai import StreamStats
|
|
978
1025
|
|
|
979
1026
|
stats = StreamStats()
|
|
980
|
-
body = AI.
|
|
1027
|
+
body = AI.chat(messages, json_mode=True, stats=stats)
|
|
981
1028
|
if stats.truncated: # finish_reason 为 length / max_tokens
|
|
982
1029
|
... # 半截 JSON:直接重试或调大 max_tokens,不要尝试修复
|
|
983
1030
|
```
|
|
@@ -995,21 +1042,20 @@ if stats.truncated: # finish_reason 为 length / max_tokens
|
|
|
995
1042
|
```python
|
|
996
1043
|
from kit.ai import (
|
|
997
1044
|
ChatService, EmbeddingService, RerankService, ImageService, # 服务类
|
|
998
|
-
ChatRequest, EmbeddingRequest, RerankRequest, ImageRequest, # 请求模型
|
|
999
1045
|
RerankHit, ImageResult, StreamStats, ModelBuilder, # 结果类型 / 构建器
|
|
1000
1046
|
)
|
|
1001
1047
|
|
|
1002
1048
|
service = ModelBuilder.build_chat() # 老按类型构建:build_chat / build_embedding / build_rerank / build_image
|
|
1003
|
-
answer = await service.
|
|
1049
|
+
answer = await service.create(messages) # 或 await service.create_once(prompt)
|
|
1004
1050
|
await service.close()
|
|
1005
1051
|
```
|
|
1006
1052
|
|
|
1007
1053
|
| 类 | 方法 |
|
|
1008
1054
|
|----|------|
|
|
1009
|
-
| `ChatService` | `
|
|
1010
|
-
| `EmbeddingService` | `
|
|
1011
|
-
| `RerankService` | `
|
|
1012
|
-
| `ImageService` | `
|
|
1055
|
+
| `ChatService` | `create(messages, *, temperature=None, max_tokens=None, thinking=None, json_mode=None, response_format=None, stats: StreamStats \| None = None, deadline=None) -> str`、`create_once(prompt, *, ...) -> str`、`create_stream(messages, *, ..., stats: StreamStats \| None = None) -> AsyncIterator[str]`(传 `StreamStats()` 即可读收尾统计);`thinking` / `json_mode` / `response_format` 语义与门面一致 |
|
|
1056
|
+
| `EmbeddingService` | `create(text) -> list[float]`、`create_batch(texts, *, batch_size=None, concurrency=4) -> list[list[float]]`、`dimension` 属性(**目标维度**,见下) |
|
|
1057
|
+
| `RerankService` | `create(query, documents, *, top_n=None) -> list[RerankHit]`(已按 score 降序) |
|
|
1058
|
+
| `ImageService` | `create(prompt, *, size=None, n=1, return_base64=False, ratio=None) -> ImageResult` |
|
|
1013
1059
|
| `ModelBuilder` | `build(model_type, model=None, *, api_key=None)` 及各类型专用 `build_chat / build_embedding / build_rerank / build_image` |
|
|
1014
1060
|
| `SdkServiceBase` | `profile` 属性、`await close()`、支持 `async with` |
|
|
1015
1061
|
|
|
@@ -1385,7 +1431,7 @@ if result.success:
|
|
|
1385
1431
|
> 前提:中文标题依赖 `w:outlineLvl` 或「标题 N」样式(都没有时退化为正文);合并单元格表格会重建为
|
|
1386
1432
|
> 等宽 GFM(覆盖位留空,不输出 HTML `<table>`);页眉页脚/脚注不提取。纯本地,无需模型或 GPU。
|
|
1387
1433
|
|
|
1388
|
-
## kit.
|
|
1434
|
+
## kit.ai.decision.decima —— 选项乱序不变、置信度可门控的决策模型
|
|
1389
1435
|
|
|
1390
1436
|
122M 参数的 late-interaction 决策模型(int8 ONNX,单 CPU 线程,**不依赖 torch**)。
|
|
1391
1437
|
每个选项独立编码、独立与 state 打分,因此**调换选项顺序不会改变答案**。
|
|
@@ -1395,7 +1441,7 @@ pip install "sdpy-kit[decima]"
|
|
|
1395
1441
|
```
|
|
1396
1442
|
|
|
1397
1443
|
```python
|
|
1398
|
-
from kit.
|
|
1444
|
+
from kit.ai.decision.decima import DecimaKit
|
|
1399
1445
|
|
|
1400
1446
|
state = "我们三月份被重复扣费了两次,请把重复的那笔退款。"
|
|
1401
1447
|
|
|
@@ -1647,7 +1693,7 @@ AI 功能需要在项目根目录提供 `config/ai_models.json`(chat / embeddi
|
|
|
1647
1693
|
|------|------|------|
|
|
1648
1694
|
| 档案级 | `endpoint` | 请求路径。**仅 rerank 生效**:chat / embedding / image 由 openai SDK 固定拼路径,本字段被忽略(保留仅为兼容旧配置,不报错) |
|
|
1649
1695
|
| 档案级 | `timeout` | 请求超时秒数(默认 60);SDK 侧为单次调用总超时。**流式例外**:流式请求 `timeout=None`,由门面首帧 60s + 帧间隔 120s 兜底 |
|
|
1650
|
-
| 档案级 | `max_tokens` | 输出上限(chat 用);`AI.
|
|
1696
|
+
| 档案级 | `max_tokens` | 输出上限(chat 用);`AI.chat/chat_once/chat_stream` 也可按调用点传参,逐级回落:调用点 → 档案 → provider 默认 |
|
|
1651
1697
|
| 档案级 | `retries` | 5xx 重试次数(默认 2;超时不重试,候选链切换才是有效重试) |
|
|
1652
1698
|
| 档案级 | `extra_body` | 厂商专有请求体字段透传(如 GLM/Qwen 关闭思考的 `{"thinking": {"type": "disabled"}}`、`{"reasoning_effort": "low"}`);与服务构造的同名键冲突时**以服务的值为准**,故 `model` / `messages` / `stream` 等保留键不可覆盖;改名类需求(如 OpenAI o 系列的 `max_completion_tokens`)无法用它实现。逐调用 `thinking` 与之同键时**以逐调用为准**并打 `WARNING`。改文件后需 `reload_config(reload_file=True)` 生效 |
|
|
1653
1699
|
| 档案级 | `thinking` | 思考开关的注入声明:`{"arg": "thinking", "off": {"type": "disabled"}, "on": {"type": "enabled"}, "default": false}`。`arg` 是请求体顶层键名(不得占用 `model` / `messages` / `stream` / `max_tokens` / `temperature` 等保留键,配置期与运行期双重校验);`off` / `on` 可为**任意 JSON 值**(双方都是 dict 时浅合并,否则整键替换);`on` 缺省表示不能显式开启;`default` 为档案默认三态(`null` 不干预 / `false` 默认关 / `true` 默认开)。**未声明 = 不支持按调用切换**:逐调用 `thinking` 被忽略并告警(不报错、不影响候选链冷却)。kit 只做翻译,不含任何厂商名 |
|