DeepSeek Harness · Internal Deep Dive

DSH × pi-ai
数据流、核心对象与框架选型

DSH 为什么把 pi-ai 放进自己的 LLM seam?两者之间到底传了什么?为什么不是 LiteLLM、OpenRouter 或 Vercel AI SDK?这份报告从源码、仓库设计说明和同类框架的边界出发,把“数据怎么流、对象怎么映射、为什么这样选”讲清楚。

in-process library provider-neutral native replay framework comparison 2026-10 快照
01 · Relationship

共享库,不是同一个 harness

Pi 是独立 coding harness;pi-ai 是它的模型层;DSH 只复用 pi-ai,不引入 Pi 的 CLI/TUI/工具。

02 · Data flow

GenerateOptions → Context → StreamChunk

DSH 的 provider-neutral 请求,经 pi-ai 的原生 provider 流,再翻译回 DSH 的块事件。

03 · Choice

要库,不要网关

DSH 的治理在自己的 credential/session/retry 层;它需要的是可嵌入的 TS provider 库。

源码快照:DSH 0.2.1-rc.2;pi-ai 1.4.0(依赖 ^1.1.0) 资料日期:2026-10-25
01 / Relationship

Pi、pi-ai、DSH:到底谁是谁

先把最常见的误解拆掉:dsh-llm-pi-ai 不是 Pi harness,也不是“DSH 内置了 Pi”。它只是 DSH 的一个 adapter,把 pi-ai 这个多 provider LLM 库接进 DSH 的 dsh-llm seam。

Pi harness @earendil-works/pi-coding-agent
独立 coding agent harness:CLI、工具、TUI、扩展、skills、agent core。
使用
→
pi-ai @earendil-works/pi-ai
多 provider LLM 库:provider 目录、认证/OAuth、模型元数据、协议适配、流事件。
←
包装
DSH @deepseek-ai/dsh
独立 coding harness:自己的 agent loop、工具、session、Web/CLI、审批、重试。
Pi

harness 本体

Pi 是 Earendil Works 的 minimal/extensible coding agent;monorepo 里还有 pi-agent-core、pi-tui、pi-durable 等。

pi-ai

模型层

不是 harness,也不是网关;它是被 Pi 和 DSH 共同复用的 provider/LLM 库。

DSH

另一个 harness

DSH 只依赖 pi-ai,不依赖 pi-coding-agent/pi-agent-core;Pi 的 CLI/TUI/工具不会进入 DSH。

一句话

Pi 和 DSH 是并列的 harness;它们共享 pi-ai 这个模型层,但不是 fork,也不是同一个运行时。 dsh-llm-pi-ai 是 DSH 侧的 adapter,负责把 pi-ai 的 Context / AssistantMessageEvent / Model 转成 DSH 的 GenerateOptions / StreamChunk / ReplayEnvelope。

证据:DSH 的 packages/llm/llm-pi-ai/package.json 只声明 @earendil-works/pi-ai,没有 pi-coding-agent 或 pi-agent-core;其 description 明确写的是 “design-verification twin of dsh-llm-deepseek”。

02 / Data flow

一次请求的数据交互流程

DSH 的请求不是“把 messages 直接丢给 pi-ai”。中间有 provider-neutral 预处理、能力校验、凭据解析、图片投影、Context 转换、事件回译和 replay 存储。

先分清两条 adapter 分支

DSH 的 dsh-llm 后面不是只有一个 adapter:dsh-llm-deepseek 直连 DeepSeek Messages(默认 route:deepseek-official / deepseek-account);dsh-llm-pi-ai 通过 pi-ai catalog 接三方 provider(OpenAI / Anthropic / Google / …)。本文的 §02–§04 以 dsh-llm-pi-ai 为主线,DeepSeek 直连分支在同一个 seam 下走另一套 adapter。

1. Agent loop从 session 构造 GenerateOptions,deep-freeze
2. LlmRuntime选 adapter、冻结本次调用、投影 file/image/tool update
3. Adapter解析 snapshot、model、capabilities、credential
4. toPiContextDSH Message → pi-ai Context
5. streamSimplepi-ai provider → 原生 wire
6. toStreamChunksAssistantMessageEvent → StreamChunk
7. BlockAssembler拼 content blocks,记录 assistant message
8. ReplayreplayState 存进 source,下一轮恢复签名/ID

