Dayward AI
Week 1 · D3About 5 hours

A Design Method: Distilling From Repeated Tasks, Checklist Style vs. Reference-Manual Style, Four Anti-Patterns, and Trigger Testing

Turn writing a skill from inspiration into a method: judge whether a task is worth turning into a skill, organize content into one of two mature forms, avoid four anti-patterns, and use a set of positive and negative examples to measure description's trigger rate.

Today's goals 0/3

Sign in to tick these off and save your progress.

Today's Goals

  1. Judge whether a repeated task is worth turning into a skill, using three criteria
  2. Distinguish checklist style from reference-manual style, and pick the right form for a task
  3. Design a set of positive and negative example queries, measure description's trigger rate, and rewrite it accordingly

Yesterday you wrote your first skill by trying three sentences and seeing whether it triggered. That works with one skill and stops working by the tenth — you cannot hold in your head whether ten descriptions compete with each other, and you cannot tell after editing one sentence whether you improved it or broke it. Today gives you a ruler you can reuse. Once you have read the walkthrough and finished the lab, scroll back to the top and tick off the three goals.

Plain-Language Walkthrough

Three criteria for choosing a subject

The filing cabinet's space is finite — not physical space but the model's attention. Every extra skill adds a line to the catalog and raises the chance of a spurious trigger. So the first question is never "how do I write this skill" but "is this thing worth turning into a skill at all."

Three criteria, and all three must hold before you start:

First, repetition. You have done this at least three times and will do it again. Something done once has no experience in it — you do not even know whether you got that once right. The test is plain: can you say immediately when you last did this? If you cannot, it is not as frequent as you thought.

Second, a correction exists. The first time the model did this, you interrupted it. This is the hardest of the three, because it proves two things at once: the model genuinely does not know (or you would not have corrected it) and you genuinely do (or you could not have). A skill with no record of correction will most likely come out as a pile of correct-and-useless lines — "handle errors appropriately," "follow best practices," sentences the model would produce without your skill anyway.

Third, the result is checkable. When it is done you can tell whether it was done right. Whether a commit message matches the format is visible at a glance; whether the amounts on a filled-in report are correct takes one calculation. Conversely, "think of a better architecture for me" is a task whose correctness is known three months later — not that it cannot be a skill, but you cannot iterate on it, so once written you can only feel that it is useful.

Start only once all three pass. Fail any one of them and the time you spend on the skill will most likely be wasted: what is not repeated goes unused, what has no correction comes out as filler, and what cannot be checked leaves you never knowing whether it worked.

These three criteria filter out far more than they keep. That is correct — three folders in the cabinet consulted daily beat thirty nobody opens. Which raises the next question: for the thing that passed, how should the content be organized? As a procedure followed step by step, or as a manual consulted at will? Those two forms suit entirely different situations, and picking wrong gives you something usable but awkward. Below, both forms and the four most commonly hit anti-patterns, settled in one go.

Distilling from one real conversation

The correction-exists criterion is not only a filter; it is also the content's direct source. The method is do it once, then distil: work through the task with the model end to end, correcting it normally throughout, then look back over that conversation and copy out four kinds of thing.

First, the sequence of steps that worked. Write down, in order, the path that eventually went through. Note that it is the path that worked, not every path you tried — branches abandoned midway do not belong in the skill, where they would only give the model more options.

Second, every correction you made. "Use this library, not that one." "Check for null here." "Wrong order, validate before writing." Those are the densest content in the whole skill, because they mark precisely the gap between the model's default behavior and your expectation.

Third, what the input and output actually look like. What format the input file is in and what the output should look like. Paste samples for this rather than describing them in prose.

Fourth, the background you supplied. Facts the model could not possibly know and that you told it on the spot: this field has three different names across three systems, this health check endpoint only checks the process is alive and not whether the database is reachable. Facts like these are extremely valuable, and they are exactly the raw material for yesterday's pitfalls section.

Beyond the conversation there is one badly underrated source: material that already exists in your project. Internal documentation and runbooks, endpoint specs and configuration files, review comments that keep recurring, and the fix commits in the history. That last one is especially valuable — it records what was actually changed rather than what was meant to be done. A data pipeline skill distilled from real incident records will always beat one generated from a "data engineering best practices" article.

