状态:✅ 全部完成、已结案(2026-07-16 复核:原 §3「暂缓」两项均已不成立, 见 §3)。D7 死代码清理 2026-06;D6 按「中立层容许别名」定调; 双消息体系统一已于 2026-07-10 落地(v0.2):删除
model/types.clj, tool-call 全库统一为{:id :name(字符串) :args}(与中立消息同构), response→neutral 桥退化为形状复位。 来源:2026-06-10 全量审查 D6「core 泄漏厂商 wire 知识」、D7「重复抽象」。
审查指「4 份响应归一化 + 协议死方法 + 双消息体系」。经调用方核查,先清掉确证为死的部分:
| 删除项 | 位置 | 核查结论 |
|---|---|---|
协议方法 build-result-messages / build-assistant-message | model.clj 协议定义 + extend-type Object 默认实现 + 4 个 provider record(base/anthropic/bailian/mock)+ 全部测试 reify | :build-result-msgs 由 service 构造但从不被调用;历史由 advisor/memory/response->neutral(中立消息)构建。全链路无消费者。 |
call-with-tools | model.clj | 核心里的「第 4 份归一化」,仅测试调用,生产路径走 service/normalize-response。 |
:build-result-msgs service 键 | model/service.clj/create-service | 同上,构造即死。 |
response-assistant-msg / :assistant-msg | model/response.clj(ILLMResponse 协议 + LLMResponse 字段 + make-response 参数) | 仅由已删的 build-assistant-message 填充,从不被读取。 |
独立函数 build-assistant-message | common/openai_compat.clj | 无调用方。 |
附带一致性修复:service/normalize-response(同步路径)现也调 response/extract-reasoning,
与 stream / response_parser 路径对齐(此前只有流式/解析器路径提取 reasoning)。
净效果:协议从 11 方法减到 9(必需 5 + 可选 4);响应归一化从「4 份」收敛为
2 份活路径(service/normalize-response 同步 + stream/* 流式,二者输入不同——
原始响应 map vs 流式累积 state——是合理分工,不再有第 3、4 份冗余)。测试 196→192
(删掉 4 个针对死方法的测试),断言数稳定,0 失败。
清掉 call-with-tools 后,"原始响应里 usage/finish-reason/reasoning 在哪" 的知识
只剩一处权威实现:model/response.clj 的 normalize-usage /
normalize-finish-reason / extract-reasoning。service/normalize-response 与
common/response_parser 都委托它,不再各写一份。
model/response.clj 的归一化函数仍然"认识"各家字段名(OpenAI prompt_tokens、
Anthropic cache_creation_input_tokens、DeepSeek prompt_cache_hit_tokens、
GLM sensitive 等)。这是有意保留的中立层设计,而非 D6 残留 bug:
extract-text / extract-tool-calls(协议方法,provider 自取)不同,usage/finish-reason
在多数 provider 间只有两种常见位置(顶层 or choices[0]),permissive 双查足够鲁棒。extract-usage / extract-finish-reason,每个 provider 自实现)
是破坏性变更:协议加方法 → 所有 provider record + 所有测试 reify 都要实现。
收益(新增"第三种 usage 位置"的 provider 才需改 core)与破坏面不成比例。结论:保留 permissive 单一来源;新增 provider 若用非主流字段,只需在
model/response.clj 一处加别名。若未来要做破坏性大版本,再考虑协议化。
本节原题「暂缓(需专项 / 破坏性大版本)」,列了 D7 剩余与 D6 剩余两项。 复核发现两项都已不成立,且本文档头部状态与本节自相矛盾(头部写「双消息体 系统一已于 2026-07-10 落地」,本节还写着「建议作为 v0.2 专项」)。现结案:
model/types.clj 已删除——model/ 下现只有 message / response / error /
service。tool-call 全库统一为 {:id :name(字符串) :args}(与中立消息同构),
response→neutral 桥退化为形状复位。scripts/check_docs.clj 已为 model.types
立墓碑,防文档复活这个幽灵 ns。
原文说「converter/json_schema.clj 按 :openai/:anthropic/:zhipu/:gemini 生成
结构化输出格式,是 core 里另一处『认识各家 wire』,随 v0.2 一并处理」。
整个 converter/ 子系统已在 c1a3ab1(「删除无消费者的 converter + prompt
子系统」)中删除——json_schema.clj / api.clj / json.clj / protocol.clj /
retry.clj 全没了,core 里 im.ttalk.agent.converter 零引用。
这项工作的对象本身不存在了,无从「随 v0.2 处理」。
(结构化输出现由 advisor/structured_output.clj 承担,JSON 解析经 :parse-fn
注入——core 不内置解析器,见 advisor-alignment-design.md §3。)
extract-usage / extract-finish-reason):不做保留 permissive 中立层(认识各家字段别名)就是 D6 的结论(见本文头部「定调」)。
协议化是破坏性变更、收益/破坏不成比例,且无真实需求——原记「留 v0.2」,
而 v0.2 已发布、0.3 亦在途,无人触发。按
design-principles.md §1,触发条件到期无人问津即证其为
假想需求,故结案不再挂账。
build-result-messages/build-assistant-message 与响应协议
response-assistant-msg。外部若有自定义 provider 实现了这些方法——删掉即可(运行时本就不调用);
若读取过 response-assistant-msg——该值本就恒为 nil。属安全的破坏。Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |