跳到主要内容

不打开融合云应用中心也能部署?用 licloud-cli 把融合云发布流程搬到终端

· 阅读需 6 分钟
Bowen Zhang
本文作者

一句话摘要: 把“登录租户 → 找流水线 → 触发构建 → 选制品 → 发布应用 → 查状态”这条应用中心流程,收敛成 licloud-cli 的几条命令;该人工确认的地方保留确认,该页面配置的地方不强行自动化。

如果你还不熟悉如何使用融合云应用中心完成应用部署,可以先阅读:融合云应用中心通用部署流程

本文对应的 CLI 版本文档:融合云应用中心CLI部署流程

每次发布,为什么总要在应用中心里点一圈

一个服务第一次部署到融合云,真正花时间的通常不是写 Dockerfile,而是把一串页面操作完整走完:

  • 先找到正确租户,再找到正确代码库;
  • 仓库下可能有多条流水线,不能随便挑一条;
  • 构建成功了,还要确认镜像进入了正确制品库;
  • 发布时要选对应用、组件、环境和镜像;
  • 环境变量、端口、域名、探针又散落在不同配置页面;
  • 失败后还要回头看构建日志、发布状态和组件实例。

这些步骤并不神秘,但它们有一个共同特点:信息多、重复高、选错代价大

所以我最近把这条流程换了一个入口:不再把“应用中心页面”当成唯一入口,而是先用 licloud-cli licloud-agent 把能命令化的部分跑起来。

一句话说清 licloud-agent 是什么

licloud-agent 不是一个本地 Codex,也不是一个普通的 REST 命令集合。它更像是融合云已经部署好的云端 CI/CD Agent 客户端:你在终端里用自然语言描述意图,CLI 把请求、租户、会话和认证信息交给融合云 Agent,再由云端 Agent 调用流水线、制品、应用和发布能力。

PowerShell

licloud-cli

融合云云端 CICD Agent

构建流水线 / 制品库 / 应用 / 组件 / 发布服务

它和自己写一个 chatbot Agent 的思路是相似的:都有自然语言、会话、工具调用和多步执行;区别在于,licloud-agent 的 Prompt、工具和 Agent Loop 由平台维护,你通过 CLI 使用它,不需要自己实现一套 CI/CD 工具注册系统。

先装好 CLI,再开始部署

安装入口:

在 AI Market 查看 licloud-cli

安装后检查:

licloud-cli version
licloud-cli --help

首次登录融合云:

licloud-cli auth login

检查登录状态并查看租户:

licloud-cli auth status
licloud-cli tenant list

记住目标租户的 tenantId。后续 licloud-agent 请求都要带上:

--tenant-id <tenant_id>

PowerShell 里要把自然语言整体放在双引号中。反引号 ` 只用来换行,不要用它包住查询内容。

一次部署到底怎么跑

第一步:先确认代码和 Dockerfile

在项目目录检查 Git 状态:

git remote -v
git status
git log --oneline -10

融合云 Agent 查询流水线时,建议使用 HTTPS Git 地址,并确认以 .git 结尾:

SSH: git@gitlab.chehejia.com:group/repo.git
HTTPS: https://gitlab.chehejia.com/group/repo.git

Dockerfile 至少确认三件事:

  • 服务监听 0.0.0.0,不能只监听 127.0.0.1
  • 容器端口和应用实际监听端口一致;
  • CMDENTRYPOINT 指向真实启动命令。

没有合适的 Dockerfile 时,可以让 Agent 帮忙生成或更新,但入口文件、端口和启动命令仍要自己确认。让 AI 生成 Dockerfile 不等于免掉构建前检查。

第二步:先查流水线,别默认选最新

licloud-cli licloud-agent "查询仓库 https://gitlab.chehejia.com/group/repo.git 的构建工程和关联流水线" --tenant-id <tenant_id>

一个仓库存在多条流水线很常见。不要默认选择第一条或最新一条,优先按下面顺序判断:

  1. 项目已有 .robot/build_config.yaml 记录的流水线;
  2. 流水线的 artifactKey 与目标组件绑定的 artifactKey 一致;
  3. 仓库只有一条流水线;
  4. 无法判断时,让人根据流水线绑定组件选择。

需要进一步确认时:

licloud-cli licloud-agent `
"查询流水线 <pipeline_name> 的详细信息,包括构建阶段、Dockerfile 和分支" `
--tenant-id <tenant_id>

这一步看起来慢一点,但比“构建成功后才发现制品不能发布”省时间得多。

第三步:没有流水线就创建,已有的优先复用

licloud-cli licloud-agent `
"创建流水线,语言是 <language>,仓库 https://gitlab.chehejia.com/group/repo.git,分支 <branch>,使用源码中的 Dockerfile,路径是 ./Dockerfile,并将构建镜像存储到制品库" `
--tenant-id <tenant_id> `
--request-id <uuid>

如果只是 Dockerfile 需要调整,优先更新现有流水线,不要重复创建:

licloud-cli licloud-agent `
"更新流水线 <pipeline_name> 的 Dockerfile 内容为:<dockerfile_content>" `
--tenant-id <tenant_id> `
--request-id <uuid>

--request-id 是有副作用操作的幂等键:网络超时时,重试必须使用同一个值;用户主动发起新一轮操作时,才生成新的值。

第四步:触发构建并查询状态

建议使用已经确认过的 commit:

licloud-cli licloud-agent `
"运行流水线 <pipeline_name>,使用 <commit_id> commit" `
--tenant-id <tenant_id> `
--session-id <session_id> `
--request-id <uuid>

继续查询构建状态:

licloud-cli licloud-agent `
"查询构建状态" `
--tenant-id <tenant_id> `
--session-id <session_id>

构建期间不要反复触发同一流水线。构建失败时,直接把问题交给 Agent 诊断:

licloud-cli licloud-agent `
"诊断构建失败原因,并给出 Dockerfile 或流水线修复建议" `
--tenant-id <tenant_id> `
--session-id <session_id>

第五步:发布应用和组件

构建成功后,发布到可用的非管控环境:

licloud-cli licloud-agent `
"把刚才构建的镜像发布到 <environment> 环境,应用名为 <app_name>,组件名为 <component_name>" `
--tenant-id <tenant_id> `
--session-id <session_id> `
--request-id <uuid>

如果应用或组件不存在,Agent 可以按上下文自动创建。发布流程通常会串起:

  • 选择构建制品;
  • 创建应用和组件;
  • 创建发布泳道;
  • 配置端口运维特征;
  • 写入环境变量运维特征;
  • 触发 Kubernetes 发布。

第六步:环境变量不要塞进 Dockerfile

运行时变量建议通过 --env-vars 传入:

licloud-cli licloud-agent `
"把刚才构建的镜像发布到 <environment> 环境" `
--tenant-id <tenant_id> `
--session-id <session_id> `
--env-vars '[{"name":"APP_ENV","value":"test"},{"name":"PORT","value":"8080"}]' `
--request-id <uuid>