Two forms: checklist style and reference-manual style

With the material gathered, the organization comes next. Mature skills land in one of two forms, and getting it right makes writing flow while getting it wrong makes everything awkward.

Checklist style suits tasks where steps depend on each other, the order cannot change, and missing one breaks things. The body is mainly a numbered list of steps, often with a progress checklist for the model to tick. Release procedures, form filling, and data migrations all belong here.

This form has a very useful variant: plan first, validate, then execute. Have the model produce an intermediate plan (a file mapping fields to values, say), run a validation script comparing that plan against ground truth, and execute for real only once it passes. The key is not the first or third step but the validation in the middle — with an error message stating "the field signature_date does not exist; available fields are…," the model has enough information to fix it itself. Bulk operations and destructive operations should all take this route.

Reference-manual style suits knowledge-dense tasks consulted on demand with no fixed order. The body is mainly a collection of what-to-do-when entries, plus a set of reference files cut small. Handling endpoint error codes, looking up format specs, and domain terminology mappings all belong here.

The criterion between the two is one sentence: does this thing have an order that must be followed? If yes, checklist style; if no, reference-manual style. Mixing them is common, but mix by section rather than listing steps and piling up entries within one section — that reads like a manual whose table of contents got shuffled.

Four anti-patterns

The four below are what beginners most often produce, and each is recognizable in one sentence.

First, covering everything. One skill tries to cover all the work in a domain: a "database skill" handling queries, index creation, and backup and restore. Its problem is that it cannot be triggered precisely — the description has to be written broadly enough to cover all that, and broad means spuriously triggered everywhere. The test: if you cannot resist words like "and so on" or "and related matters" while writing the description, the scope is already too large. Split it.

Second, shattered into fragments. The reverse: one thing split into five skills, one reading files, one validating, one converting. Its problem is that doing one thing activates five at once, five bodies enter the context together, and they may even contradict each other. The test: if two skills are almost always used together, they were one skill.

The scale for splitting and merging is the same as for splitting functions: a skill should encapsulate one cohesive unit of work and compose with other skills. "Query the database and format the results" can be one unit; "query the database and also administer the database" is two things.

Third, restating common knowledge. The body spends paragraphs explaining what a PDF is, how HTTP works, what a database migration means. The model knows all of it, and writing it in only dilutes attention. The test is the same line: without this, would the model get it wrong? If not, delete it.

Fourth, a menu with no default. "You may use any of the four libraries A, B, C, or D." Handed a pile of peer options, the model can only pick one, and it may pick differently each time. The right form is one default plus one fallback: "use A; switch to B for scanned documents going through OCR." This one often gets mistaken for preserving flexibility, when it is really offloading the decision cost onto the model.

A related point while we are here: a skill is not better for being more complete. A skill covering every edge case tends to make the model waste steps on irrelevant instructions — reading a rule that does not apply to the current task, it will still try to comply. Concise step-by-step guidance plus one usable example usually beats exhaustive documentation. When you notice yourself covering the seventh edge case, ask first: would this one be better left to the model's judgment?

Trigger testing: replacing feel with numbers

Now to today's hardest section. Everything above was about how to write; this is about how to know you wrote it right.

Yesterday you tried three sentences, which is spot-checking. Turning it into a ruler takes three things.

First, a set of labeled queries. About 20, of which 8 to 10 should trigger and 8 to 10 should not. The should-trigger batch has to spread across four dimensions: phrasing formal, casual, and even with typos; some naming the domain directly and some only describing the need; some very short and some carrying a pile of file paths and background; some single-step tasks and some burying this thing inside a long stretch of other work. The most valuable positive cases are the queries where the skill genuinely should be used but the wording does not say so — a query that recites the skill's function verbatim will be matched by any description and measures no difference at all.

The should-not batch takes even more design. A sentence with no overlap at all, like "what is the weather today," measures nothing. What is genuinely useful is the near-miss negative: sharing keywords or concepts with the skill while actually needing something else. For a CSV analysis skill, "help me fix a formula in my Excel budget sheet" and "write a script to push each CSV row into the database" are both good negatives — the first is Excel editing rather than CSV analysis, and the second is data movement rather than analysis.