图中的 5–8 步是 dsh-llm-pi-ai 的路径;dsh-llm-deepseek 走 DeepSeek Messages,不经过 toPiContext/toStreamChunks,但共享同一个 dsh-llm seam 和 StreamChunk 契约。

2.1 入口:GenerateOptions

Agent loop 从 session 里取出历史,构造“模型将看到的精确输入”。DSH 的 GenerateOptions 同时包含请求身份、消息、工具和采样控制:

interface GenerateOptions {
  provider: string
  model: string
  reasoningEffort?: ReasoningEffortId
  messages: RequestMessage[]       // system / developer / user / assistant / tool
  system?: string                  // one-shot 调用
  tools?: ToolSchema[]
  toolHistory?: ToolHistory
  temperature?: number
  maxTokens?: number
  stop?: string[]
  sessionId?: SessionId
  purpose?: 'compaction' | 'session-title'
  signal?: AbortSignal
}

messages 里的内容块是 DSH 的 canonical ContentBlock:text、reasoning、image、file、tool-call、tool-addition、tool-removal。这份输入会被 deep-freeze,adapter 只读。

2.2 LlmRuntime:provider-neutral 预处理

在进入 adapter 前,LlmRuntime.adapterStream() 做四类统一处理:

  • 文件投影:file block 永远不直接发给 provider,转成带路径/大小的文本句柄;
  • 图片投影:不支持图片的模型,图片变成文本占位符;支持图片的模型才进入 attachment 解析;
  • 工具更新投影:按模型的 toolUpdate 能力选择 in-history / addition-only / 完整列表;
  • Replay 隔离:如果历史 assistant 的 source.provider 不是当前 adapter 拥有的 provider,就剥掉 replayState,避免跨 adapter 使用 provider 签名。

这一步是 DSH 的“provider-neutral 边界”:所有 provider 看到的输入先被规范化,但 reasoning/cache 等 provider 语义不被强行翻译。

2.3 PiAiAdapter:解析 snapshot、模型、凭据

每个请求会取当前 profiles 的不可变 snapshot(profiles + pi-ai Models collection)。配置变更会构建新 snapshot,不会修改飞行中的请求;这样 prepareCall() 冻结的配置能一直保持到 dispatch。

// 简化自 adapter.ts
const profile = snapshot.profiles.get(options.provider)
const model = snapshot.models.getModel(options.provider, options.model)
const reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning)
const apiKey = await this.config.resolveApiKey(options.provider, profile)
const events = snapshot.models.streamSimple(model, context, {
  apiKey,
  reasoning,
  ...options.temperature !== undefined ? { temperature: options.temperature } : {},
  ...options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {},
  ...options.sessionId !== undefined ? { sessionId: String(options.sessionId) } : {},
  signal: watchdog.signal,
  headers,
  maxRetries: 0, // 重试归 DSH
})

凭据解析是“fail loud”的:如果 profile 明确写了 apiKeyEnv,解析不到就抛 MISSING_CREDENTIAL,不会让 pi-ai 去捡一个不相关的 OPENAI_API_KEY。只有完全没配凭据的 route 才交给 pi-ai 的 provider-native ambient auth / OAuth store。

2.4 toPiContext:DSH Message → pi-ai Context

toPiContext() 把 DSH 的 role/content 结构翻译成 pi-ai 的 Context:

  • 请求级 system + 开头连续的 system 历史 → Context.systemPrompt;
  • 其余 system / developer / assistant / tool / user → pi-ai messages;
  • tool-call → pi-ai toolCall(arguments 从 DSH 的原始 JSON 字符串解析成对象);
  • tool → pi-ai toolResult,toolName 从前一条 assistant 的 tool call 建立 id→name 映射补上;
  • developer 的 tool-addition/tool-removal → pi-ai system 的 toolsAdded/toolsRemoved(或模型不支持时降级);
  • 图片 → pi-ai ImageContent;文件永远只以文本句柄出现。

2.5 pi-ai provider:原生 wire

models.streamSimple() 是 pi-ai 的统一简化入口。它内部按模型的 api 选择协议实现:anthropic-messages、openai-responses、openai-completions、google-generative-ai、bedrock-converse-stream 等。协议差异由 pi-ai 的 provider 层处理,DSH 只看到统一的 AssistantMessageEvent。

2.6 toStreamChunks:事件回译

