DeepSeek Harness 中 Adapter 自治的 maxTokens 默认值设计:defaultMaxTokens 从模型路由到持久请求头的完整链路
DeepSeek Harness 中 Adapter 自治的 maxTokens 默认值设计defaultMaxTokens 从模型路由到持久请求头的完整链路【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness本文基于仓库内的架构决策记录 2026-07-30-adapter-owned-max-token-defaults.md讲解 DeepSeek HarnessEverything is a Plugin 的 LLM Agent 框架如何把「每请求输出 token 上限的默认值」的决策权交给 LLM Adapter 自身而非塞进 Provider 序列化或 Agent Loop 驱动层。读完你可以掌握LlmResolvedModelInfo.defaultMaxTokens的定义、校验与物化链路理解adapterDefaults标记如何让「Adapter 默认值」与「调用方显式值」在持久化的request/header中互不混淆并学会通过llm-deepseek.config.maxTokens调整部署级默认预算。问题背景一个默认值不该放在哪里的三重困境该架构笔记描述的起点是一个看似简单的问题当调用方没有显式传入GenerateOptions.maxTokens时请求到底该带上什么输出上限笔记指出两条直觉路线都有结构性缺陷只在 Provider 序列化阶段兜底如果默认值只加在 DeepSeek 的请求序列化里那么实际发往 Provider 的 wire 请求会携带一个在持久化request/header中不存在的值——日志、审计与重放看到的请求和线上请求不一致把每个 Provider 的默认值写进 Agent LoopAgent Loop 是 provider 中立的驱动层若由它内置各 Provider 的模型策略等于把部署策略与模型策略从 Adapter 中「搬运」进了中立层破坏了「一切皆插件」的职责边界。因此决策是由 Adapter 自己声明默认值。LlmResolvedModelInfo.defaultMaxTokens承载「针对某个精确 provider/model 路由的、由 Adapter 配置的每请求输出上限」LlmRuntime只负责校验并在调用方省略时物化不夹带任何 Provider 特定的策略。核心机制defaultMaxTokens 的定义、校验与物化类型定义defaultMaxTokens是精确路由模型元数据的一部分定义在 types.ts/** Exact-route model metadata resolved by its owning adapter. */ export interface LlmResolvedModelInfo extends LlmModelInfo { /** Provider-owned context capacity when known. */ context?: LlmModelContext /** Adapter-configured per-request output cap materialized when callers omit one. */ defaultMaxTokens?: number /** Adapter-owned selectable reasoning levels when exposed. */ reasoning?: LlmModelReasoningInfo }注意字段注释与笔记措辞一致它是「调用方省略时才被物化的每请求输出上限」而不是模型硬上限。选择省略该字段的 Adapter 即表示「保留 Provider 自己的默认行为」这正是决策中强调的「adapters that preserve provider-owned defaults omit it」。LlmRuntime 的校验在 LlmRuntime.normalizeModelInfo 中Runtime 对 Adapter 返回的defaultMaxTokens做防御性校验const defaultMaxTokens resolved.defaultMaxTokens if (defaultMaxTokens ! undefined (!Number.isSafeInteger(defaultMaxTokens) || defaultMaxTokens 0)) { throw new LlmError( adapter returned invalid default maxTokens for provider ${provider} model ${model}, INVALID_MODEL_MAX_TOKENS, ) }即该字段必须是正的安全整数否则以INVALID_MODEL_MAX_TOKENS错误拒绝——与笔记中「LlmRuntimevalidates it as a positive safe integer」逐字对应。校验通过后该字段随LlmResolvedModelInfo一起被 detached 返回与 Adapter 内部对象解耦。物化只有调用方省略时才生效默认值的物化发生在 resolveCallWithInfoconst defaulted config.maxTokens undefined info.defaultMaxTokens ! undefined ? { ...config, maxTokens: info.defaultMaxTokens } : config三个条件共同保证了优先级语义调用方显式值永远胜出config.maxTokens ! undefined时原样保留Runtime 不做任何夹逼clamping或改写显式请求与 Agent 选项「remain unmarked and therefore win without clamping」Adapter 未发布默认值时不干预info.defaultMaxTokens undefined时配置原样通过Provider 自有默认行为保持不变物化产生的是副本{ ...config, maxTokens: ... }不修改调用方传入的原始对象。prepareCall 与 adapterDefaults 标记让默认值成为持久请求事实笔记中的关键设计是Agent Loop 在记录request/header之前先 prepare 调用因此「哪些字段是 Adapter 默认值补上的」会成为持久请求事实的一部分。这一机制在 LlmRuntime.prepareCall 中实现const resolvedConfig deepFreeze(structuredClone(resolved.config)) const adapterDefaults deepFreezeLlmCallConfigAdapterDefaults({ ...config.reasoningEffort undefined resolvedConfig.reasoningEffort ! undefined ? { reasoningEffort: true } : {}, ...config.maxTokens undefined resolvedConfig.maxTokens ! undefined ? { maxTokens: true } : {}, })标记逻辑精确区分了两种来源物化前的config.maxTokens是undefined而物化后的resolvedConfig.maxTokens有值说明这个值来自defaultMaxTokens于是打上maxTokens: true标记调用方显式传入的值则在物化前后一致不会被打标。返回的PreparedLlmCall是绑定到当前 Adapter 注册的一次性句柄deepFreeze 单次 dispatch 约束保证 header 日志与后续 dispatch 使用的是同一份能力解析结果——从源码结构看注释明确说明这是为了防止 HMR 场景下「一个 Adapter 的能力结果被拼接到另一个 Adapter 上」。Agent Loop 侧的消费切换路由前先清除标记字段在 agent.ts 中Loop 把上一轮持久 header 转换为「下一轮请求的提案」时会先剥离 Adapter 派生值/** Remove adapter-derived values before plugins propose the next request config. */ function requestProposal(header: EpochHeader): LlmCallConfig { if (header.adapterDefaults undefined) return header.config const proposal { ...header.config } if (header.adapterDefaults.reasoningEffort true) delete proposal.reasoningEffort if (header.adapterDefaults.maxTokens true) delete proposal.maxTokens while (true) return proposal }注意真实实现中该函数没有while结构上面最后一行while (true)是笔误请以仓库源码为准其实际行为就是被标记的字段从提案中删除随后「exact-model resolution」会用当前路由的 Adapter 默认值重新物化。这一「先删后补」的顺序保证了笔记描述的核心不变量切换 Provider/模型时新 Adapter 的默认值会重新物化而不会把上一个 Adapter 的派生值误当作显式覆盖沿用到新路由相反会话中显式设置的maxTokens因为从未被打标会持续保留。该行为有测试固化request-reconstruction.spec.ts 对多轮adapterDefaults的持久化与剥离做了断言如第 229、302、336 行附近对header.data.header.adapterDefaults序列的toEqual校验覆盖了「标记字段被持久化后在新提案中消失、显式字段保留」的路径。DeepSeek 原生 Adapter 的实现256,000 默认与 1,000,000 上下文笔记对原生 DeepSeek 部署的结论——「默认发送max_tokens: 256000、默认上下文容量 1,000,000」——可以直接在 llm-deepseek 源码中逐条印证。常量与每模型元数据adapter.ts 定义了两个关键默认常量/** Default combined request/response context capacity. */ export const DEFAULT_CONTEXT_WINDOW 1_000_000 /** Default per-request output-token cap. */ export const DEFAULT_MAX_TOKENS 256_000在 modelInfoFor 中Adapter 为每个精确 provider/model 路由组装LlmResolvedModelInfodefaultMaxTokens与contextWindow的回退链是const contextWindow configured?.contextWindow ?? connection.defaultContextWindow return { ... context: { contextWindow }, defaultMaxTokens: configured?.maxTokens ?? connection.maxTokens, ... }这里对应笔记中两条规则每模型maxTokens优先于 profile 级maxTokensDeepSeekCatalogModel接口adapter.ts中的maxTokens?: number注释明确写着「omission falls back to the profilesDeepSeekConnectionOptions.maxTokens」未列出的直通pass-through模型 id 与未配置容量的条目继承同一 Adapter 级回退对未在 catalog 中登记的模型 idconfigured为undefineddefaultMaxTokens直接取connection.maxTokens即 256,000 默认而contextWindow取connection.defaultContextWindow1,000,000 默认。同时catalog 中两条内置 V4 模型条目在 index.ts 中显式发布了contextWindow: DEFAULT_CONTEXT_WINDOW与笔记「both built-in V4 entries publish that exact capacity」吻合。Cordis 配置侧的校验llm-deepseek/src/index.ts 中插件配置即 Cordis 插件配置对这两个值都做了正整数约束且 profile 级maxTokens的 zod schema 直接以DEFAULT_MAX_TOKENS为默认contextWindow: z.number().step(1).min(1), maxTokens: z.number().step(1).min(1), // profile 级 maxTokens: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER).default(DEFAULT_MAX_TOKENS),配置解析阶段还有二次防御第 303-305 行maxTokens不是正安全整数时抛出llm-deepseek: maxTokens must be a positive safe integer连接选项组装时回退为config.maxTokens ?? DEFAULT_MAX_TOKENS第 384 行。因此「部署可通过llm-deepseek.config.maxTokens改变默认值」这条结论有配置 schema 与运行时解析双重依据。序列化边界effective 值映射为 max_tokens最终 wire 请求在 serialize.ts 生成...options.maxTokens undefined ? {} : { max_tokens: options.maxTokens },由于LlmRuntime在 prepare 阶段已把defaultMaxTokens物化进config.maxTokens序列化时看到的已是「有效值」max_tokens字段必然与持久request/header中的值一致——这正是拒绝「只在序列化处兜底」这一备选方案的直接目的wire 请求不再携带任何请求头中不存在的模型可见值。备选方案对比为什么其他位置都不合适笔记完整记录了四个被否决的备选它们从不同角度框定了这套设计备选方案否决理由工程含义仅在 DeepSeek 序列化处应用默认值Provider wire 会包含一个缺失于持久请求头的模型可见值日志/重放/审计与实际请求必须一致默认值必须发生在「请求事实」形成之前在每个发行应用里设置AgentOptions.maxTokens应用重复 Adapter 部署策略直接 LLM 调用行为不同切换到其他 Provider 后仍残留 DeepSeek 专属上限部署策略属于 Adapter 配置不属于应用代码LlmRuntime.stream()直连路径必须走同一套物化把 256,000 表示为硬模型上限配置值是「期望的请求预算」并非「每个配置端点都会拒绝更大输出」的证据显式调用方保持权威地位系统不做 clamp完全交由 Provider 默认值决定原生 DeepSeek 部署的产品要求是跨兼容端点稳定的 256,000 token 会话预算「保留 Provider 默认」对不发布defaultMaxTokens的 Adapter 仍然是合法行为值得强调的是第三行defaultMaxTokens是请求默认值而非硬上限。resolveCallWithInfo中没有任何 min/max 夹逼逻辑显式传入 300,000 时系统不会替你改回 256,000——「explicit callers remain authoritative」。结论与运维含义综合以上链路这套「Adapter 自治默认值」设计在仓库中的最终形态是默认链路DeepSeek 会话在未显式配置时发送max_tokens: 256000且request/header同时记录该值与adapterDefaults.maxTokens true标记即「值」与「值的来源」都是持久事实优先级链从高到低per-request 显式值 /AgentOptions.maxTokens→ per-model catalogmaxTokens→ profile 级llm-deepseek.config.maxTokens→ 内置默认 256,000路由切换安全requestProposal先删除标记字段、再按当前路由重新物化切换 Provider 不会把 DeepSeek 派生的 256,000 误当成显式覆盖带到新 Adapter预算权衡256,000 的输出预算在「预分配请求输出」的端点上会占用 1,000,000 token 上下文中的很大一块。若你的网关或模型只支持更小输出预算应显式调低maxTokens——笔记的原话是「explicit configuration is preferable to an undocumented provider fallback」显式配置优于未文档化的 Provider 兜底扩展方式其他 Adapter 保持既有行为直到它们「有意发布defaultMaxTokens」即该字段是纯增量能力不改变未声明默认值的 Adapter 的语义。如果你要为自己的 Adapter 接入同类能力只需在resolveModel/prepareCall返回的LlmResolvedModelInfo中发布正整数defaultMaxTokensRuntime 的校验、物化、标记与 Loop 的剥离逻辑即自动生效——这正是「Everything is a Plugin」在请求参数层的一个具体实例。中文对照版决策记录见 2026-07-30-adapter-owned-max-token-defaults.zh.md。【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

