docs(design): 给 0008 与 0009 补上外部先例,两个决定都是印证不是改动
0008:主流框架没有一家把截断量做成工具返回值上的字段(Anthropic 的 tool_result 只有三个
字段,OpenAI/LlamaIndex/Pydantic AI 的结果类型都没有),唯一结构化记下来的 LangChain 走的
是通用 artifact 通道而不是专设字段。另补「将来要加时怎么加」的正反两例:Pydantic AI 在允许
返回的类型集合里加一个新类型、旧路径不动,零兼容问题;OpenAI Agents SDK 改成运行期形状
嗅探,一个返回 {"msg": ...} 的普通工具被当成图片输出转掉、线上 400,三天后回落。
0009:Pydantic AI 2026-07 加过一条几乎同形的 meta-test(扫描包、新增公共数据类超过一个位置
参数就失败),PR 正文两句正好对上本文两条论证——「一条老在评审里被提却没有机器执行的意见」,
以及「不给已有的数据类补,那会打断按位置构造的调用方;白名单只减不增,清空它得发新 major」。
它已经付了本文想避开的那笔账。另记一条连带影响:kw_only 字段不进 __match_args__。
This commit is contained in:
@@ -194,8 +194,21 @@ outputBytes / maxLines / maxBytes` 这一组**绝对量**加两个布尔,不
|
||||
**停机不是截断**——本库把它落成了停止判定 B 档的 `context_overflow`。也就是说本库这条主路上
|
||||
根本不该发生截断,`observation_truncated_chars` 恒为 0 不是缺口,是这条路径的真实情况。
|
||||
|
||||
**主流框架没有一家把截断量做成工具返回值上的字段。** Anthropic 的 `tool_result` 内容块只有
|
||||
`tool_use_id` / `content` / `is_error` 三个字段;OpenAI Agents SDK 的三个输出类型、LlamaIndex
|
||||
的 `ToolOutput`、Pydantic AI 的 `ToolReturn` 都没有截断字段。唯一把「截了多少」结构化记下来的
|
||||
是 LangChain 的 shell 中间件,而它走的是通用的 `artifact` 通道(一个随便装什么的字典),不是
|
||||
为截断专设的字段。截断本身也都发生在工具实现或宿主那一层,不在循环框架里。
|
||||
|
||||
## 留给后续的
|
||||
|
||||
**真出现一个要报截断量的消费者时,加的应该是一个新的返回类型,不是往 `str` 上打补丁。** 那时
|
||||
把 `ToolHandler` 的返回改成联合类型(`str | ToolOutput`)对已有实现是兼容变更,而字段形状按
|
||||
那个消费者真实要的来定,不按今天猜的来定。
|
||||
|
||||
这条路有现成的正反两例。**Pydantic AI 就是这么做的**:它在允许返回的类型集合里加了一个
|
||||
`ToolReturn`,旧的「返回任意对象」那条路一点没动,所以没有兼容问题、也不需要迁移说明
|
||||
(PR #2060,随 v0.3.5 发布)。**反面是 OpenAI Agents SDK**:它在 v0.4.0 里改成对返回值做运行期
|
||||
形状嗅探,一个本意只是返回 `{"msg": "foobar"}` 的工具被当成图片输出转换掉,线上直接 400,
|
||||
三天后不得不收紧规则、让不合形状的字典回落成 `str()`(PR #1898 → issue #1930 → PR #1965)。
|
||||
区别在于加一个显式类型还是去猜一个已有类型的意图——**将来加这个能力时走前一条**。
|
||||
|
||||
Reference in New Issue
Block a user