敏感值在执行前确认,不能写进 Git、Dockerfile 或普通日志。后续发布确认、环境选择和跨 session 续轮命令,也要继续携带完整的 --env-vars,否则配置可能没有带到发布流程里。

第七步:查询发布状态并诊断

licloud-cli licloud-agent `
"查询 <app_name> 的 <component_name> 在 <environment> 环境的发布状态" `
--tenant-id <tenant_id>

遇到问题时:

licloud-cli licloud-agent `
"诊断 <app_name> 的 <component_name> 在 <environment> 环境的发布问题" `
--tenant-id <tenant_id>

它真正省下来的是什么

1. 少点页面,不是少做判断

CLI 把查询、创建、构建、发布串起来了,但租户、分支、流水线、制品和环境的判断依然重要。自动化最怕的不是多点几下,而是把错误的制品发布到错误的组件。

2. 把“记住上次怎么发”变成配置

建议在项目中保存 .robot/build_config.yaml,记录:

version: '1.0'
deployMethod: build-and-deploy
app:
tenantId: <tenant_id>
appName: <app_name>
componentName: <component_name>
artifactKey: <artifact_key>
pipeline:
name: <pipeline_name>
artifactKey: <artifact_key>
gitUrl: https://gitlab.chehejia.com/group/repo.git
branch: <branch>

其中最关键的是:

pipeline.artifactKey == app.artifactKey

这条关系能避免下次重新部署时选错流水线。

3. 把失败处理也纳入流程

构建失败、发布失败不是流程之外的异常,而是流程的一部分:先查状态,再诊断,再决定更新 Dockerfile、复用流水线还是回到页面处理。

哪些事情还不要强行 CLI 化

目前不建议把下面几项默认当成 CLI 已经完全覆盖:

  • 生产环境和管控集群发布;
  • 域名申请,以及“跨域”“强制 HTTPS 及重定向”等插件配置;
  • HTTP 探针的具体路径、初始延迟等细节;
  • CPU、内存、副本数等组件资源配置;
  • 分支自动构建、准入镜像分支和高级发布触发节点;
  • Pod、容器日志、健康检查、页面和业务接口的最终验证。

一句话:CLI 适合做主流程,页面适合做高风险配置和最后确认。

最短命令清单

# 登录和租户
licloud-cli auth login
licloud-cli auth status
licloud-cli tenant list

# 查询应用
licloud-cli licloud-agent "我有哪些应用" --tenant-id <tenant_id> -o table

# 查询流水线
licloud-cli licloud-agent "查询仓库 <git_url> 的构建工程和关联流水线" --tenant-id <tenant_id>

# 查询构建状态
licloud-cli licloud-agent "查询构建状态" --tenant-id <tenant_id> --session-id <session_id>

# 查询发布状态
licloud-cli licloud-agent "查询 <app_name> 的发布状态" --tenant-id <tenant_id>

最后检查一遍

  • CLI 已登录,租户 ID 正确;
  • 代码已推送,分支和 commit 已确认;
  • Dockerfile、端口和启动命令正确;
  • 选择的流水线和 artifactKey 能对应目标组件;
  • 构建成功且镜像进入制品库;
  • 构建/发布操作使用固定 request-id
  • 环境变量通过 --env-vars 传入;
  • 发布状态和实例状态正常;
  • 域名、探针、资源和高级发布配置已人工复核;
  • 健康检查、页面或业务接口验证通过。

最后一句: 应用中心没有消失,它只是从“每次都要手点的主入口”,变成了“CLI 主流程之外的高风险确认台”。

延伸阅读

飞书 Playwright + Doc Parser 文档下载

· 阅读需 3 分钟
Bowen Zhang
本文作者

必需前置条件

本技能是 Playwright MCP + Doc Parser MCP 的组合实现,二者缺一不可:

  • Playwright MCP:复用已登录的飞书浏览器会话,读取 Wiki 目录树、节点层级和 Wiki token。
  • Doc Parser MCP:解析飞书文档正文、下载 Markdown 及图片。批量下载阶段必须调用其 submit_and_download_with_images 能力。

使用前必须先安装并配置 Doc Parser MCP。安装参考: https://li.feishu.cn/wiki/HoSbwwOt7iLGlZkPGKQcsTNin0f

如果 Doc Parser MCP 未安装、未配置或不可用,应先停止下载并提示用户完成安装;不要改用 lark-cli、飞书 OpenAPI、手工复制或其他解析方式替代。

适用范围

使用本技能把飞书 Wiki 下的全部或指定文档下载到本地,并保留知识库原有层级。目录读取必须通过 Playwright MCP 完成,文档解析和下载必须通过 Doc Parser MCP 完成。

工作流程

  1. 复用 Playwright MCP 中已经登录飞书的浏览器会话。不要随意新建未登录浏览器;如果页面跳到登录页,先重新连接已登录会话。
  2. 打开用户提供的 Wiki 地址,等待左侧目录树完成渲染。只处理用户指定 Wiki 子树,不要把其他空间或搜索结果混入任务。
  3. 从 DOM 收集目录节点的标题、层级位置和 Wiki token。优先使用以下选择器:
    • 节点:div.workspace-tree-view-node
    • 标题:.workspace-tree-view-node-content
    • 层级:data-node-pos
    • 标识:data-node-uid 中的 wikiToken
  4. 只展开目标节点的后代。记录每个节点的原始 pos、标题、token 和父子关系;不要只依赖当前可见文本,因为折叠节点可能尚未出现在 DOM 中。
  5. 根据 data-node-pos 生成本地目录。常见位置如 2,0,0,0 应从索引 3 开始映射,前面的 Wiki 根节点索引不应创建成本地目录。每篇文档使用独立目录,Markdown 和图片保存在该目录内。
  6. 先安全删除本次目标输出目录,再开始全量刷新。确认解析后的绝对路径位于用户指定根目录内,禁止删除其他路径。
  7. 对每个节点调用 Doc Parser 的 submit_and_download_with_images
    • resourceUrihttps://<飞书域名>/wiki/<wikiToken>
    • outputDir:该节点对应的本地目录
    • pollInterval:通常为 5 秒
    • timeout:按文档大小设置,至少覆盖正常解析和图片下载时间
  8. Doc Parser 通常会在 outputDir 下创建 docs-* 临时目录。任务成功后,将临时目录中的最终内容移动到节点目录的预期位置,并删除临时目录;失败时保留错误信息,不把临时目录当作最终结果。
  9. 所有节点完成后执行结果校验,汇总成功、失败、重复名称、缺少 Markdown、图片数量和残留临时目录。