Second, repeated runs. A model's behavior is non-deterministic, and the same query may trigger this time and not the next. Run each 3 times and compute a trigger rate: triggers divided by runs. A should-trigger query passes above 0.5, and a should-not query passes below 0.5. Twenty queries times 3 runs is 60 calls, which at that scale demands a script.

Third, a train and validation split. This is what beginners most often skip and most often pay for. Tune the description against all 20 and you will produce a description tuned specifically for those 20, which collapses on a fresh batch. The method is to split the query set roughly sixty-forty: use only the training set to find problems and guide rewrites, and never look at the validation set, then use the validation pass rate at the end to pick which version of the description is best. Keep the positive-negative ratio close in both halves, and fix the split once made rather than reshuffling every round.

Judging whether a query triggered is the core of this apparatus. The principle is surprisingly simple: assemble every skill's name and description into a catalog, hand it to the model along with the user's sentence, and ask which one to use or none. That is what a client does in stage one, and we are simply pulling it out to run on its own.

trigger.ts
type SkillMeta = { name: string; description: string }
 
// This prompt deliberately mirrors what a client does in stage one: names and descriptions only, no bodies
function buildJudgePrompt(skills: SkillMeta[], query: string): string {
  const catalog = skills.map((s) => `- ${s.name}: ${s.description}`).join('\n')
  return [
    'Below is the catalog of available skills, each with only a name and a description.',
    catalog,
    '',
    `The user says: ${query}`,
    '',
    'Answer with one skill name only; if none clearly applies, answer none. Do not explain.',
  ].join('\n')
}
 
export async function judgeOnce(skills: SkillMeta[], query: string, target: string): Promise<boolean> {
  if (process.env.MOCK === '1') {
    // Offline simulation: approximate the model's judgment by keyword overlap so the chain runs without a key
    const hit = target.split('-').some((w) => query.includes(w))
    return hit
  }
  const answer = await callModel(buildJudgePrompt(skills, query))
  return answer.trim().toLowerCase() === target.toLowerCase()
}
 
// Run it `runs` times for a trigger rate, because the model's judgment is itself non-deterministic
export async function triggerRate(skills: SkillMeta[], query: string, target: string, runs = 3) {
  let hits = 0
  for (let i = 0; i < runs; i++) if (await judgeOnce(skills, query, target)) hits++
  return hits / runs
}

With the trigger rate in hand, what remains is statistics and the split. The code below runs a set of labeled queries into a table: expectation, trigger rate, and pass or fail per row, then the pass rate summarized separately for the training and validation sets. The key is computing the two sets separately — the training numbers guide your edits and the validation numbers decide which version you ship.

evaluate.ts
type Case = { query: string; shouldTrigger: boolean; split: 'train' | 'validation' }
 
export async function evaluate(skills: SkillMeta[], target: string, cases: Case[]) {
  const rows = []
  for (const c of cases) {
    const rate = await triggerRate(skills, c.query, target)
    // Threshold 0.5: should-trigger must be above it, should-not must be at or below it
    const passed = c.shouldTrigger ? rate > 0.5 : rate <= 0.5
    rows.push({ ...c, rate, passed })
  }
  const rateOf = (split: Case['split']) => {
    const subset = rows.filter((r) => r.split === split)
    return subset.length === 0 ? 0 : subset.filter((r) => r.passed).length / subset.length
  }
  // Training numbers guide the rewrite; validation numbers decide which version you ship
  return { rows, train: rateOf('train'), validation: rateOf('validation') }
}

Once you have the results, there are two hard rules for editing. A should-trigger query that did not trigger means the description is too narrow, and what you add is the class of phrasing rather than that one sentence — copying the failing query's exact words into the description is where overfitting begins. A should-not query that triggered means the description is too broad, and what you add is a boundary: state explicitly what it does not do, or spell out the line between it and neighboring capabilities.

Two more lessons worth recording. Stop after about five rounds: if the pass rate stops moving, the problem is most likely the query set itself (too easy, too hard, or mislabelled) rather than the description. The best version is not necessarily the last: the later rounds are quite likely overfitting to the training set, so pick the version by validation pass rate rather than by iteration order.

Source Reading

Hands-On Lab

🧪 D3 lab: a skill trigger testing script fed a set of labeled queries, printing per-query hits and trigger rates