// 简化映射
text_start      → { type: 'block-start', blockType: 'text' }
text_delta      → { type: 'text-delta', text }
thinking_start  → { type: 'block-start', blockType: 'reasoning' }
thinking_delta  → { type: 'reasoning-delta', text }
toolcall_start  → { type: 'block-start', blockType: 'tool-call' }
toolcall_delta  → { type: 'tool-call-delta', argumentsDelta }
toolcall_end    → { type: 'block-end', block: { type:'tool-call', arguments: JSON.stringify(...) } }
done            → { type: 'usage' } + { type: 'finish', replayState }
error           → { type: 'usage' } + { type: 'finish', reason: error/aborted }

这里有一个重要方向差异:pi-ai 的 tool arguments 是已解析对象,DSH 的 tool-call 保留原始 JSON 字符串。所以 toolcall_end 会重新 JSON.stringify;参数非法时 DSH 会报 MALFORMED_RESPONSE(除非是 length 截断)。

2.7 回到 DSH:BlockAssembler 与 Replay

BlockAssembler 把 StreamChunk 拼成 DSH 的 content blocks;finish.replayState 被存进 assistant message 的 source.replayState。下一次请求只有在同一个 adapter 实例同时拥有历史 provider 和目标 provider 时,才会把 replay state 传给 adapter;否则剥离并降级为 provider-neutral 历史。

03 / Objects

核心数据对象

DSH 和 pi-ai 各有一套完整的类型系统。理解 adapter 的关键,是看清两边的对象如何一一对应,以及哪些字段是“语义损失点”。

DSH

Provider-neutral 词汇

GenerateOptions

provider / model / messages / system / tools / toolHistory / reasoningEffort / temperature / maxTokens / stop / sessionId / purpose / signal

Message + ContentBlock

role: system / developer / user / assistant / tool;block: text / reasoning / image / file / tool-call / tool-addition / tool-removal

StreamChunk

block-start / text-delta / reasoning-delta / tool-call-delta / block-end / usage / finish

ReplayEnvelope

response + blocks:adapter-private 的原生回放元数据,DSH 只存不解释

pi-ai

Provider 原生词汇

Context

systemPrompt / messages / tools

Message

user / assistant / toolResult / system

AssistantMessage

content: text / thinking / toolCall;usage、stopReason、responseId、responseModel、providerThinkingLevel、签名

AssistantMessageEvent

start / text_* / thinking_* / toolcall_* / done / error

Model + Models

provider/id/api/baseUrl/reasoning/input/contextWindow/maxTokens/thinkingLevelMap/compat;Models 提供 streamSimple()

对象映射表

DSH ↔ pi-ai 的对象对应关系
DSHpi-ai转换要点
GenerateOptionsContext + SimpleStreamOptions消息进 Context,采样/凭据/传输进 options
Message / ContentBlockContext.messages / ContentBlockrole 和 block 语义基本对齐,但 toolResult 需要补 name
ToolSchemaToolname/description/parameters 直接映射
StreamChunkAssistantMessageEvent事件一一对应,但 tool arguments 类型不同
TokenUsageUsagepi-ai 把 reasoning 折进 output;cache 只在非零时出现
FinishReasonAssistantMessage.stopReasonstop/toolUse/length/error/aborted 映射;deferred → error
ReplayEnvelopeAssistantMessage 原生字段只保存 responseId / signatures / thoughtSignature / namespace
LlmResolvedModelInfoModelcontextWindow、input、reasoning、thinkingLevelMap、compat

最容易踩的四个转换点

Arguments

原始 JSON 字符串 vs parsed object

DSH 保留模型产出的 raw JSON string;pi-ai 的 toolCall.arguments 是 parsed object。adapter 在 toolcall_end 重新 stringify。非法 JSON 在 DSH 侧是 MALFORMED_RESPONSE。

Tool name

toolResult 需要 toolName

DSH 的 tool 消息只有 toolCallId;pi-ai 的 toolResult 需要 toolName。adapter 从前一条 assistant 的 tool call 建立 id→name 映射补上。

Error

cause 被压平,只能文本分类

pi-ai 把底层 Error 压平成 error.message,丢掉 cause。DSH 的 stream.ts 里有 XXX(pi-ai upstream) 注释,承认只能正则识别 AUTH / RATE_LIMIT / TIMEOUT / TRANSPORT。

Perf

tool 参数流式解析 O(n²)

DSH 对 pi-ai 打 patch,去掉每个 delta 对整个累计 JSON 的重复解析;否则多 MB 参数流会卡事件循环。这是库级集成的真实代价。