TiXL Debug Protocol 实现指南:让外部 Agent 通过 TCP 驱动实时图形编辑器

TiXL Debug Protocol 实现指南:让外部 Agent 通过 TCP 驱动实时图形编辑器

TiXL Debug Protocol 实现指南:让外部 Agent 通过 TCP 驱动实时图形编辑器 【免费下载链接】t3 TiXL is an open source software to create realtime motion graphics. 项目地址: https://gitcode.com/GitHub_Trending/t3/t3 TiXL(t3&#xff09…

2026/9/19 5:57:39 阅读更多 →
工控协议故障驱动学习法:从Modbus到S7/FINS的现场排障实战

工控协议故障驱动学习法:从Modbus到S7/FINS的现场排障实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 5:57:39 阅读更多 →
React Native与鸿蒙跨平台快递柜系统开发实践

React Native与鸿蒙跨平台快递柜系统开发实践

1. 项目背景与核心价值在快递物流行业,末端配送环节的效率直接影响用户体验和运营成本。传统快递柜系统往往存在几个痛点:取件码生成规则单一、包裹状态更新不及时、查询功能简陋、表单交互体验差。这个React Native鸿蒙跨平台项目正是为了解决这些实际问…

2026/9/19 5:57:39 阅读更多 →

最新新闻

