dsh-ask-form:在 DeepSeek Harness 里用结构化表单向用户提问

前言

在 DeepSeek Harness(DSH)里,智能体常用内置的 ask_user_question 向用户确认选项:一次一页、扁平选项列表,多字段、带条件或校验时,往往要拆成多次调用,回传结果也多是字符串,后续逻辑还要自己解析。

社区插件 dsh-ask-form(维护者 Zekilou,分类:工作流)提供工具 ask_form:一次调用呈现整表,支持 14 种字段类型、跨字段条件与校验、校验失败时的定向重问,以及带类型的 JSON 答案。在无法渲染表单的环境会自动退化为内置问答流,与「一切皆插件」的 DSH 用法一致。目录页见 SkillHub,源码见 GitHub。

这是什么

dsh-ask-form 是面向 DeepSeek Harness 的社区插件包。Host 侧注册 ask_form,Client 侧在 Web UI 渲染居中浮层表单;Bundle 为 index.js 与 client.js 两半,无需额外构建步骤。当前 package 版本为 0.4.0,许可证 MIT。

与内置工具的对比如 README 所述:内置 ask_user_question 是逐题展示的选项列表;ask_form 增加字段类型、跨字段约束与一次提交,并在不支持渲染的界面上 degrade 到内置流程。

核心功能

字段类型与返回值

支持 14 种字段类型:confirm、single、multi、text、longtext、number、integer、date、tags、scale、slider、ranking、matrix、budget。

校验与展示相关能力包括:

  • 条件显示:visible_if
  • 校验:validate(白名单表达式语言,不使用 eval)、pattern、max_length、min / max、sum_to
  • 定向重问:仅重问未通过校验的字段,最多 max_rounds 轮

各类型结果在 Host 侧解码为对应结构,例如 scale / slider / number → 数字,ranking → 有序数组,matrix → {row: choice},budget → {option: number},tags → 字符串数组。

访谈包与扩展

内置访谈包:requirement-intake、design-choice、release-gate、incident-intake,可通过 pack_args 调整。

single、multi、tags 默认允许自由文本「Other」;设置 allow_other: false 可关闭。mode: "script" 可在 Web UI 渲染自定义 React 元素,并应声明 script.fallback 供其他界面使用;Script 模式失败时会明确报错,而不是静默降级。

运行方式概要

Host 半部通过既有 ctx.userQuestions 接缝注册工具:将表单编译为普通 AskUserQuestionItem[],任何 answerer 仍可作答;Client 半部在 conversation.composer 链上低优先级注册,仅当问题携带本插件 intent.kind 时渲染整表并回传 JSON 信封。无本插件渲染器的界面仍会把每个字段当作普通问题,结果中 renderer 为 "generic"。

安装与启用

前提:Harness profile 需具备 plugin_manager 工具(web profile 已包含)。

  1. 在 Harness 中让智能体安装,或通过 plugin_manager 执行:
action: install_bundle
target: github:Zekilou/dsh-ask-form

若使用本地目录,将 target 换为该目录的绝对路径,例如 /absolute/path/to/dsh-ask-form。

  1. 重新加载 Harness Web 页面一次,以便客户端 bundle 注册(client.js 负责表单界面)。
  2. 安装完成后,ask_form 与 ask_user_question 并列可用。

插件在 当前 DSH 进程权限 下运行;安装前请自行审阅 仓库源码 与许可证(MIT)。

典型用法

一次工具调用即一张表单;列表类字段中,第一项按惯例为推荐选项。

自定义表单示例:

{
  "title": "Runtime decision",
  "intro": "Pick the runtime and weight the criteria.",
  "fields": [
    { "name": "runtime", "type": "single", "label": "Runtime",
      "options": ["Node 22 (Recommended)", "Bun", "Deno"] },
    { "name": "needs_wasm", "type": "confirm", "label": "Do you need WASM?",
      "visible_if": "runtime == 'Bun'" },
    { "name": "weights", "type": "budget", "label": "Criteria weights (sum 100)",
      "options": ["Performance", "Ecosystem", "Footprint"], "sum_to": 100 },
    { "name": "priority", "type": "ranking", "label": "Priority order",
      "options": ["Ship fast", "Stay small", "Be portable"] },
    { "name": "scores", "type": "matrix", "label": "Score each dimension",
      "rows": ["Performance", "Cost"], "options": ["High", "Medium", "Low"] }
  ],
  "notes": true
}

使用预制访谈包:

{ "pack": "requirement-intake", "pack_args": { "topic": "cache layer" }, "notes": true }

返回结构包含类型化值与来源信息,status 取值为 answered、incomplete、cancelled、aborted、no_answerer、unavailable、script_error 之一。示例:

{ "status": "answered", "rounds": 1, "renderer": "form",
  "values": { "runtime": "Bun", "needs_wasm": true,
              "weights": { "Performance": 50, "Ecosystem": 30, "Footprint": 20 },
              "priority": ["Be portable", "Ship fast", "Stay small"],
              "scores": { "Performance": "High", "Cost": "Low" } },
  "notes": "…" }

适用场景与注意

适合:需求 intake、设计选型、发布门禁、事故 intake 等需要多字段、条件分支、数值约束(如 budget 求和)且希望 Agent 直接消费 JSON 的工作流。

兼容性与 UI 行为(摘自 README):

  • Host 需要 ctx.tools 与 ctx.userQuestions;Client 需要 conversation.composer 链及 shell 中的 react-dom。
  • 实现基于 @deepseek-ai/dsh-* 的 0.2.0-rc.2 时代 API,后续可能变动。
  • 表单为居中模态层,点击遮罩不关闭、Escape 不取消,避免误触丢失半填内容。
  • 10 秒内若答案未回到 Host,界面会重新启用按钮并提示,避免长时间挂起。

本地验证(无需 monorepo 与浏览器):

node tests/host.test.mjs
node tests/client.test.mjs

SkillHub 等社区目录为独立站点,与 DeepSeek / 幻方无官方从属关系;星标等统计以目录页为准(当前 GitHub 星标为 0)。

小结

dsh-ask-form 把「向用户问一组结构化问题」收敛为单次 ask_form 调用:类型化字段、条件、校验与 JSON 答案,Web 端有专用渲染,其它界面仍可走内置问答。需要时可从 SkillHub 目录页 进入说明,在 GitHub 查看 README、THIRD_PARTY_NOTICES 与 Issue。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