04 / Replay

Replay:为什么 DSH 能保留原生签名

DSH 的 durable 内容(text / reasoning / tool-call)是 source of truth;pi-ai 的 replay metadata 只负责恢复“原生保真度”,不是重新存一份 assistant message。

1. pi-ai done拿到完整 AssistantMessage + usage + stopReason
2. toPiReplayState提取 responseId / responseModel / thinking signatures / thoughtSignature
3. DSH 存储写进 assistant.source.replayState
4. 下一轮toPiAssistant 校验并恢复原生 AssistantMessage

Replay envelope 有两半:

  • response:api、provider、model、responseId、responseModel、providerThinkingLevel、stopReason;
  • blocks:逐块的 textSignature、thinkingSignature、redacted、toolCall.thoughtSignature、namespace。
关键设计

如果 replay state 缺失、版本不匹配、provider/model 不匹配或 block 数量/类型不一致,DSH 会把它降级成 provider-neutral 历史,并记 warning,而不是让请求失败。这样既保住了“能跑”,又尽量保住“原生签名”。

这也解释了 DSH 为什么不把“所有 provider 都归一化成 Chat Completions”:一旦归一化,thinking signature / responseId / thoughtSignature 就没有地方存,长时程工具循环的质量会下降。

05 / Why pi-ai

DSH 选 pi-ai 的因素

这一节把“仓库明说的”与“我基于代码结构的推断”分开。前者可以在 DSH 的 README、Agent Note、源码注释里找到;后者是工程判断,不是官方声明。

5.1 仓库/代码明确说到的

Twin adapter

“design-verification twin”

DSH 同时有 dsh-llm-deepseek(直连 fetch)和 dsh-llm-pi-ai(库实现)。两套不同内部实现跑同一个 StreamChunk 契约,用来验证“provider-neutral”不是只适配了 DeepSeek 的假抽象。

Catalog + auth

provider 目录、OAuth、模型元数据

catalog route 继承 pi-ai 的 endpoint、protocol、model catalog;OAuth 登录、credential store、环境变量发现都不需要 DSH 自己为每个 provider 重写。

Narrow protocols

自定义 route 只开 3 种协议

openai-completions / openai-responses / anthropic-messages。Bedrock/Vertex/Azure/Codex 的认证流程无法用“key + baseURL + models”完整表达,所以走各自 catalog provider。

Bundle

narrow runtime imports

