1. 为什么要在本地搭一套 dsh 运行环境DeepSeek Harnessdsh是 DeepSeek 开源的智能体运行框架底层基于 Cordis 插件框架构建核心范式是 Everything is a plugin——模型适配器、工具注册表、会话日志、agent 循环本身都是插件全部通过 Cordis 挂载到共享的 ctx 上从配置层面就能整体替换。它适合需要在本地搭建可扩展智能体运行环境的开发者尤其是想自己控制插件加载顺序、替换模型 provider、或者把 agent 循环换成自定义实现的人。dsh 的运行入口是npx deepseek-ai/dsh web默认 Web UI 监听http://127.0.0.1:3080。语言栈是 TypeScriptESM加 Python SDK子进程驱动包作用域为deepseek-ai/dsh-pkg其中deepseek-ai/cordis是每个包的 peerDependency许可证 MIT。我试过从零跑通 dsh 的插件加载链路最容易卡住的不是代码本身而是配置骨架没搭对profile 里 bundles 的顺序、cordis.patch.yml 的层级覆盖、以及模型适配器指向哪个 API 通道。这篇就围绕这三件事交付一份可复制的config.toml与settings.json骨架并给出通过 TaoToken 统一 Key/API 通道接入的验证动作目标是一次性跑通插件加载与运行链路。需要先明确一点dsh 当前处于 developer preview 阶段SESSION_FORMAT_VERSION为 0后端拒绝旧的磁盘格式架构细节可能随版本变化。所以下面的配置骨架以仓库最新docs/与AGENTS.md为准遇到字段对不上时优先查文档。2. 前置准备TaoToken 统一 Key 与 API 通道dsh 的 LLM 能力族在packages/llm它拥有对话与流式类型并通过ctx.llm暴露LlmRuntime。适配器契约里registerAdapter(providers, adapter)负责注册适配器实例stream()是唯二必须方法。也就是说你只要让适配器指向一个兼容的 API 通道就能把模型请求接进来。TaoToken 在这里扮演的是统一 Key/API 通道的角色一个 Key 覆盖多家模型API 地址固定省去在 dsh 里为每个 provider 单独配凭证的麻烦。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 不加 UTM。操作顺序建议这样先到控制台创建 Key。打开 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 登录后在 API Keys 页面新建一个 Key复制出来。这个 Key 后面会写进 dsh 的凭证引用里不要直接硬编码在config.toml中。然后确认模型对话通道可用。在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 选一个你想用的模型记下模型名。dsh 的适配器需要 provider 名和模型名两个字段provider 填taotoken模型名按你选的填。如果你打算长期跑编码类 agent 或做 Agent 编排可以看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite API Keys 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。注意dsh 的凭证走ctx.credentials引用机制配置里只写引用名真实 Key 放在环境变量或凭证存储里。这样 reload / teardown 时不会把密钥写进会话日志。3. 可复制的 config.toml 与 settings.json 骨架dsh 的运行时组合由 Profile 和 Bundle 两层构成。Profile 存储在 Harness home 的命名组合列出堆叠的 bundles、树外插件以及用户自己的cordis.patch.ymlBundle 是 Cordis 配置行及其挂载代码的发行格式每个包在自己的package.json用dsh字段声明dsh.profile和dsh.bundle。分层应用顺序对空入口列表是profile 中dsh.profile.bundles顺序的每个 bundle → profile 的cordis.patch.yml→ home 级cordis.patch.yml→--patch覆盖层。你可以用dsh --profile web --dump-config查看机器实际启动的树。3.1 config.tomlprofile 与 bundle 骨架下面这份config.toml放在$DSH_HOME/profiles/local-dev/下作为自定义 profile 的起点。它显式列出三层 bundle并在最后挂一个模型适配器插件。# $DSH_HOME/profiles/local-dev/config.toml # dsh 自定义 profile本地可扩展智能体运行环境 [profile] name local-dev # 第一层必须是 dsh-base模型适配器、工具、持久化、沙箱与审批策略、设置、凭证、遥测 bundles [ dsh-base, dsh-web-app, dsh-headless, ] # 树外插件本地开发的适配器与工具扩展 [[plugins]] name dsh-llm-taotoken path ./plugins/llm-taotoken enabled true [[plugins]] name dsh-tool-local-shell path ./plugins/tool-local-shell enabled true # 凭证引用只写引用名真实 Key 从环境变量读取 [credentials] llm_provider_ref TAOTOKEN_API_KEY # 模型适配器配置provider 名 模型名 [llm] provider taotoken model deepseek-chat base_url https://taotoken.net/api stream true # 沙箱与审批策略本地开发建议先放宽生产再收紧 [sandbox] backend none approval_policy ask # 会话持久化JSONL 后端便于 replay 与调试 [session] backend jsonl format_version 0几个字段的取舍说明。bundles的顺序不能乱dsh-base必须第一它提供模型适配器、工具、持久化、沙箱与审批策略、设置、凭证、遥测dsh-web-app增加浏览器应用dsh-headless增加一个一次性运行器无 server。如果你只跑 headless 任务可以去掉dsh-web-app。[llm]段里的base_url指向 TaoToken 的 API 基址provider填taotokenmodel按你在模型对话页选的填。stream true对应适配器契约里的流式要求——StreamChunk是封闭判别联合以assertNever收尾包含block-start、text-delta、reasoning-delta、tool-call-delta、block-end、usage、finish等变体。[sandbox]段本地开发先设backend none等链路跑通再换成bwrap、Landlock或Seatbelt。approval_policy ask对应工具执行管线里的tools/pre-execute瀑布允许 / 拒绝 / 询问三态。3.2 settings.json用户设置与凭证引用settings.json放在$DSH_HOME/下管的是用户级设置和凭证引用不涉及插件树结构。{ version: 0, credentials: { TAOTOKEN_API_KEY: { source: env, envVar: TAOTOKEN_API_KEY } }, llm: { defaultProvider: taotoken, defaultModel: deepseek-chat, requestTimeoutMs: 120000, maxRetries: 2 }, session: { persistChunks: true, deriveMessagesOnLoad: true }, tools: { preExecutePolicy: ask, guards: [] }, telemetry: { enabled: false } }credentials段用source: env加envVar的方式引用环境变量这样config.toml里只出现引用名TAOTOKEN_API_KEY真实值在 shell 里 export。session.persistChunks true对应持久化契约——每个事件包括assistant/chunk都无损持久化seq连续所有event.data必须 JSON 可序列化Session.append在源头校验。tools.guards是空数组对应ToolGuard的 scope 感知最终预分发策略。它的返回类型没有allow结果undefined保留 waterfall 决策返回reason只能收窄权限所以后续 listener 无法把拒绝翻转为允许。这个设计保证了策略的单调性。3.3 环境变量与启动在 shell 里设置 Key然后启动 profileexport TAOTOKEN_API_KEY你的_TaoToken_Key export DSH_HOME$HOME/.dsh # 首次使用自定义 profile 需经 dsh plugin 创建 dsh plugin --profile local-dev init # 启动 web 形态 dsh --profile local-dev web # 或者跑一个 headless 任务 dsh --profile local-dev --profile headless 列出当前目录的 TypeScript 文件dsh plugin --profile name pnpm args会转发到 profile 目录的 pnpm用来管理插件。web 与 headless profile 首次使用从模板自动初始化其他 profile 须经dsh plugin创建。4. 验证请求跑通插件加载与运行链路配置写完后先别急着发模型请求按下面三步验证链路。4.1 检查配置树dsh --profile local-dev --dump-config这条命令打印机器实际启动的树。重点看三处bundles是否按dsh-base→dsh-web-app→dsh-headless顺序展开plugins里两个树外插件是否 enabledllm.base_url是否指向https://taotoken.net/api。如果dsh-base不在第一层启动会直接失败——Misconfiguration fails loud是 dsh 的不变量自包含时加载即失败否则在最早可解析点失败绝不静默跳过缺失引用。4.2 验证模型适配器启动 web 形态后打开http://127.0.0.1:3080在对话里发一句简单请求。观察终端日志应该能看到StreamChunk的流式输出先是block-start然后一串text-delta最后block-end加usage加finish。适配器契约里有几条硬性要求验证时对照检查usage必须在finish之前tool-call参数保持 raw JSON 字符串两种错误路径同一LlmFailure类型一次适配器调用等于一次 provider 尝试上下文溢出统一CONTEXT_WINDOW_EXCEEDED码空完成是 retryable 错误携带 app-attribution header。如果请求返回但内容为空先看是不是finish先于usage到达这通常意味着适配器没按契约顺序发 chunk。4.3 验证工具执行管线发一个需要调用工具的请求比如让它读一个文件。工具执行管线是tools/pre-execute允许 / 拒绝 / 询问→ 已注册单调 guards →tools/executearound-dispatch 包装→tools/post-execute检查 / 替换结果→ 可选的finalizeContent→tools/result不可变权威结果。只有tools/execute视图可替换 signal。在approval_policy ask下你应该在 UI 里看到审批提示。批准后工具执行结果经tools/result落成不可变权威结果同时写入会话日志的tool/call和tool/result事件。4.4 验证会话日志与 replay会话是类型化SessionEvent的 append-only 日志是 agent 整个交互历史的唯一事实源。LLM 消息历史是从日志派生deriveMessages()的从不单独存储replay 即同一事件的再派生。# 查看会话日志文件 ls $DSH_HOME/sessions/ # 用 headless 跑一个任务观察日志写入 dsh --profile local-dev --profile headless 读一下 README.md 的前 20 行跑完后检查 JSONL 文件应该能看到turn/start、step/start、user/message、assistant/chunk、assistant/message、tool/call、tool/result、step/end、turn/end等事件按seq单调递增排列。SurfaceEventType只有user/message、assistant/message、tool/result三类产生消息携带surfaceOpappend或{op:replace,start,end}deriveMessages()据此派生模型可见历史。5. 本篇常见错排查5.1 启动报 bundle 顺序错误现象dsh --profile local-dev web启动即失败提示 bundle 依赖缺失。原因dsh-base不在bundles第一层。dsh-base提供模型适配器、工具、持久化、沙箱与审批策略、设置、凭证、遥测是每个 profile 的第一层。处理把dsh-base移到bundles数组首位重新--dump-config确认。5.2 模型请求 401 或凭证找不到现象对话返回认证失败或日志提示credential ref not resolved。原因config.toml里llm_provider_ref TAOTOKEN_API_KEY引用的环境变量没 export或settings.json里envVar名字对不上。处理确认 shell 里echo $TAOTOKEN_API_KEY有值确认settings.json的credentials.TAOTOKEN_API_KEY.envVar与 export 的变量名完全一致。Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 管理。5.3 流式输出中断或空完成现象请求发出后没有text-delta直接finish或中途断开。原因适配器没按StreamChunk契约发 chunk或base_url写错导致请求打到不兼容端点。处理确认base_url https://taotoken.net/api检查适配器是否在finish之前发usage空完成在契约里是 retryable 错误看maxRetries是否生效。5.4 工具调用被静默跳过现象模型请求了工具但执行管线没触发也没有审批提示。原因tools/pre-execute瀑布里某个 listener 没调用next()短路了整条链。Waterfall 语义是next()委托给下游不调用即短路。处理检查settings.json的tools.guards和已注册的tools/pre-executelistener确认每个 listener 在非决策路径上都调用了next()。5.5 会话日志 replay 报格式错误现象加载旧会话时提示SESSION_FORMAT_VERSION不匹配。原因dsh 当前SESSION_FORMAT_VERSION为 0无兼容承诺后端拒绝旧磁盘格式。处理删掉旧会话文件重新跑或把settings.json里session.format_version对齐当前版本。这是 pre-release 格式的预期行为不是 bug。5.6 插件 reload 后注册残留现象reload 插件后旧的工具 schema 或提示段还在。原因注册没走ctx.effect()/ctx.on()disposer 没在卸载时解除。Registrations are effects是贯穿代码库的工程纪律。处理检查插件里所有贡献是否都通过ctx.effect()/ctx.on()安装确保返回的 disposer 在插件卸载时自动解除。6. 下一步把链路接进你的工作流链路跑通后接下来是把它接进实际工作流。如果你主要做编码类 agent 或长期运行的 Agent 编排建议看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它更适合持续调用场景。接入细节和字段说明在接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。Key 的创建和轮换在 API Keys 页 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。想先验证模型对话是否正常可以直接在模型对话页试 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。dsh 的扩展点机制里新增行为挂在已文档化的扩展点上改循环本身要更新docs/architecture.md。加模型 provider 在ctx.llm注册适配器加模型面能力在ctx.tools注册给某会话不同能力集就组合一个 agent preset加 shell 执行注册ctx.shell后端加持久终端注册ctx.terminals后端加dsh-tool-terminal加人类命令在ctx.commands注册加后台工作在ctx.jobs注册。事件域分三类Session 事件是持久事实追加到日志并广播session/eventAgent 事件agent/*携带实时 AgentCapability 事件把策略与适配器挂到 seamfs/*、tools/*、telemetry/*无需 import 循环。最后提醒一句Model-visible means logged是运行时不变量任何进入模型请求的内容都必须能从会话日志重建新增模型可见输入等于必须新增一条会话事件。这条约束在扩展插件时最容易踩写新工具或新提示段时记得同步加事件。
企业数字化 ERP 产品动态
相关推荐
校园跑腿系统开发:ThinkPHP与Laravel双框架实践 1. 项目背景与需求分析校园跑腿服务系统是近年来在高校中兴起的一种O2O服务模式。作为一名长期从事校园信息化建设的开发者,我发现学生们对于代取快递、代买餐食、代办手续等跑腿服务需求旺盛。传统的QQ群、微信群接单方式存在信息混乱、支付不安全、服务无保障等问… · 2026/9/23 2:18:59
标普永华数据中心2026最新实战搭建:3步解决文档痛点 标普永华数据中心2026最新实战搭建:3步解决文档痛点 官方文档太长抓不住重点,这是很多开发者在接触新系统时的第一反应。尤其是面对像标普永华数据中心这样复杂的企业级应用,几千页的PDF看得人头皮发麻。别慌,今天咱们不啃书,直接上手。结合20… · 2026/9/23 2:18:59
用 Fresh + Nushell + coreutils 重塑 Windows 命令行体验 Windows Terminal 用了这么多年,我一直在想一个问题:为什么 Windows 下的命令行工具链总是让人感觉差一口气?PowerShell 功能很强,但写起来动词冗长、管道传的是对象却不直观;想用ls、grep、find这些 Unix 命令&#x… · 2026/9/23 2:18:59
JsonSurfer实战:流式解析超大JSON,内存占用降低10倍 去年在做日志清洗任务时,碰到一个特别头疼的场景:线上导出一份接近 2GB 的 JSON 日志文件,里面记录了用户一整天的行为明细。用以前惯用的方式JsonNode整体加载解析,程序刚跑起来内存就飙到 6GB 多,几分钟后直接 OOM。… · 2026/9/23 3:07:26
Formily 2.x 业务逻辑管理指南:effects 与 reactions 的定位、选择与最佳实践 Formily 2.x 业务逻辑管理指南:effects 与 reactions 的定位、选择与最佳实践 【免费下载链接】formily 📱🚀 🧩 Cross Device & High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/Rea… · 2026/9/23 3:07:20
内部域名钓鱼:邮件认证疏漏与子域名接管引发的信任危机 上个月帮一家企业做反钓鱼应急时,看到一封让我后背发凉的邮件:发件人写着IT-Support他们自己的域名.com,正文是“您的企业邮箱存储空间已满,请在两小时内点击下方链接重新认证,否则将暂停收发邮件”。点进去的页面几乎… · 2026/9/23 3:07:13
通勤蓝牙耳机怎么选?五款主动降噪TWS实测横评与避坑指南 通勤两年,我前前后后换过七八副蓝牙耳机,从几十块的杂牌到两千多的旗舰都折腾过。2026年这波新品本来没打算跟,结果身边好几个朋友一直问我“通勤到底买哪副”,干脆把市面上口碑比较靠前的型号集中收了五款,每天早晚高… · 2026/9/23 3:07:07
Agent核心能力解析与行业应用场景全景梳理 刚接触科研时,光是各种免费文献网站的推荐就让我眼花缭乱,每个都试一下,结果哪个都没用透,效率极低。直到我静下心来深度测试,才发现真正能称为“天花板”的网站,只需要四个。尤其是第一个,它能… · 2026/9/23 3:07:07
3个关键点搞懂幻灯片母版是什么,从入门到精通 3个关键点搞懂幻灯片母版是什么,从入门到精通 官方文档翻了三遍还是晕头转向?别急,今天把【幻灯片母版是什么】拆解成三块硬骨头,10分钟从入门到精通。你公司项目里是怎么处理的?欢迎评论。 一句话原理:母版是PPT的DNA… · 2026/9/23 3:07:07
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29