Code location: labs/agent-skills-7days/day-03-trigger-eval

Acceptance criteria:

  1. The whole flow runs under MOCK=1, printing a per-row table of query, expectation, trigger rate, and pass or fail, ending with the training and validation pass rates.
  2. The query set has at least 12 entries with a close positive-negative balance, of which at least 3 are near-miss negatives sharing keywords with the target skill.
  3. Each query runs 3 times for a trigger rate rather than being judged from one run.
  4. The training and validation sets are split roughly sixty-forty with close positive-negative ratios in both, and summarized separately.
  5. After rewriting the description per the training set's failures and rerunning, the output shows the two versions' validation pass rates side by side.

There is real code to write today. Before starting, have yesterday's commit-message skill description ready, since it is the subject under test. When stuck on inventing near-miss negatives, go back to the two CSV examples in the trigger testing section and build from them — shared keywords, different target verb, which is the only criterion.

  1. Get the solution running and use MOCK=1 to see the per-row hit table and the two pass rates from a labeled query set.
  2. Complete the description-matching judgment in the starter so it returns a hit or miss plus one line of reasoning per query.
  3. Complete the trigger rate statistics and the separate summaries for the training and validation sets.
  4. Add three near-miss negatives of your own, rerun, and observe how the trigger rates change.
  5. Rewrite the description per the training set's failures, run again, and compare the two versions' validation pass rates.

Interview Questions

Today's 3 questions are in the question bank below, weighted toward the criteria for choosing a skill's subject, the trade-off between the two content forms, and the design of trigger testing and overfitting. Expand each one and read the analysis before the key points — practicing the derivation beats memorizing bullets. The high-frequency labels for the domestic and overseas markets are there so you can pick by target market.

Checklist and Tomorrow

  • Judge whether a repeated task is worth turning into a skill, using three criteria
  • Distinguish checklist style from reference-manual style, and pick the right form for a task
  • Design a set of positive and negative example queries, measure description's trigger rate, and rewrite it accordingly
  • Name the four anti-patterns on the spot, with one example each you have written or seen
  • All 5 acceptance criteria of the lab pass
  • Answer at least 2 of the 3 interview questions without looking at the key points

Tomorrow (D4) we give a skill hands and feet. That crucial validation inside today's plan-validate-execute is a script; today's "the model reinvents the same logic every time" is likewise a signal to write one. Tomorrow settles when to switch from writing instructions to writing code, how a script's dependencies become self-contained, how an interface is designed for an agent rather than a person, and one unavoidable question — exactly how risky is it to let a model run your script.