目录映射规则

  • 使用 pos 的路径索引建立父子关系,而不是按遍历顺序猜测目录。
  • 同一父节点下出现同名文档时,按稳定顺序命名为 标题标题 (2)标题 (3);后缀只作用于真正同名的兄弟节点。
  • 不能因为递归遍历了很多子节点,就把父目录错误命名为 标题 (10)
  • 不能把不同节点合并到同一个目录,也不能静默覆盖同名文档。
  • Windows 文件夹名中的非法字符统一替换为 _,同时保留原始标题用于日志和校验。
  • 每个文档目录至少应包含一个 Markdown 文件;图片应保留为相对路径,避免 Markdown 中出现失效的临时绝对路径。

Playwright 读取示例

const nodes = await page.locator('div.workspace-tree-view-node').evaluateAll(items =>
items.map(node => ({
pos: node.dataset.nodePos || '',
uid: node.dataset.nodeUid || '',
title: node.querySelector('.workspace-tree-view-node-content')?.textContent.trim() || ''
}))
);

const tokenFromUid = uid => uid.match(/wikiToken=([^&]+)/)?.[1] || '';

实际执行时应先确认目录已展开、节点数量稳定,再保存 pos、标题和 token。若 token 不在 data-node-uid,点击对应文档后从当前地址提取 /wiki/<token>,仍然只通过 Playwright 完成。

失败处理

  • 登录失效:停止提交下载任务,重新连接已登录 Playwright 会话后再继续。
  • 单篇文档失败:记录 pos、标题、token、目标目录和错误,继续处理其他节点,最后集中重试失败项。
  • 目录数量异常:重新展开目标子树并重新采集,不要依据不完整列表执行全量删除或下载。
  • 出现重复目录或覆盖迹象:停止后续写入,检查同名兄弟的稳定后缀和 pos 映射,再从干净目标目录重跑。
  • Doc Parser 超时:提高该节点的 timeout 后重试;不要把未完成的 docs-* 目录标记为成功。

完成校验

至少检查以下项目:

  • Playwright 采集的文档节点数与成功下载的 Markdown 数量一致,或明确列出失败节点。
  • 每个预期节点都有正确的本地目录,目录层级与 pos 映射一致。
  • 同名文档均有稳定后缀,且没有误覆盖、误合并或父目录异常后缀。
  • Markdown 中的图片引用有效,统计图片总数并抽查相对路径。
  • 目标根目录下没有残留 docs-*、日志、临时下载目录或空的错误目录。

最终报告简要列出输出根目录、节点总数、成功/失败数、Markdown 数、图片数和需要人工处理的节点。

潮汐账本(Neon 版本)

· 阅读需 2 分钟
Bowen Zhang
本文作者

基于 Neon 官方 Vercel Marketplace 模板迁移的个人记账 Web 应用。

技术组合:Next.js 16 + Vercel + Neon Postgres + Drizzle ORM + Better Auth。项目保留原有的移动端优先账本界面、可用的金额键盘、账单本地解析和导入预览;认证与数据访问已替换为 Better Auth 会话和服务端 Neon API,不依赖 Supabase。

当前功能

  • 响应式首页、账户、计划和报表界面;
  • 支出 / 收入 / 转账记账面板,数字、小数点、退格、清空与保存可用;
  • Better Auth 邮箱 + 密码注册、登录与会话;
  • 首次访问账本 API 时自动建立“日常账本”、微信/支付宝/现金账户和基础分类;
  • 手动记账通过 POST /api/ledger 写入 Neon;首页从 GET /api/ledger 读取真实流水、收入、支出、结余和最近流水;
  • 微信/支付宝 CSV、XLSX、ZIP 文件在浏览器本地解析并预览,原始文件默认不上传;
  • Drizzle migration 已生成,包含 Better Auth 的用户/会话表和账本领域表。

目录说明

src/lib/auth/ Better Auth 配置与生成的认证 schema
src/lib/db/ Neon + Drizzle 数据库连接
src/features/ledger/schema.ts 账本、账户、分类、流水、预算、导入批次表
src/features/ledger/server.ts 默认账本初始化与服务端数据库操作
src/app/api/ledger/ 受 Better Auth 会话保护的账本 API
src/features/importers/ 微信/支付宝/通用账单本地解析
drizzle/ 由 Drizzle Kit 生成、需要应用到 Neon 的 migration

Neon 初始化

  1. 在 Neon 创建一个项目,并创建 development 分支;
  2. 从 Neon 的 Connection Details 获取 pooled DATABASE_URL
  3. 复制 .env.example.env.local,并填写:
DATABASE_URL="postgresql://..."
BETTER_AUTH_SECRET="至少 32 个随机字符"
BETTER_AUTH_BASE_URL="http://localhost:5001"

PowerShell 生成本地开发密钥:

[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))
  1. 安装依赖并应用 migration:
npm install
npm run db:migrate
npm run dev
  1. 打开 http://localhost:5001,先创建账号,再登录并记录第一笔账。

Vercel 部署

在 Vercel 项目中安装 Neon Integration 并连接 Neon 的 production/main 分支。然后在 Vercel 的 Production、Preview、Development 环境中配置:

DATABASE_URL=
BETTER_AUTH_SECRET=
BETTER_AUTH_BASE_URL=

Production 的 BETTER_AUTH_BASE_URL 必须是实际线上地址,例如:

BETTER_AUTH_BASE_URL="https://你的实际域名"

每个 Neon 分支使用独立连接串。推荐:

main 正式数据
development 本地开发
preview-* 功能 / Vercel Preview 验证

数据库变更工作流