dormant 的 dsh-llm-pi-ai 不 import pi-ai aggregate entry,避免把 TypeBox 和数百个模块带进每次启动;协议实现走 api/*.lazy。

Retry

重试归 DSH

pi-ai 调用设 maxRetries: 0;DSH 的 dsh-llm-retry 在 agent step 边界重试。adapter 一次调用就是一次 SDK attempt。

Cache

system reminder fallback

pi-ai 对不支持 mid-conversation system 的模型会把后续 system 拼到初始 prompt,破坏 prefix cache;DSH 改成 <system-reminder> user 消息,保留原生 system 的模型则不动。

Patch

流式 tool 参数性能

DSH 仓库对 pi-ai 的流式 tool-call 参数解析打 patch,去掉每个 delta 的整段 JSON 重复解析(O(n²))。

Replay

durable content 权威

DSH 只存 pi-ai 的原生签名/ID,不存完整 assistant message;跨 adapter 剥离 replay,失效时降级而不是失败。

5.2 我的推断(未在仓库中直接写死)

  1. TS/Node 同栈、in-process:DSH 是 TS 插件系统;pi-ai 是 TS 库,可以直接进进程,不需要像 LiteLLM 那样额外跑 Python 服务。对桌面/CLI/本地优先的 harness,这是决定性因素。
  2. 覆盖成本:要自己接 OpenAI、Anthropic、Google、Bedrock、Vertex、OpenRouter、Groq、Cerebras、xAI、Copilot 等几十家 provider,认证/OAuth/模型目录/流事件都要维护;pi-ai 已经把这些做成 catalog。
  3. 原生协议保真:DSH 的差异化是“provider-neutral 但不丢 provider 语义”;pi-ai 保留 native protocol 和 provider metadata,比 Chat 归一化网关更贴合 DSH 的 replay 设计。
  4. 插件化快照语义:DSH 的 prepareCall() 要冻结一次调用的 adapter generation;pi-ai 的 Models collection 可以整体替换,adapter 用不可变 snapshot 包住,正好匹配。
  5. 不需要网关能力:DSH 不需要中心化 key、LB、guardrails、团队配额;这些是 LiteLLM/Portkey/Bifrost 的强项,但对本地 harness 是额外服务。DSH 自己已经有 credential seam、retry、session、审批。
  6. 生态/许可证:pi-ai 是 MIT,Pi harness 自己 dogfood;DSH 可以读源码、打小 patch,不需要引入商业网关。

5.3 代价与风险

Dependency

上游 + patch 维护

pi-ai 升级要重新验证 patch、错误文本分类、provider 行为;DSH 的 patch 是集成成本的一部分。

Error

错误 cause 丢失

pi-ai 把底层 Error 压平成 message,DSH 只能靠正则识别 401/429/5xx/timeout;provider 改文案就会误分类。

Scope

不是网关

没有 load balancing、fallback、central quota、guardrails;DSH 只做单次调用,路由/重试在更上层。

Drift

catalog 漂移

pi-ai 的模型目录/协议支持变化会影响 DSH 的模型选择;DSH 用 patch/版本 pin 控制。

06 / Frameworks

同类框架:pi-ai 在哪个位置

pi-ai 既不是 LiteLLM Proxy,也不是 OpenRouter,更不是 LangChain。先把“库 / 网关 / 托管 / agent 框架”分开,再比较会清楚很多。

6.1 四类形态

先分类,再比较:不同形态解决的问题不同
类别代表形态适合
进程内多 provider 库pi-ai、Vercel AI SDK、LiteLLM SDK、aisuite、any-llm代码依赖,直接调用 provider嵌入 harness/应用,低延迟,自己控制运行时
自托管 HTTP 网关LiteLLM Proxy、Portkey、Bifrost、TensorZero独立服务,统一 API团队级 key/配额/路由/观测/guardrails
托管网关OpenRouter、Vercel AI Gateway、Cloudflare AI GatewaySaaS 代理快速接大量模型,免运维
Agent 框架LangChain、LlamaIndex、Pydantic AI、Mastra编排/agent 抽象构建应用逻辑,不是模型传输层
DSH 要的是第一类

DSH 是本地优先的 coding harness,自己的治理边界在 credential / session / approval / retry 层;它不需要再套一个中心网关。pi-ai 作为 in-process 库,正好补“多 provider 接入”,又不和 DSH 的运行时抢职责。

6.2 横向对比

代表性框架对比(2026-10;部分数字为厂商自述,具体以官方为准)
框架形态/语言协议策略优点代价/限制DSH 匹配
pi-aiTS 库每个 provider 走 native protocol;统一 Context / eventprovider 目录全、OAuth/认证/模型元数据、类型好、可嵌进程、MIT不是网关;无路由/LB/guardrails;错误 cause 丢失;需维护 patch最匹配
LiteLLMPython SDK + Proxy(新版 Rust core)主要 OpenAI 格式,支持 native passthrough100+ provider、成本追踪、路由/fallback、guardrails、企业功能独立 Python 服务;翻译层可能丢 reasoning/cache;运维复杂服务端可选
Vercel AI SDKTS 库provider packages 走 native API;统一 LanguageModel / stream partsUI/agent 生态强、provider 多、TS 类型好、Apache-2.0更偏应用/UI;默认 Vercel AI Gateway;不是 provider catalog/auth 库可选替代
OpenRouter托管网关主 API 是 OpenAI Chat;另有 Anthropic Messages / Responses(stateless)400+ 模型、路由/fallback、免运维、统一账单托管、额外网络跳、数据合规、无本地/离线可当 route
Portkey自托管/托管网关(MIT)OpenAI-compatible,1600+ 模型guardrails、缓存、路由、观测、企业部署独立服务;翻译层;不是 TS 库团队网关
BifrostGo 网关(Apache-2.0)OpenAI-compatible,10k+ 模型高性能(<200µs)、failover、语义缓存、MCP独立服务;Go 运维;翻译层团队网关
TensorZeroRust 网关 + LLMOps(Apache-2.0)OpenAI-compatible观测/评估/优化/实验一体化偏 LLMOps 平台;独立服务团队实验
aisuitePython 轻量库(MIT)统一 Chat Completions + Agents简单、易学、provider 覆盖功能少、无 gateway/路由;PythonPython 应用
any-llmPython 库(Apache-2.0)单一接口轻量、provider 覆盖、Mozilla 生态无 gateway/路由;PythonPython 应用
LangChain / LlamaIndexPython/TS 编排框架各自 model wrapper生态、RAG/agent 组件不是 wire-level 传输层;抽象重不是同类

6.3 三个关键对比

pi-ai vs LiteLLM

pi-ai:TS 库,嵌进程;provider catalog / auth / model metadata / 原生流事件;无服务、无网关治理。

LiteLLM:Python SDK + Proxy;统一网关、路由、成本、guardrails、企业治理;以 OpenAI 格式为主,支持 native passthrough。

选择:本地/桌面 harness → pi-ai;团队统一入口/配额/审计 → LiteLLM。

pi-ai vs Vercel AI SDK

两者都是 TS 进程内库。AI SDK 更上层,偏应用/UI/agent,默认 Vercel AI Gateway,provider 包很多;pi-ai 更底层,重点是 provider catalog、认证/OAuth、模型元数据、原生流事件。

选择:DSH 已有自己的 agent loop/UI/session,pi-ai 的边界更窄、更贴合 dsh-llm;如果是 Next.js 应用,AI SDK 更顺手。

pi-ai vs OpenRouter / Portkey / Bifrost

这些是网关/服务,不是库:多一跳网络、多一套运维、可能翻译协议;适合团队统一治理,不适合本地优先的 DSH 内核。

选择:DSH 可以把它们当成一个自定义 OpenAI-compatible route,但不会把它们嵌进进程。

pi-ai vs aisuite / any-llm

这两者都是 Python 轻量统一接口,适合 Python 应用快速接多家 provider;但没有 DSH 需要的 TS 类型、provider catalog、OAuth、原生 replay 元数据和进程内插件语义。

选择:Python 应用 → aisuite/any-llm;TS harness → pi-ai/AI SDK。

6.4 决策矩阵

按需求选形态:没有“最好”,只有“边界匹配”
需求首选次选不要选
本地/桌面 coding harness,TS,进程内pi-aiVercel AI SDKLiteLLM Proxy / OpenRouter
团队统一 key、配额、审计、路由LiteLLM Proxy / PortkeyBifrostpi-ai(没有治理层)
快速接 400+ 模型、免运维OpenRouterVercel AI Gateway自建 provider 适配
Python 应用快速统一接口LiteLLM SDK / aisuiteany-llmpi-ai(TS)
LLM 实验/评估/优化TensorZeroLiteLLM + 自建观测纯库
Next.js/React AI 应用Vercel AI SDKAI Gatewaypi-ai(缺少 UI 层)
07 / Conclusion

结论

  1. DSH 的 pi-ai adapter 是“模型接入层”,不是 Pi harness,也不是网关。它把 pi-ai 的 provider/catalog/auth/native stream 接进 DSH 的 dsh-llm,DSH 自己保留 agent loop、工具、session、审批、重试。
  2. 数据流是“双向翻译 + 原生保真”:DSH Message → pi-ai Context → provider wire → pi-ai events → DSH StreamChunk;assistant 的原生签名/ID 通过 ReplayEnvelope 存回 DSH,下一轮再恢复。
  3. 选 pi-ai 的核心因素:TS 同栈、in-process、provider 覆盖、OAuth/模型目录、原生协议保真、MIT、可打 patch;以及“twin adapter”用两套实现验证 provider-neutral 契约。
  4. 不选 LiteLLM/OpenRouter/Portkey/Bifrost 的核心原因:它们是网关/服务,不是库;对本地优先的 DSH 来说多一跳、多一套运维,而且 Chat 归一化会丢 reasoning/cache 语义。
  5. 代价:上游依赖/patch、错误 cause 丢失导致文本分类、catalog 漂移、没有网关级路由/LB;这些由 DSH 自己的 retry/credential/session 层补位。
选型的一句话

要“把模型接进自己的 harness”——选 pi-ai/AI SDK;要“把模型接给整个团队”——选 LiteLLM/Portkey/Bifrost;要“最快接最多模型”——选 OpenRouter;要“做 agent 应用”——选 AI SDK/LangChain。DSH 属于第一种。

来源

版本提示:DSH 仍是开发预览;本文按当前安装的 @deepseek-ai/dsh 0.2.1-rc.2 与 @earendil-works/pi-ai 1.4.0 的包文档/代码核对。框架对比中的“模型数量/性能”含厂商自述,生产前请按锁定版本复核。