Win11更新后音频设备消失?从驱动到服务的全面修复指南

Win11更新后音频设备消失?从驱动到服务的全面修复指南

1. 问题定位:为什么Win11一更新,音频设备就"失踪"说实话,每次Windows大版本更新或者累积更新之后,音频设备消失这事儿,几乎是我见过最多的高频问题了。无论是刚买的笔记本,还是用了两三年的老台式…

2026/9/19 6:49:02 阅读更多 →
Chrome DevTools MCP:让AI自己打开F12调试网页的完整指南

Chrome DevTools MCP:让AI自己打开F12调试网页的完整指南

调试网页这件事,过去十年基本离不开一个动作:打开 Chrome 的 F12,切到 Elements 看结构,切到 Network 看请求,切到 Console 看报错,再手动点几下页面复现问题。现在多了一个新选项:让 AI 自己打…

2026/9/19 6:49:02 阅读更多 →
WT系列语音芯片发声链路、PWM/DAC与3.3V输出调参实战

WT系列语音芯片发声链路、PWM/DAC与3.3V输出调参实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 6:49:02 阅读更多 →
企业AI小程序落地指南:从需求收敛到上线的关键决策

企业AI小程序落地指南:从需求收敛到上线的关键决策

收到这个需求的时候,客户最常说的一句话往往是:“我们想做个AI小程序,但具体做成什么样,你们先拿方案,最好一个月上线。”企业AI应用小程序开发最致命的地方就在这里——你永远在跟"不确定性"赛跑。模型选型…

