api-design

api-design is a skill for Claude Code, Codex from pingfanfan/hello-dsh. It costs 54 tokens per session (1,170 once invoked), scanned A, original, MIT.

Guidance for designing public programming interfaces, meaning the methods and data structures other code is allowed to use. It emphasizes adding only interfaces with real callers and making invalid uses impossible to compile.

In plain words
What is it for?
Deciding whether to add a public method, choosing parameter types, representing valid and invalid results, and designing distinguishable errors.
Why use it?
It helps prevent APIs that are unnecessary, hard to remove, easy to misuse, or difficult for callers to handle correctly.

Skill for Claude CodeCodex

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add skills/pingfanfan/hello-dsh/api-design
Any agent
npx skills add pingfanfan/hello-dsh --skill api-design
Clone the repo
git clone --depth 1 https://github.com/pingfanfan/hello-dsh

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for api-design

README.md
[![agentmods](https://agentmods.dev/badge/skills/pingfanfan/hello-dsh/api-design.svg)](https://agentmods.dev/skills/pingfanfan/hello-dsh/api-design)
Your own site
<a href="https://agentmods.dev/skills/pingfanfan/hello-dsh/api-design"><img src="https://agentmods.dev/badge/skills/pingfanfan/hello-dsh/api-design.svg" alt="Measured on agentmods" height="20"></a>
Per session 54 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 1,170 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00054 $0.01170
Opus 5 $0.00027 $0.00585
Sonnet 5 $0.00011 $0.00234
Haiku 4.5 $0.00005 $0.00117

Measured 3d ago against content hash d5d575463630, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

api-design scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 3d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

examples/skills/api-design/SKILL.md · 111 lines

What it actually says

接口设计

每一个公开出去的东西都是承诺。 加一个方法容易,删一个方法要等所有调用方迁移完。所以决定加什么之前,先问它该不该存在。

必要性判断

新增公开接口前,回答:

现在有几个真实调用方?

  • 零个 —— 不要加。「以后可能用得上」不是理由,等真用上再加。
  • 一个,而且是内部的 —— 这是个信号。一个通用服务(注册表、会话管理器)上新增的公开方法,如果唯一调用方是某个内部消费者,那它不该是公开 API,应该在构造时把一个私有能力闭包交给那个消费者。
  • 两个以上,且用法一致 —— 可以加。
  • 两个以上,但用法不一致 —— 说明你在设计的是两个东西,分开。

这个判断挡掉的是投机性通用化:为了想象中的未来需求造出来的灵活性,最后既没人用,又没法删。

让错误用法无法表达

好的接口让人不容易用错,而不是用错了报错。

// 差:两个 string 参数,顺序写反了编译器不管
function transfer(from: string, to: string, amount: number)

// 好:类型系统拦住顺序错误
function transfer(from: AccountId, to: AccountId, amount: Money)
// 差:非法状态可以被表达出来
interface Result { ok: boolean; data?: T; error?: Error }
// ok: true 但 data 是 undefined 怎么办?

// 好:非法状态无法表达
type Result<T> = { ok: true; data: T } | { ok: false; error: Error }

优先级:编译期拦住 > 运行时报错 > 文档里写"不要这样"

参数

  • 超过三个参数就用对象,调用处才能看到参数名
  • 布尔参数几乎总是错的render(true) 读不懂,改成 render({ inline: true }) 或拆成两个函数
  • 可选参数要有明确默认值,不要靠 undefined 传递含义
  • 不要用同一个参数表达两种意思(比如传 null 表示"用默认值",传 undefined 表示"不设置")

错误

调用方需要区分处理的失败,必须是可区分的。

// 差:调用方只能靠匹配错误消息来区分
throw new Error('not found')

// 好
throw new NotFoundError({ resource: 'session', id })

判断标准:调用方拿到这个错误后,需要做出不同的反应吗? 需要,就要能区分;不需要,一个通用错误就够。

还有一条:不要把结构化的错误替换成通用错误。DSH 有过一个真实事故,沙箱的 SandboxUnavailableError 被上层捕获后替换成了通用的 SEARCH_FAILED,调用方彻底失去了判断依据,排查花了很久。

一致性

同一个代码库里,同类操作要长得一样:

  • 命名:都叫 get 还是都叫 fetch,选一个
  • 返回:找不到时都返回 undefined 还是都抛错,选一个
  • 异步:都返回 Promise,不要一部分同步一部分异步
  • 顺序:参数顺序在同类方法间保持一致

不一致的代价是每次调用都要查一遍文档。

演进

加东西容易,删东西难。 所以:

  • 新增可选字段是安全的
  • 新增必填字段是破坏性的
  • 收紧参数类型是破坏性的
  • 放宽返回类型是破坏性的(调用方可能在依赖窄类型)

要改接口时的顺序:加新的 → 两者并存 → 迁移调用方 → 删旧的。四步,不是一步。

文档写什么

写代码表达不了的:

  • 前置条件(调用前必须成立什么)
  • 后置条件(调用后保证什么)
  • 谁拥有返回的对象(调用方能不能改它)
  • 失败时的状态(是原子的还是可能半完成)
  • 并发语义(能不能同时调)

不要写代码已经说清楚的(参数类型、字段名的含义)。

不要做的事

  • 不要为了"以后可能需要"加参数、加字段、加方法
  • 不要在通用服务上开一个只服务于单一消费者的口子
  • 不要让同一个方法有多种返回形态
  • 不要用位置参数表达可选配置
  • 不要在没有第二个调用方的时候就抽象
  • 不要让调用方靠解析错误消息来做流程判断
Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 3d ago First seen · 111 lines · 54 tokens per session scan A d5d575463630

Subscribe to this mod's changes

api-design is a skill published in the GitHub repository pingfanfan/hello-dsh (87 stars, last pushed 20d ago), licensed MIT. It adds 54 tokens to every session and 1,170 once invoked, about $0.0003 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other skills, from other repositories

dsh-plugin-guide

Use when developing, reviewing, packaging, debugging, or answering questions about DeepSeek Harness (DSH) plugins — the plugin-based agent harness on vendored Cordis. Applies the official plugin-development constraints (plugin contract, cordis.yml layers, services/events/effects, tool DSL, bundles/profiles) backed by…

PerryLink/dsh-plugin-guide · 76 tokens

dsh-web-release

Release and publish the dsh-web monorepo (DSH Web GUI plugin family + skin collection) — bump all packages to one unified version, commit and tag (tags are cut from main after dev integration; dev is the integration branch), push the vX.Y.Z tag that triggers the GitHub Actions publish pipeline, and verify the npm…

zhu1090093659/dsh-web · 151 tokens

dsh-web-community-plugin-developer

Develop a DSH community plugin and register it in the dsh-web Community Plugins index — author the plugin in the contributor's own repository following the official cordis bundle standard, add its entry to packages/dsh-community-plugins/community.json, regenerate the index with scripts/community-index, rebuild and…

zhu1090093659/dsh-web · 123 tokens

dsh-web-skin-developer

Build a new skin for the dsh-web skin collection (DSH Web GUI) and publish it into the Skin Center — the first-level settings section — scaffold with scripts/dsh-skin-new, author the v2 skin.json manifest plus skin.css token remap (pure asset directory, no package.json, no build step), validate with scripts/dsh-skin…

zhu1090093659/dsh-web · 120 tokens

dsh-web-pre-push-checks

Use before pushing, opening or updating a pull request, or claiming dsh-web checks pass. Selects the required repository gates and diff-specific generation, build, and GUI evidence.

zhu1090093659/dsh-web · 45 tokens

dsh-web-documentation

Use when adding or editing dsh-web README files, docs, AGENTS.md instructions, user-facing configuration text, or bilingual documentation pairs.

zhu1090093659/dsh-web · 34 tokens