Interview questions

  • Which tasks are worth turning into a skill and which are not? Give me a test I can apply on the spot.什么样的任务适合做成 skill,什么样的不适合?给我一套能当场用的判断标准。
    Common in ChinaCommon overseasBasic#agent-skills#skill-design

    How to reason about it · think before answering

    1. The lazy answer is repetitive and complex tasks, which anyone can say. The interviewer wants a falsifiable test plus the reasoning behind each part.
    2. Give three criteria and insist all three must hold: repetition (done at least three times and will recur), correction (you interrupted the model the first time), and checkable results (you can tell afterwards whether it was right).
    3. Explain each. Correction is the strongest, because it simultaneously proves the model does not know and that you do. Without correction history you produce generic filler like handle errors appropriately.
    4. Checkability is the one people skip, and it decides not whether you can write the skill but whether you can iterate on it. If correctness only surfaces in three months, you are guessing.
    5. Then state the failure modes: without repetition nobody uses it, without correction it is filler, without checkability you cannot improve it.
    6. Expected follow-up: how wide should one skill be? Scope it like a function: one coherent unit that composes with others. Two skills always activated together were one skill; if the description needs and so on, the scope is too wide.

    分析过程 · 先想清楚再作答

    1. 这题最容易答成「重复的、复杂的任务」,那是所有人都会说的话,没有区分度。面试官想听的是一套能证伪的判据,以及每一条判据背后的道理。
    2. 给三条,并且强调三条都要成立:重复(干过至少三次且还会干)、有纠正(模型第一次做时你打断过它)、结果可检验(做完能判断对错)。
    3. 逐条解释为什么。「有纠正」是最硬的一条,因为它同时证明模型确实不会、你确实会——没有纠正记录的 skill 写出来大概率是「妥善处理错误」这类正确的废话。
    4. 「可检验」这条常被忽略但很关键:它决定的不是这个 skill 能不能写,而是**你能不能迭代它**。对错要三个月后才知道的任务,你写完只能凭感觉觉得有用。
    5. 然后给反面:不满足这三条会怎样——不重复的没人用,没纠正的是废话,不可检验的没法改进。这一句把判据从清单变成了论证。
    6. 可预期的追问是「那范围多大合适」。答案是像拆函数一样:一个内聚的工作单元,且能与别的 skill 组合。两个总是一起激活的 skill 本来就是一个;描述里忍不住写「等等」说明范围太大了。

    Key points

    • All three must hold before you start: repetition, correction, checkable results.
    • Correction is the strongest signal because it proves both the gap and your expertise.
    • Checkability decides whether you can iterate, not whether you can write it.
    • Scope to one coherent unit; two skills that always activate together should be merged.
    • If the description needs and so on, the scope is already too wide.

    答题要点

    • 三条判据全部成立才动手:重复、有纠正、结果可检验。
    • 有纠正是最硬的一条,它同时证明模型不会而你会。
    • 可检验决定的不是能不能写,而是能不能迭代。
    • 范围按内聚工作单元切,总是一起激活的两个 skill 应该合并。
    • 描述里出现「等等」「以及相关的」,说明范围已经太大,该拆。
  • How do you evaluate whether a skill description is good? Is trying a few prompts yourself enough?怎么测一个 skill 的 description 好不好?自己试几句话够吗?
    Common in ChinaCommon overseasIntermediate#agent-skills#evaluation

    How to reason about it · think before answering

    1. The hinge is the second half. Saying a few prompts is enough fails immediately, but saying write a test set is not enough either; the interviewer wants the design.
    2. Explain why spot checks fail: fine with one skill, useless at ten, because you cannot hold ten descriptions in your head nor tell whether an edit helped or hurt.
    3. Then give three ingredients. First, a labeled query set of about twenty, balanced positive and negative. Vary positives along phrasing, explicitness, detail and complexity; the most valuable positives are the ones where the skill applies but the wording does not say so.
    4. Negatives are where the design effort goes: unrelated sentences test nothing. Near-misses that share keywords but need something else are what matters, such as editing Excel formulas or loading CSV rows into a database for a CSV-analysis skill.
    5. Second, repeat runs for a trigger rate, since model behavior is nondeterministic: three runs per query with a 0.5 threshold. Third, a roughly sixty-forty train and validation split with the validation set untouched.
    6. Expected follow-up: how do you decide whether a query triggered? Build the catalog of names and descriptions, hand it plus the query to the model and ask which skill applies. That is exactly what a client does at discovery, run standalone.

    分析过程 · 先想清楚再作答

    1. 题眼在后半句。答「自己试几句就行」直接出局,但只答「要写测试集」也不够——面试官要看你知不知道这个测试集该怎么设计。
    2. 先说为什么抽查不够:一个 skill 时够用,装到第十个就不行了,因为你既记不住十个描述之间会不会互相抢,也没法在改完一句话后判断是改好了还是改坏了。
    3. 然后给三件东西。第一是带标注的查询集,约 20 条,正负各半。正例要在措辞、显式程度、详略、复杂度四个维度上铺开;**最有价值的正例是那些确实该用但字面看不出来的**,字面已经念了一遍功能的查询任何描述都能命中,测不出区别。
    4. 负例是设计的重点:毫无重叠的句子测不出任何东西,真正有用的是近似负例——共享关键词或概念但目标动词不同。对 CSV 分析 skill,「改 Excel 预算表的公式」和「把 CSV 每行写进数据库」都是好负例。
    5. 第二是重复跑取触发率:模型是不确定的,每条跑三次算命中比例,阈值取 0.5。第三是训练验证拆分,六比四,验证集全程不看。
    6. 可预期的追问是「怎么判断一条查询触发了没有」。答案是把所有 skill 的名字与描述拼成目录,连同这句话交给模型问它该用哪一个——这正是客户端在发现阶段做的事,只是单独拎出来跑。

    Key points

    • Spot checks work for one skill and break down once several skills compete.
    • About twenty labeled queries, balanced, with positives varied by phrasing, explicitness, detail and complexity.
    • Negatives must be near-misses that share keywords but need a different action.
    • Three runs per query for a trigger rate with a 0.5 threshold, because behavior is nondeterministic.
    • Split roughly sixty-forty; train guides revision, validation picks the winning version.

    答题要点

    • 抽查在一个 skill 时够用,多个 skill 互相干扰时完全不够。
    • 约 20 条带标注查询,正负各半,正例在措辞、显式程度、详略、复杂度四维上铺开。
    • 负例必须是近似负例:共享关键词但目标动词不同,无关句子测不出东西。
    • 每条跑三次取触发率,阈值 0.5,因为模型行为不确定。
    • 训练验证六四拆分,训练集指导改写,验证集只用来选版本。
  • When optimizing a description, how do you avoid overfitting to the very queries you wrote?优化 description 的时候怎么避免过拟合到你自己写的那几条测试查询?
    Common in ChinaCommon overseasDeep dive#agent-skills#evaluation

    How to reason about it · think before answering

    1. This is a familiar machine learning idea in a new setting. Saying validation set is only the start; the discriminator is describing the exact wrong move.
    2. Name what overfitting looks like here: a query fails, you paste its wording into the description, that query passes, and a synonymous one fails. Pasting the wording is the overfitting act itself.
    3. The right move is to generalize: identify the category the failing query represents and cover that. If a casual phrasing failed, cover casual phrasings, not that sentence.
    4. Structurally, rely on the split: roughly sixty-forty, revise only from train-set failures, keep the validation set out of the loop, preserve label balance in both, and freeze the split across iterations.
    5. Two practical rules: pick the version by validation pass rate rather than by recency, since later rounds tend to overfit, and stop after about five iterations if nothing moves, because the problem is then in the queries.
    6. Expected follow-up: how do you know the queries are the problem? Look at items that pass or fail in every configuration. Always-pass items carry no information; always-fail items are mislabeled or beyond the model.

    分析过程 · 先想清楚再作答

    1. 这题是机器学习的老概念换了个场景,考的是你能不能把它迁移过来。能说出「验证集」三个字只是起点,真正的区分度在你怎么描述那个具体的错误动作。
    2. 先点明过拟合在这里长什么样:一条查询没触发,你把它的原话抄进描述,于是这一条过了,换一句同义的又不过。**抄原话就是过拟合的动作本身。**
    3. 正确做法是归纳:找出这条失败查询代表的**那一类说法**,然后把这一类补进去。比如「这几个文件我要提交了」失败了,该补的不是这句话,是「不含专业词的口语提交请求」这一类。
    4. 结构上靠拆分兜底:查询集按六比四拆成训练与验证,只用训练集的失败项指导改写,验证集全程不参与优化过程,两份都要保持正负比例接近,拆完固定不再洗牌。
    5. 还有两条实操经验。**挑版本按验证集通过率挑,不是按迭代顺序挑**——后面几轮往往在往训练集上过拟合,最好的可能是第三版而不是第五版。改五轮左右还不动就该停,问题多半在查询集本身而不在描述。
    6. 可预期的追问是「怎么知道是查询集的问题」。答案是看那些在两种配置下都失败或都成功的条目:都成功说明这条太容易、没有信息量,都失败说明要么标注错了要么要求超出模型能力,两类都该换掉。

    Key points

    • The overfitting move is pasting a failing query verbatim; generalize to its category instead.
    • Split roughly sixty-forty and revise only from train-set failures.
    • Keep label balance in both splits and freeze the split across iterations.
    • Select the version by validation pass rate; the best is not always the last.
    • If five rounds change nothing, inspect the query set for triviality, impossibility or mislabeling.

    答题要点

    • 过拟合的具体动作是把失败查询的原话抄进描述,要改成补它代表的那一类说法。
    • 查询集六四拆分,只用训练集指导改写,验证集全程不看。
    • 两个集合都要保持正负比例接近,拆完固定,不要每轮重洗。
    • 按验证集通过率挑版本,最好的那版不一定是最后一版。
    • 五轮不动就停,去查查询集本身是不是太容易、太难或标注错了。

Comments