不要手工修改已经应用到 Neon 的 drizzle/*.sql 文件。后续改数据结构时:

修改 Drizzle schema
→ npm run db:generate
→ 审查 drizzle/ 下新生成的 SQL
→ 先在 Neon development 分支执行 npm run db:migrate
→ 验证后再应用到 main

下一阶段

  • 让月历和趋势图完全按真实 Neon 流水聚合;
  • 补齐分类管理和预算管理;
  • 将账单导入确认结果批量写入 transactions,并实现交易号去重、批次撤销;
  • 为 Preview 部署自动创建/绑定 Neon 分支。

Vanna Fuxi SQL(伏羲数据问答)

· 阅读需 2 分钟
Bowen Zhang
本文作者

基于已部署的 Vanna AI SQL 问答服务(伏羲环境)接口:

  • POST https://vanna-ai-sql-api-ontest.inner.chj.cloud/ask

当用户询问“伏羲上的数据”时(例如“我想查伏羲上的张博文准驾等级”“帮我查伏羲里某人的驾驶证信息”),使用本 skill 调用该接口并整理结果后回复用户。

触发场景(给模型看的)

当满足以下任意条件时,优先考虑使用本 skill:

  • 用户明确提到“伏羲”“伏羲上的数据”“伏羲系统”“Vanna SQL 问答”等。
  • 用户用自然语言问与驾驶/准驾等级/人员车辆信息等相关的问题,并你知道这些数据在伏羲库里。

示例触发语句:

  • “我想查伏羲上的张博文准驾等级”
  • “帮我看看伏羲里某个驾驶人的违规记录”
  • “用 Vanna 那套 SQL 问答帮我看下这个人近期的驾驶情况”

调用方式

使用 exec 工具调用 Node.js 脚本:

python {baseDir}/scripts/ask.py "<自然语言问题>"

其中:

  • <自然语言问题> 直接使用用户的问题文本,例如:
    我想查伏羲上的张博文准驾等级

脚本会:

  1. https://vanna-ai-sql-api-ontest.inner.chj.cloud/ask 发送 POST 请求。

  2. 请求体 JSON 结构遵循后端 QuestionRequest 模型:

    {
    "question": "我想查伏羲上的张博文准驾等级",
    "visualize": false,
    "allow_llm_to_see_data": true,
    "model": null
    }
  3. 得到形如 QuestionResponse 的 JSON:

    • success: 是否成功
    • question: 实际问句
    • sql: 生成并执行的 SQL
    • data: 查询结果(列表,元素为对象)
    • explanation: 对 SQL / 结果的解释(如果有)
    • 其他辅助字段(visualization, data_markdown, error, execution_time 等)
  4. 将完整 JSON 输出到标准输出。

对话流程建议

  1. 检查用户问题是否属于伏羲数据范围:

    • 如果只是一般业务咨询,不需要查库,则按普通对话处理。
    • 如果需要真实数据(例如“准驾等级”“近半年违章次数”等),用本 skill。
  2. 调用脚本:

    python {baseDir}/scripts/ask.py "<用户原始问题>"
  3. 读取脚本输出的 JSON,按以下规则总结回答给用户(用中文):

    • 如果 success == false 或有 error 字段:
      • 告知用户“伏羲查询失败”,简要给出错误信息(避免泄露敏感内部栈信息)。
    • 如果 success == truedata 有内容:
      • 简要说明:你已经调用伏羲 SQL 问答接口并成功返回结果。
      • 若有 sql 字段且非空,请把生成的 SQL 展示给用户(可用代码块包裹)。
      • 结合 datasql/explanation,提炼用户最关心的信息:
        • 对于“准驾等级”类问题,只强调相关字段(例如某人的准驾等级、证件状态等)。
        • 如有多行数据,说明筛选条件(例如按最新记录、或者全部罗列)。
    • 尽量用自然语言解释,必要时可附上一小段表格或项目符号列表。
  4. 如有歧义(例如伏羲数据里有多个同名“张博文”):

    • 向用户说明存在同名记录。
    • 给出区分字段(如身份证号尾号、所属部门等),请用户补充信息后再调用一次接口。

注意事项

  • 本 skill 假定远端接口已经在伏羲环境正确配置并可访问。
  • 如遇网络故障 / 5xx 等错误,先向用户说明是“后端服务不可用或网络异常”,再视情况建议稍后重试。
  • 不要在对话中泄露完整内部 URL 日志,只说明是调用了“伏羲 SQL 问答接口”。

DeepSeek Harness 必装的 10 个插件

· 阅读需 8 分钟
Bowen Zhang
本文作者

截至2026年8月15日,Oh-My-DSH目录已收录精选插件 1117个,监测生态仓库 1521个,累计获得Star 301295 颗。

今天这篇文章,我就从众多插件里,挑出10个最值得装的,希望对你会有所帮助。

一、先搞懂Harness的插件怎么装

在聊具体插件之前,我们先花2分钟搞清楚怎么装插件。

Harness的插件安装只有一条命令:

dsh plugin --profile web add "github:owner/repo#ref"

比如装一个视觉插件:

dsh plugin --profile web add "github:liustack/modlens#main"

这条命令会从GitHub拉取插件代码,通过dsh.bundle声明自动启用它。安装完成后,重启dsh web服务并刷新页面,插件就生效了。

一个重要的坑:启动Web UI时必须加上--patch参数,否则很多插件和技能不会生效。完整命令:

npx @deepseek-ai/dsh web --patch

另外,官方建议插件仓库打上#dsh标签,这样社区目录才能自动收录。想找更多插件,可以直接在GitHub搜索dsh-plugin话题。

下面开始正式推荐。

二、插件1:ModLens

它给纯文本模型装上一双眼睛。

仓库:liustack/modlens | Star:905+

DeepSeek本身是纯文本模型,最大的短板就是看不了图。你贴一张报错截图、丢一个UI设计稿,它只能对着文字干瞪眼。

ModLens的README第一句就是"Give a text-only model sight"。

装上之后,图片可以直接粘贴进聊天框,它通过一个原生的modlens_read_image工具,把图转成结构化文本证据,再喂给DeepSeek作答。

核心思路是:DeepSeek还是那个纯文本模型,但凭空多了双眼睛。视觉模型把图像内容"翻译"成文字,纯文本模型再接着处理——就像请了个会看图的朋友在旁边给你念。

安装命令(注意必须锁版本号,别用@latest):

dsh plugin --profile web add "@liustack/modlens@3.17.2"

场景:贴报错截图让AI分析、丢UI设计稿让AI还原、识别流程图中的文字信息。

三、插件2:dsh-web-ui

它从毛坯到精装,一站式全家桶。

仓库:zhu1090093659/dsh-web-ui | Star:1013+

如果只让装一个插件,我会选dsh-web-ui。

默认的dsh web界面就是个纯聊天框,用久了你会觉得它"太素了"。

装上这个插件集之后直接变精装房——任务看板、Git图谱、右侧面板、移动端UI、宠物、实时Token统计、皮肤中心,一套全给齐

最让我惊喜的是任务看板(dsh-task-board):五列看板——待规划/待办/进行中/已完成/已失败。卡片能直接交给真实DSH会话去执行,跑完自动更新状态,还支持cron定时任务。

安装命令

dsh plugin --profile web add "github:zhu1090093659/dsh-web-ui#main"

装完之后,左侧边栏多了任务看板、Git图谱、Token统计等面板,整个界面从"毛坯"变成了"精装"。

场景:所有场景。这是Harness的"基础设施级"插件,装了不亏。

四、插件3:dsh-better-sidebar

它把WebUI变成Codex风格的工作台。

仓库:omdsh-dev/DSH-better-sidebar | Star:684+

如果你习惯用Codex或Claude Code的界面风格,dsh-better-sidebar就是给你准备的。

这个插件给Harness的WebUI加了一个侧边栏工作台,支持文件查看/编辑、终端、Git、子代理,还有可扩展的Tab。

装完之后,整个界面跟Codex几乎一模一样。

安装命令

dsh plugin --profile web add "github:omdsh-dev/DSH-better-sidebar#main"

dsh-better-sidebar vs dsh-web-ui:前者更像一个完整的工作台布局,侧重文件树、终端、Git这些开发工具;后者更像一个功能集合包,侧重任务看板、皮肤、宠物这些增强功能。

两个可以一起装,互不冲突——better-sidebar管布局,web-ui管功能。

场景:习惯IDE风格界面的开发者,想在浏览器里获得类似Codex的体验。

五、插件4:dsh-TUI

它把Harness搬回终端。

仓库:ccch1mneyyy/dsh-TUI | Star:793+

这是dsh中最火的插件之一。

官方没有推出任何CLI或TUI形式,所以TUI只能通过插件来扩展。

装上之后执行:

dsh --profile cc-tui

就可以进入DeepSeek Harness的全屏终端界面了。常用的命令基本都涵盖了。

dsh-TUI vs dsh-better-sidebar:better-sidebar是给WebUI补一个工作台,dsh-TUI则是直接把整个交互搬回终端

平时习惯在浏览器里看文件树、预览Markdown,就装better-sidebar;已经在日常离不开Claude Code、Codex CLI这种风格的,就装dsh-TUI。

安装命令

dsh plugin --profile web add "github:ccch1mneyyy/dsh-TUI#main"

场景:终端爱好者、习惯CLI工作流的开发者、想在远程服务器上跑Harness的场景。

六、插件5:deepseek-harness-desktop

它把Harness变成桌面App。

仓库:anywhere-labs/deepseek-harness-desktop | Star:4745+

这是最近最火的Harness插件之一。

官方没有提供桌面端,社区把这个缺口补上了。

核心功能:把DeepSeek Harness打包成Electron桌面应用,自动启动和管理本地Harness服务,集成系统托盘+桌面窗口。

最爽的一点是:无需装Node.js、无需敲命令。双击图标就能跑起来。

注意:这是社区项目,不是DeepSeek官方桌面端。目前主要支持macOS和Windows。插件市场、手机远程这些能力还在后续规划里。

安装方式:直接去GitHub Releases下载对应平台的安装包,双击安装即可。

场景:不想装Node.js、不想敲命令的开发者,或者想在系统托盘里随时启动Harness的用户。

七、插件6:dsh-at-file

它让引用文件,像Codex一样丝滑。

仓库:omdsh-dev/dsh-at-file

这是我在Codex中见过的功能——通过@的方式引用文件。

装上之后,在对话输入框中输入@,会自动弹出工作区文件列表供你选择,选中的文件内容会自动附加到提示词中。

不用再手动复制粘贴文件内容了。

安装命令

dsh plugin --profile web add "github:omdsh-dev/dsh-at-file#main"

场景:需要频繁引用项目文件进行对话的场景。

装了之后,Harness在文件引用这个体验上就追平了Codex。

八、插件7:dsh-agent-teams

它能让多智能体团队协作。

仓库:NanmiCoder/dsh-agent-teams

安装这个插件后,任何会话只需一句自然语言(例如"用AgentTeams调研一下XX"),即可驱动一个多智能体团队协作完成目标,并在Web GUI右上角实时看到团队活动面板。

工作流程:创建团队(队长=当前会话Agent)→拉成员(可续聊子代理)→拆任务并声明依赖→成员间直接收发消息(邮箱直达+唤醒,无队长中转)。

安装命令

dsh plugin --profile web add "github:dsh-external/dsh-agent-teams#main"

注意:本仓库不公开,github:安装依赖本机git对dsh-external/dsh-agent-teams的读取权限。

场景:需要多Agent协作的复杂任务,比如市场调研、技术选型分析、多维度报告生成。

九、插件8:dsh-plan-execute

它能让双模型路由,规划和执行分离。

仓库:dsh-external/dsh-plan-execute

这个插件的思路非常聪明:规划用推理模型,执行用经济模型

复杂任务先让推理模型做规划和拆解,生成的子任务再交给经济模型去执行。

规划阶段的思考质量高,执行阶段的成本低——脑子和手脚分开用

安装命令

dsh plugin --profile web add "github:dsh-external/dsh-plan-execute#main"

装完之后,Web设置页会多出"规划/执行模型"的配置行。

场景:复杂任务需要高质量规划,但不想让执行过程烧太多Token。

这是"降本增效"的典型插件。

十、插件9:dsh-context-doctor

它让你看清模型的"上下文账单"。

仓库:Zhenyu98/dsh-context-doctor

很多人不知道,大模型每次请求背着多少上下文——系统提示词、技能目录、工具schema全部累加在一起,每一轮都在烧Token。

dsh-context-doctor让你看清这笔账单。它逐项量化指令链/技能目录/工具schema的Token成本,自动检测重复与冲突,给出可执行裁剪建议。

Web端提供圆环面板可视化展示,同时提供context_audit工具供Agent调用。全程只读,不影响任何配置。

安装命令

dsh plugin --profile web add "github:Zhenyu98/dsh-context-doctor#main"

场景:Token消耗异常的排查、Agent上下文优化、成本敏感型项目的精细化管理。

十一、插件10:dsh-reverse-skill

它里面包含85个安全研究技能包。

仓库:dhicoc/dsh-reverse-skill

一个包含了85个SKILL.md的技能路由包,覆盖逆向工程、授权渗透测试与安全研究等领域。

如果你在做安全相关的工作,这个插件能让你快速获得一整套方法论和工具链。

安装命令

dsh plugin --profile web add "github:dhicoc/dsh-reverse-skill#main"

场景:安全研究、代码审计、逆向工程、渗透测试。

十二、优缺点

优点

  1. 极致可定制:从毛坯到精装,全部自己决定。不像其他工具那样"给你什么用什么"。
  2. 生态爆炸式增长:1117个插件,1521个生态仓库,301295颗Star。你要的功能大概率已经有了。
  3. 安装极其简单:一条dsh plugin --profile web add命令搞定一切。不需要手动下载、解压、配置。
  4. 开源协议友好:MIT协议,可自由使用、修改、商用。

缺点

  1. 版本波动大:目前还是developer preview,插件迭代很快,装之前记得看版本。
  2. 部分插件需要额外配置:比如ModLens需要锁版本号,dsh-agent-teams需要Git权限。
  3. 启动时记得加--patch:否则技能和部分插件不生效。

选装建议

用户类型推荐插件组合
只想用Harness干活dsh-web-ui + dsh-at-file
想要Codex风格界面dsh-better-sidebar + dsh-at-file
纯终端爱好者dsh-TUI
不想装Node.jsdeepseek-harness-desktop
需要看图加装ModLens
复杂任务/多Agent加装dsh-agent-teams和dsh-plan-execute
成本敏感加装dsh-context-doctor

十三、写在最后

回到最初的问题:DeepSeek Harness必装的10个插件是什么?

我给它们分了三个层次:

第一层(核心体验层):dsh-web-ui和dsh-better-sidebar。这两个是Harness的"精装修",装了之后界面体验直接从"毛坯"变"精装"。

第二层(交互方式层):dsh-TUI(终端)、deepseek-harness-desktop(桌面App)、dsh-at-file(@引用文件)。这三个决定了你用什么方式跟Harness交互。

第三层(能力扩展层):ModLens(看图)、dsh-agent-teams(多Agent)、dsh-plan-execute(双模型)、dsh-context-doctor(上下文审计)、dsh-reverse-skill(安全技能)。这些按需加载,需要什么能力就装什么插件。

DeepSeek给Harness的口号是"一切皆插件"。

从这一千多个插件来看,这真的不是口号——模型、工具、技能、会话、沙箱、存储、循环、调度、UI,全都可以拆下来换掉

我的建议是:先装dsh-web-ui和dsh-at-file这两个最基础的,把Harness从"毛坯"变成"能住"。然后根据你的使用习惯,选一个交互方式(TUI或桌面App)。最后遇到具体需求的时候(比如要看图、要多Agent协作),再去GitHub搜索dsh-plugin话题找对应的插件装上。

一千多个插件,总有一款适合你。

开源地址

DeepSeek Harness 接入 EPT 模型指南

· 阅读需 3 分钟
Bowen Zhang
本文作者

🛠️ 工具分享 | 2026-09-03

使用方式:把这篇文档丢给你电脑的 Agent(Codex、Claude 或其他),让 AI 帮你配置。

推荐 Skill

在 AI 市场安装 ept-dsh Skill:

https://ai-market.chehejia.com/?page=skills&skill=vfmxzgyvvqvtm5mmvf4j&creatorUid=18211132604_64538&rankType=hot&pageSize=20

⚠️ 注意:这个 Skill 不是接入融合云网关,而是调用你自己的 EPT LLM API(EPT Codex Responses API / EPT Claude Anthropic API)。每次对话都从你自己的 EPT 额度中扣除,占用的是个人 EPT 用量,与融合云 Token 额度无关。想用公司融合云额度,请参考《DeepSeek Harness 接入融合云模型指南》。

效果

  • 在 DSH 中使用 EPT 模型(如 baidu-deepseek-v4-flash)
  • 一键启动 / 停止 / 查看 DSH Web(端口 3080)
  • 一键启动 / 停止 / 测试 EPT Claude 本地代理(127.0.0.1:8787)
  • 一键把 EPT Codex Key 刷新进 DSH 凭据

前置条件

  • 已安装 DeepSeek Harness,~/.dsh 目录存在
  • 已登录 EPT,~/.config/ept/auth_session.json 存在且含 portal_token
  • 电脑已安装 Codex 或 Claude 客户端,可安装 Skill

第一步:安装 Skill

打开上面的 AI 市场链接安装 ept-dsh。安装后直接对你的 Agent 说「使用 ept-dsh 启动 DSH」即可。

第二步:配置 settings.yaml

编辑 ~/.dsh/settings.yaml,在末尾追加 provider 配置。

EPT Claude(需要本机代理):

llm-pi-ai:
providers:
ept-claude:
displayName: EPT Claude (Anthropic)
apiKeyEnv: EPT_CLAUDE_AUTH_TOKEN
api: anthropic-messages
baseURL: http://127.0.0.1:8787
models:
- id: baidu-deepseek-v4-flash
name: baidu-deepseek-v4-flash

EPT Codex(直连,无需代理):

llm-pi-ai:
providers:
ept-copilot:
displayName: EPT Codex
apiKeyEnv: EPT_CODEX_API_KEY
api: openai-responses
baseURL: https://portal-k8s-prod.ep.chehejia.com/api/copilot/codex/v1
models:
- id: baidu-deepseek-v4-flash
name: baidu-deepseek-v4-flash

模型 id 以 EPT 实际提供的为准;/models 接口 404 不代表 provider 不可用,直接用已知模型 id 即可。

第三步:启动 EPT Claude 代理(仅 ept-claude 需要)

EPT Claude 要求 Authorization: Bearer,而 Anthropic SDK 默认发 x-api-key,所以 Skill 内置了本机代理做转换。把 <skill-root> 换成 Skill 实际安装路径(如 ~/.agents/skills/ept-dsh):

python "<skill-root>\scripts\start_ept_claude_proxy.py"
python "<skill-root>\scripts\test_ept_claude_proxy.py"

代理只监听 127.0.0.1:8787;每次请求实时读取 EPT 登录态,登录态刷新后无需重启代理。

第四步:填入 / 刷新凭据

  • EPT Claude~/.dsh/.credentials.yaml 中添加 EPT_CLAUDE_AUTH_TOKEN。代理会忽略这个值,改用 EPT 当前 portal_token,所以填非空占位符即可。
  • EPT Codex:EPT 登录态刷新后,在同一 PowerShell 会话确认 EPT_CODEX_API_KEY 环境变量已存在,然后执行:
python "<skill-root>\scripts\refresh_ept_key.py"

该脚本只更新 refs.EPT_CODEX_API_KEY,保留其他凭据,并自动生成 .bak-时间戳 备份。更新后重启 DSH Web。

第五步:启动 DSH

# npx 方式(推荐)
python "<skill-root>\scripts\start_dsh.py" --npx

# 源码方式
python "<skill-root>\scripts\start_dsh.py" --source --source-path "<dsh源码目录>"

# 查看 / 停止
python "<skill-root>\scripts\start_dsh.py" --status
python "<skill-root>\scripts\start_dsh.py" --stop

必须使用 DSH 输出的完整 ?token=... 地址,不能只打开裸地址;同一时间只启动一个 3080 实例。

验证

python "<skill-root>\scripts\start_ept_claude_proxy.py" --status
python "<skill-root>\scripts\test_ept_claude_proxy.py"
python "<skill-root>\scripts\start_dsh.py" --status

代理测试通过会输出 EPT Claude proxy 通过:HTTP 200

关键参数说明

参数说明
baseURLhttp://127.0.0.1:8787EPT Claude 本地代理地址
apianthropic-messages / openai-responses分别对应 Anthropic / OpenAI 兼容协议
代理端口8787仅监听 127.0.0.1
DSH Web 端口3080同一时间单实例

回滚

# 恢复备份(refresh 脚本自动生成)
Copy-Item "$env:USERPROFILE\.dsh\.credentials.yaml.bak-时间戳" "$env:USERPROFILE\.dsh\.credentials.yaml" -Force

删除 settings.yaml 中的 ept-claude / ept-copilot provider 节即可回到原状。

常见问题

Q: 看不到 EPT 模型? 检查 settings.yaml 缩进、凭据 ref 是否匹配、代理是否已启动。

Q: Claude 401 / 403? 先运行 test_ept_claude_proxy.py;失败则重新执行 EPT 登录或 ept claude,不要改 DSH 源码。

Q: 代理或 DSH 端口冲突?--stop,再启动一个实例。

Q: 浏览器打开 401? 使用完整 ?token=... URL。

Q: 用这个 Skill 会扣费吗? 会。它调用的是你自己的 EPT LLM API,所有请求从个人 EPT 额度中扣除;如需使用公司融合云额度,请改用融合云网关方案。

EPT DSH

· 阅读需 2 分钟
Bowen Zhang
本文作者

使用公司 EPT 模型时,保留凭据在 $env:USERPROFILE\.dsh\.credentials.yaml,不得打印 key、token、凭据内容、请求体或 Authorization 头。

路线选择

  • ept-copilot:EPT Codex Responses API,直连 https://portal-k8s-prod.ep.chehejia.com/api/copilot/codex/v1api: openai-responses,凭据引用 EPT_CODEX_API_KEY
  • ept-claude:EPT Claude Anthropic API。必须经本 Skill 的本机代理,api: anthropic-messagesbaseURL: http://127.0.0.1:8787,凭据引用可保留为 EPT_CLAUDE_AUTH_TOKEN

不要修改 DeepSeek Harness 源码来适配 EPT Claude。Anthropic SDK 默认发 x-api-key,而 EPT Claude 要求 Authorization: Bearer;本机代理负责转换。

Claude 代理

先启动并确认代理,再启动 DSH:

python "<skill-root>\scripts\start_ept_claude_proxy.py"
python "<skill-root>\scripts\start_ept_claude_proxy.py" --status
python "<skill-root>\scripts\test_ept_claude_proxy.py"

代理只监听 127.0.0.1:8787。每次请求读取 %USERPROFILE%\.config\ept\auth_session.jsonportal_token,所以 EPT 登录态刷新后无需重启代理。代理不记录 prompt 或 token。

$env:USERPROFILE\.dsh\settings.yaml 中保留或添加:

llm-pi-ai:
providers:
ept-claude:
displayName: EPT Claude (Anthropic)
apiKeyEnv: EPT_CLAUDE_AUTH_TOKEN
api: anthropic-messages
baseURL: http://127.0.0.1:8787
models:
- id: baidu-deepseek-v4-flash
name: baidu-deepseek-v4-flash

EPT_CLAUDE_AUTH_TOKEN 只需是非空凭据;代理会丢弃 DSH 传来的 key,改用 EPT 当前 portal_token。缺少该 ref 时,把一个非敏感占位值保存为该 ref,或同步当前 EPT token。

启动 DSH

优先使用内置脚本;同一时间只启动一个 3080 Web 实例:

python "<skill-root>\scripts\start_dsh.py" --npx
python "<skill-root>\scripts\start_dsh.py" --source --source-path "<dsh-source>"
python "<skill-root>\scripts\start_dsh.py" --status
python "<skill-root>\scripts\start_dsh.py" --stop

npx 命令:

$env:DSH_HOME = Join-Path $env:USERPROFILE '.dsh'
npx --yes --package '@deepseek-ai/dsh@alpha' dsh web --no-open

源码命令必须在 DSH 仓库执行:

$env:DSH_HOME = Join-Path $env:USERPROFILE '.dsh'
pnpm dsh web --no-open

始终使用 DSH 输出的完整 ?token=... URL,不能只打开裸地址。

刷新 EPT Codex key

在 EPT 登录态已刷新、且当前 PowerShell 拿到 EPT_CODEX_API_KEY 后执行:

python "<skill-root>\scripts\refresh_ept_key.py"

代理认证会读取 %USERPROFILE%\.config\ept\auth_session.json;也可通过环境变量 EPT_AUTH_SESSION 指定该文件路径。刷新脚本读取环境变量 EPT_CODEX_API_KEY

该脚本只更新 refs.EPT_CODEX_API_KEY,保留 EPT_CLAUDE_AUTH_TOKENCHJ_GATEWAY_API_KEYrecords。更新后重启 DSH Web。

排查

  • Claude 401/403:先运行 python scripts/test_ept_claude_proxy.py。失败时让用户重新执行 EPT 登录或 ept claude;不要改 DSH 源码。
  • Claude 代理端口冲突:python scripts/start_ept_claude_proxy.py --stop 后重启。
  • DSH Web 端口冲突:python scripts/start_dsh.py --stop 后只启动一个实例。
  • 浏览器 401:使用包含 token 的完整 URL。
  • EPT /models 404:不是 provider 不可用的证据;使用已知模型 id。
  • Codex 401/403:刷新 EPT_CODEX_API_KEY,运行刷新脚本,然后重启 DSH。

SSP 车辆管理 - 从 prod 迁移车辆到 testtwo

· 阅读需 2 分钟
Bowen Zhang
本文作者

📖 不知道怎么获取 x-chj-gwtoken?看这里! 👉 飞书文档 - 获取 x-chj-gwtoken 操作指南(含截图步骤)

核心原则:优先通过接口操作。 流程:先查 prod 获取原车数据(需 x-chj-gwtoken)→ 再到 testtwo 还原创建(无需鉴权)。

环境信息

环境域名鉴权
prod(licar)https://api-hmi-default-private-front.chehejia.com需要 x-chj-gwtoken
testtwohttps://bcs-jedi-stub-service.testtwo.k8s.chehejia.com无需鉴权

域名可通过环境变量覆盖(默认使用上表中的值):

  • VEHICLE_SYNC_PROD_URL:prod 环境域名
  • VEHICLE_SYNC_TESTTWO_URL:testtwo 环境域名

快速开始

# 安装依赖
pip install -r requirements.txt

# 直接提供 x-chj-gwtoken 运行(推荐)
python scripts/sync.py <VIN> --token "your-x-chj-gwtoken"

# 不提供 x-chj-gwtoken 运行(会提示输入)
python scripts/sync.py <VIN>

获取 x-chj-gwtoken

不知道怎么获取 x-chj-gwtoken?查看飞书文档 👉 获取 x-chj-gwtoken 操作指南(含截图)

x-chj-gwtoken 有过期时间,如果迁移过程中报 401/403,重新获取一次即可。

工作流程

1. [prod] 查询车辆基础信息 → vehSeriesNo、vehVariableModelNo、purpose
2. [prod] 查询车辆配置字 → vehicleConfigCode(HU 功能配置字)
3. [prod] 查询车辆设备信息 → SN、ICCID
4. [testtwo] 同步车辆基础信息(mes/vehicle-info/licar/sync)
5. [testtwo] 同步拓扑信息(mes/topology-info/sync)
6. [testtwo] 创建 HU 功能配置字(config-code/create)
7. [testtwo] 绑定设备(devices/bind)
8. [testtwo] 更新车辆展示信息(update-veh-info)
9. 验证结果

执行步骤(供 Claude 使用)

1. 确认参数

先问用户以下信息,缺什么问什么:

如果用户提供了 VIN 和 x-chj-gwtoken,直接进入第 2 步。 如果用户只给了 VIN,先问 x-chj-gwtoken,并告知去飞书文档查看获取方式。

2. 检查 Python 环境

python --version

确认 Python 3.10+ 可用。

3. 安装依赖

cd "docs/skill/车云平台数据同步-prod-to-testtwo"
pip install requests

4. 运行同步脚本

python scripts/sync.py <VIN> --token "<token>"

如果用户没有提供 x-chj-gwtoken 参数,会交互式提示输入。

5. 向用户报告结果

  • 成功:显示迁移完成 + 车辆信息摘要
  • 失败:显示具体失败步骤 + 错误信息

参数说明

参数必填说明
VIN目标车辆 VIN(位置参数)
--tokenx-chj-gwtoken,不传则交互式输入

故障排查

问题原因解决
401 Unauthorizedx-chj-gwtoken 过期重新获取 x-chj-gwtoken
未找到车辆VIN 不存在于 prod确认 VIN 是否正确
同步失败网络或服务异常重试,或检查 testtwo 服务状态

DSH 接入公司 LLM —— 集成工程

· 阅读需 3 分钟
Bowen Zhang
本文作者

目标:把公司内部 LLM 接口接进 DeepSeek Harness 直接用。 结论:主路线(chj-gateway / deepseek-v4)已经在用;本目录补全模型清单,并新增 EPT Copilot(GPT-5.6,Responses API) 作为第二 provider(路线 C)。


一、现状盘点(已侦察确凿)

chj-gateway(已有,主力)ept-copilot(本次新增)
端点https://llm-gateway-proxy.inner.chj.cloud/llm-gateway/v1https://portal-k8s-prod.ep.chehejia.com/api/copilot/codex/v1
协议openai-completions(标准 Chat Completions)openai-responses(EPT/Codex 用的 Responses API)
鉴权CHJ_GATEWAY_API_KEY(已在 .credentials.yamlEPT_COPILOT_TOKEN(需获取,见下)
模型示例kivy-deepseek-v4-flash-0731 / kivy-deepseek-v4-pro / kivy-glm5 / kivy-kimi-k2_6azure-gpt-5_6-luna / sol / terra
现状✅ 已配好,本会话正在用它跑 kivy-deepseek-v4-flash-0731❌ 未接入

▲ 完整模型清单请在本机连 VPN 后用 verify.ps1 拉取(网关 /v1/models)。


二、一句话的 EPT 机制解析

ept codex 做的事:用 auth_session 登录态 → 从企业 copilot 拉取配置 → 通过环境变量注入 base_url + API keyEPT_CODEX_API_KEY)→ 启动 Codex,Codex 走 .../api/copilot/codex/v1/responses。 也就是说公司 LLM 的“钥匙”是 portal 域名的 Bearer 令牌auth_session.json 里的 access_token / portal_token 二选一,见 verify.ps1 探测结果)。


三、目录文件

dsh-ept-integration/
├── README.md # 本文件
├── provider-merge.yml # 两个 provider 的配置片段(合并目标)
├── verify.ps1 # ① VPN 终端先跑:拉 chj 模型 + 探测 ept 可用令牌
├── apply.ps1 # ② 备份+安全合并进 $DSH_HOME/settings.yaml
└── refresh-ept-key.ps1 # ③ (可选)刷新/写入 ept 令牌到 credentials

四、操作步骤

第 1 步(重要):先探测,别急着改

在你的正常终端(已连公司 VPN)里跑:

powershell -ExecutionPolicy Bypass -File D:\bowen\git-project\dsh-ept-integration\verify.ps1

它会(只读,绝不打印密钥值):

  1. CHJ_GATEWAY_API_KEYllm-gateway-proxy.../v1/models → 打印真实模型 id 列表;
  2. 依次用 auth_session.jsonaccess_tokenportal_token 作为 Bearer 探测 portal-k8s-prod.../api/copilot/codex/v1/models → 打印哪一个令牌被接受(HTTP 200 即为通过),并在通过时打印该端点可用的模型 id。

把这两份“模型 id 列表”和“通过的令牌名”回贴给我,我再据此定稿 provider-merge.yml 里的模型清单(不要凭我给的那几个猜测字段,要以网关真实返回为准)。

第 2 步:合并配置到 DSH

确认 provider-merge.yml 里的模型/令牌符合第 1 步结果后:

# 先看差量预览(不写盘)
D:\bowen\git-project\dsh-ept-integration\apply.ps1

# 确认无误再真正合并(会自动备份 settings.yaml)
D:\bowen\git-project\dsh-ept-integration\apply.ps1 -Apply

第 3 步:写入 ept 令牌(路线 B 用)

把第 1 步确认可用的令牌写进 DSH 凭据:

D:\bowen\git-project\dsh-ept-integration\refresh-ept-key.ps1 # 交互式从 auth_session 提取并写入 .credentials.yaml

(写入的是 EPT_COPILOT_TOKEN 键;注意 access_token 每天过期,需定期刷新——脚本会提示。)

第 4 步:让 DSH 生效并选模型

改完 settings.yaml重启 dsh web,然后在 Web 的模型选择里切换:

  • CHJ LLM Gatewaykivy-deepseek-v4-*(主力)
  • EPT Copilotazure-gpt-5_6-*(新增)

五、注意事项

  • 密钥安全:令牌属于敏感信息,脚本只在内存中使用、不回显;写入 .credentials.yaml 时保持该文件私密。
  • 凭据自动刷新access_token 短有效期(auth_session.jsonexpires_at),企业后台凭据说 refresh_token 可续。用 cron / 开机脚本定期跑 refresh-ept-key.ps1 即可维持。
  • 503 抖动:日志曾见 simulated no healthy upstream(deepseek-v4-pro 偶发 503)。属网关上游问题;pi-ai 有重试策略,若频繁可顺手把 CLI 里的重试调高。
  • 本沙箱无 VPN 且写盘受限,所以所有实连验证都必须在你的正常终端完成

Ponytail:把 AI 写代码时的过度设计剪掉

· 阅读需 1 分钟
Bowen Zhang
本文作者

Ponytail 是我给 AI 编程工作流写的一套约束:先问这件事是否需要存在,再复用已有代码、标准库和平台能力,最后才增加最小实现。

它约束的不是代码风格

重点不是“每次都写一行代码”,而是要求 AI 先理解真实调用链,修根因而不是给每个调用方打补丁。懒惰的目标是少维护,不是少思考。

为什么需要显式的跳过项

很多工程浪费来自“顺手加上”的配置、抽象和扩展点。记录“这次跳过了什么、什么时候才值得加”,能让简化变成有意识的取舍,而不是遗漏。

适合落地到团队吗

适合把它当 review 清单和 agent 指令,不适合当成拒绝所有复杂设计的教条。安全、数据完整性、可访问性和明确要求,永远优先于少写几行代码。