← 返回目录

第 8 卷

第 8 / 43 卷作者:Un-named日期:

tui(需插件)终端 UIdsh --profile tui(未内置,需安装插件)

一个 profile 目录长这样(`~/.dsh/profiles/<name>/`):

<!-- [style] 目录树代码块统一补 text 语言标签 -->

profiles/web/ ├── package.json# 插件依赖 + dsh.profile 清单(bundles 顺序) ├── cordis.patch.yml# 你的补丁层:挂载/覆盖插件的声明 ├── cordis.yml#(生成的)合成

配置 ├── pnpm-workspace.yaml └── node_modules/

**加载顺序**(官方文档原文):内置 bundle(`dsh-base` → `dsh-web-app`)→ profile 的 `cordis.patch.yml` → 用户级 `~/.dsh/cordis.patch.yml` → `--patch` 覆盖层。

内置 Agent 预设:标准 / PTC / 极简 / 创造

profile 解决"**以什么形态启动**",Agent 预设解决"**以什么方式跑 Agent**"。dsh 内置了四种 Agent 预设(源码在官方仓库 `apps/cli/config/agent-presets/` 的

`agent.cordis.yml`),每种预设默认加载不同的插件集合:

预设定位加载内容典型场景
标准默认预设完整工具组合日常Agent工作
PTC(Code代码驱动工具链程序化工具调用—复杂多步骤工具工
mode)—模型生成一段代作流

码组合多轮工具调用

极简基准测试仅bash +一个文件最小环境下的模型
编辑工具基准测试
创造插件开发用检查当前运行时、构建与测试新的插
在内存中试验件组合

Cordis 插件、组合新预设

**PTC 命名澄清** ([#1052](https://github.com/deepseek-ai/deepseek-harness/discussions/1052) 评论

区社区详解):PTC = **Programmatic Tool Calling(程序化工具调用)**。官方中文站只用了「PTC 模式」这个营销名(官方站点原文:"PTC 模式通过模型生成的一段代码组合多轮

工具调用"),官方英文页面对应 **Code mode**;「Programmatic Tool Calling」的完整扩写出自社区详解([cnblogs 指南](https://www.cnblogs.com/sing1ee/p/22455466)),

与源码实现完全吻合。机制与收益详见第 8 章 8.3.1;四种运行模式总览见第 2 章 2.4.1。

3.2 挂载一个插件:两处改动

以挂载社区插件 `dsh-better-sidebar` 为例(真实操作):

**① `package.json` 加依赖**(`link:` 指向本地源码,或用 npm 包名):

}

**② `cordis.patch.yml` 加挂载行**:

  • insert:- id: better-sidebarname: dsh-better-sidebar

**③ 安装并重启**:

cd ~/.dsh/profiles/web && pnpm install dsh web# 重启后生效

> 💡 插件默认是**按会话隔离**的(`better-sidebar` 的布局/标签按会话持久化)——挂载是 profile 级,但状态是会话级。

3.3 host 半与 client 半:一个包,两副面孔

**"半"(half)= 插件的半边实现**。一个插件可以拆成两个部分分别跑在不同环境:**host 半**跑在 Node 进程(有文件系统/命令/服务权限),**client 半**跑在浏览器(web UI,

只能做界面和交互)。两者通过 cordis 服务桥接(`ctx.provide`/`ctx.get`)。

**一个插件可以只有 host 半**——无 UI 需求的插件(工具类、服务类)只需 host 半:不声明 `dsh.client`、不写 `exports["./client"]` 即可(第 4 章模板就是纯 host 插件)。反之也可

以只有 client 半(见 3.5 Q4),但 client 半无法直接访问文件系统,需要 host 半桥接。

插件可以同时携带两个运行半:

半边运行位置职责示例
host半Node进程工具、服务、事applyctx注册工具
件、文件系统、进/服务

程

client 半浏览器(webUI、交互、DOMpackage.json 的 profile)dsh.client 声明 +

src/client/

`package.json` 里如何声明 client 半:

{"dsh": {"client": {"platform": "web","inject": [],// 需要注入的 client 服务(通常为空;官方示例即 [])"immediately": true// 是否随 web 启动立即加

载}},"exports": {".": { "types": "./lib/types/index.d.ts", "default":

"./lib/index.js" },"./client": { "types": "./lib/types/client/index.d.ts", "default":

"./lib/client.js" }} }

  • host 半:`exports["."]` → `apply(ctx)`(cordis 插件主体)
  • client 半:`exports["./client"]` → 浏览器侧的 `apply(ctx)`
  • `inject`:声明需要的服务(cordis 依赖注入)

3.4 扩展点:改行为优先找钩子,别 fork 核心

官方原则(CONTRIBUTING/AGENTS.md 明示):**"Plugins, not loop changes: new behavior goes on documented extension points"**。新手最常见的错误是改核心 loop

——正确做法是用扩展点。

已确认的常用扩展点(后续章节逐一实战):

扩展点位置用途
agent/request waterfallagent-loop每次模型请求前改配置

(provider/model/ reasoningEffort/tools)

——提速插件示例用这个

agent/request-erroragent-loop请求失败时干预(官方 compaction 插件用这个

做上下文溢出恢复)

conversationEvents.regiclient runtime订阅/注入对话事件 ster(tool/call、turn/start

等)

ctx.slots.injectclient ui-slots在界面槽位注入 UI(如 turnTail 显示产物文件

行)

settings 服务dsh-settings注册用户可配置的命名空间(设置页自动渲染)

ctx.provide / ctx.getcordis跨插件提供服务

**怎么用(以 `agent/request` 为例)**——在插件的 `apply(ctx)` 里注册:

import type {} from '@deepseek-ai/dsh-agent'// 类型增强 export function apply(ctx: any) {

ctx.on('agent/request', async (request, next) => {//每次模型请求前触发:可以改provider
/ model / reasoningEffort / toolsrequest.reasoningEffort = request.tools?.length > 3 ?
'low' : request.reasoningEffort//必须await next()并return其结果(它是Promise,把修
改后的请求交给下一环) return await next(request)}) }

> 关键:`agent/request` 是 **waterfall**(链式)——每个插件都要 `await next()` 并 return 结果;漏 `await` 或没 return,下游收不到你的修改(见 3.5 常见坑)。

3.5 常见坑(真实踩过)

依赖解析坑

坑现象解决帖号
rc.1依赖断裂pnpm install报官方rc.1时代多个—
@deepseek-ai/ds包从未发布;升级
h-type-到^0.1.0-rc.6线

meta@0.0.1-rc.1 404

全局全局设过临时取消全局#139https://
突(如config --global --deepseek-ai/
Codex/Claudeunsetdeepseek-
全站分卷索引 · 43 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷
  27. 27第 27 卷
  28. 28第 28 卷
  29. 29第 29 卷
  30. 30第 30 卷
  31. 31第 31 卷
  32. 32第 32 卷
  33. 33第 33 卷
  34. 34第 34 卷
  35. 35第 35 卷
  36. 36第 36 卷
  37. 37第 37 卷
  38. 38第 38 卷
  39. 39第 39 卷
  40. 40第 40 卷
  41. 41第 41 卷
  42. 42第 42 卷
  43. 43第 43 卷