2026/9/19 6:49:02 阅读更多 →
Hermes Agent零基础实战:安装配置与多场景自动化应用

Hermes Agent零基础实战:安装配置与多场景自动化应用

1. Hermes Agent到底是什么,为什么值得零基础入手先说个实际的感受。我接触自动化工具这些年,从最早的按键精灵、Selenium脚本,到后来的Playwright、Appium、Jenkins流水线,每个工具都有各自的脾气。有的安装环境能把人逼疯&#…

2026/9/19 6:49:02 阅读更多 →
first-contributions 项目:Git 与开源初贡献完整实战指南(Fork 到 Pull Request 全流程)

first-contributions 项目:Git 与开源初贡献完整实战指南(Fork 到 Pull Request 全流程)

first-contributions 项目:Git 与开源初贡献完整实战指南(Fork 到 Pull Request 全流程) 【免费下载链接】first-contributions 🚀✨ Help beginners to contribute to open source projects 项目地址: https://gitcode.com/gh_…

2026/9/19 6:48:02 阅读更多 →

日新闻

BP神经网络时序预测:滑窗长度与多窗口平均策略

BP神经网络时序预测:滑窗长度与多窗口平均策略

简介:面向机器学习、深度学习与数据建模学习者的一份完整研究文献,聚焦BP神经网络在农业产量预测中的应用。文档以1980—2018年全国棉花产量为样本,系统讲解数据归一化处理、激活函数原理、多层神经网络结构搭建及训练流程,展示敏…

2026/9/19 0:00:30 阅读更多 →
Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

上个月调一个Deformable DETR模型,在单卡上要跑将近两天。第二天早上我下意识打开终端翻日志,发现loss从凌晨两点就开始往上爬,一路从0.8涨到1.35,整整六个小时没人发现。那六个小时的训练不仅白跑,还霸占着卡——等于…

2026/9/19 0:00:30 阅读更多 →
OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南 【免费下载链接】opencloud 🌤️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign. 项目地址: htt…

2026/9/19 0:00:30 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/19 3:59:36 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/19 3:53:08 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/19 4:02:43 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/16 22:31:27 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/15 21:39:18 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/16 22:32:59 阅读更多 →