综合与复盘:把一套团队规范做成 skill 包并驱动子代理完成一次真实任务
把七天学的东西合成一次交付:从一份团队规范文档拆出三个 skill,用子代理隔离执行一次真实任务,用评估验证它确实比不带 skill 强,最后写成一条作品集条目。
今日目标
- 能把一份团队规范文档拆成边界清晰、互不重叠的三个 skill
- 能设计一组评估用例,证明带 skill 与不带 skill 的产出差在哪
- 能把这次交付写成一条经得起追问的作品集条目
最后一天不讲新概念,把前六天的东西合成一次完整交付:拿一份真实的团队规范文档,拆成三个 skill,交给一个干净的子代理去做一件真事,再用一组带断言的评估证明它确实有用——不是感觉更好,是通过率高了多少。最后把这次交付压成一条经得起追问的作品集条目。读完正文、做完实验之后,回到页面顶部把三条目标勾掉。
小白版讲解
交付的是能力,不是文档
先把验收标准说死,否则最后一天很容易做成「又写了几个文件」。
这次交付的成品不是那三份 SKILL.md,是一句能被追问的结论:在某一组任务上,带这个包的产出通过率从多少提升到多少,测量条件是什么。三份 SKILL.md 只是达成这个结论的中间产物。
判断标准也随之明确:一个没有参与过的人,照着你的交付文档,能不能复现出那个数字。 复现不出来的,无论文件写得多漂亮,都还没交付完。
档案柜的比喻最后用一次:前六天你在做柜子、做索引卡、做分发。今天要证明的是这个柜子确实让新人少犯了错——不是「大家都说好用」,是拿同样一批任务,装柜子前和装柜子后,各跑一遍数错误。
从规范文档到三个 skill:按触发场景切,不按章节切
拿到一份团队规范文档,最自然的做法是照着它的目录切:第一章一个 skill、第二章一个 skill。这是最常见的错误。
章节结构是为人的阅读顺序服务的,通常从概念讲到细节;而 skill 的边界必须为触发场景服务——模型是在「用户刚说了一句话」这个时刻决定要不要翻开它的。这两种结构几乎从不重合。
按触发场景切,操作上就三步。
第一步,把文档读一遍,只记「什么时候有人会用到这一段」。 不记内容,只记场景。一份三十页的工程手册,通常能压出十来个场景。
第二步,把场景按「同一个时刻」聚类。 提交信息的格式、类型的取值范围、正文该写什么,这三段在文档里可能分散在三章,但它们都在「我要提交了」这一个时刻被用到——它们是一个 skill。反过来,同一章里讲的「怎么写提交信息」和「怎么拆提交」是两个时刻,得拆开。
第三步,每个聚类各写一句描述,然后检查互斥。 这一步用第三天那套正负例:为每个 skill 写三句会触发它的话,再写两句形似但不该触发的,跑一遍看有没有互相抢。抢了就说明聚类没聚干净,回第二步。
还有一类内容要单独处理:文档里那些确定性的规则——类型只能是这六个、版本号格式必须匹配某个正则。它们更适合按第四天的判据沉淀成一个校验脚本,让 skill 的正文只留一句「写完跑一次校验脚本」。
驱动子代理执行:为什么要隔离一个干净会话
三个 skill 装好了,怎么试?不要在你调试了两小时的那个会话里试。
那个会话的上下文里,早就散落着你刚才手打的规范片段、你纠正过的措辞、你贴过的示例。模型在这种情况下产出得很好,你会以为是 skill 起作用了——实际上是你自己在会话里把答案说了一遍。这是评估 skill 时最常见的自欺。
正确的做法是交给子代理:一个带自己独立上下文窗口的执行者,从一个干净的起点开始,只带上你指定的东西,做完把结果交回来。
它带来三件事,每一件都直接服务于今天的验收。
第一,上下文是干净的。 子代理不继承主会话的对话历史。你在主会话里说过什么、纠正过什么,它一概不知道。这样跑出来的结果,才真的只反映 skill 的作用。
第二,能力可以被精确限定。 子代理的定义里可以声明它能用哪些工具、用哪个模型,也可以直接声明预加载哪几个 skill——这一点对做对照特别有用:带 skill 的那一组明确写上,不带的那一组就留空,其它条件完全一样。
第三,噪音不进主会话。 它把翻文件、试错、跑脚本这些过程留在自己的上下文里,只把结论交回来。
一个子代理的定义就是一份带 frontmatter 的 Markdown,放在约定目录里:
---
name: convention-runner
description: 按团队规范完成提交、评审与发布类任务
tools: Read, Grep, Bash
model: sonnet
skills:
- team-conventions:commit-message
---
你是一个严格按团队规范工作的执行者。只做被要求的那一件事,
不要额外改动文件。产出交回之前,逐条对照规范自查一遍。做对照实验时,两份定义只差 skills 这一行。 其它任何差异——模型不同、工具集不同、提示词多一句——都会让你的结论说不清楚是谁的功劳。
评估:断言怎么写
有了干净的执行环境,接下来是今天技术含量最高的一步:怎么把「更好」变成一个数字。
一个评估用例由三部分组成:一句提示、一份期望产出的描述、以及两到四条可判定的断言。断言是全部重点,写不好断言,这个评估就只是换个地方感慨。
可判定的意思是:不看产出的好坏,只看事实成不成立。 对照一下就很清楚:
- 不可判定:「提交信息写得清楚」「评审意见有价值」——这些还是感觉。
- 可判定:「类型字段取自那六个值之一」「范围字段等于仓库里真实存在的某个目录名」「正文里没有出现 diff 里已有的文件名列表」「首行不超过 50 个字符」。
一条断言最好只查一件事。三条各查一件的断言,比一条查三件的断言有用得多——因为失败时你立刻知道是哪一条挂了。
评估集怎么配比?正例、边界例、负例大约按五比三比二。正例是最常见的用法;边界例是那种「差一点就该触发另一个 skill」的输入;负例是明确不该触发的输入,断言写成「这个 skill 没有被激活」。少了负例,你测不出触发面有没有过宽——而过宽是 skill 最常见的坏法。
跑法很朴素:同一组用例,带 skill 的子代理跑一遍,不带的跑一遍,逐条判定,算两边的通过率。
type Assertion = { id: string; describe: string; check: (output: string) => boolean }
type Case = { id: string; prompt: string; kind: 'positive' | 'boundary' | 'negative'; assertions: Assertion[] }
type Run = { caseId: string; output: string }
export type Report = { total: number; passed: number; rate: number; failures: string[] }
/** 一条用例全部断言都成立才算通过。逐条记失败,因为失败明细才是改 skill 的依据。 */
export function score(cases: Case[], runs: Run[]): Report {
const byCase = new Map(runs.map((r) => [r.caseId, r.output]))
const failures: string[] = []
let passed = 0
for (const c of cases) {
const output = byCase.get(c.id)
if (output === undefined) {
failures.push(`${c.id}:没有这一条的运行记录`)
continue
}
const failed = c.assertions.filter((a) => !a.check(output))
if (failed.length === 0) passed += 1
else failures.push(...failed.map((a) => `${c.id} / ${a.id}:${a.describe}`))
}
return { total: cases.length, passed, rate: passed / cases.length, failures }
}
/** 对照的结论只有一个数:通过率差值。两组必须跑同一批用例。 */
export function compare(withSkill: Report, without: Report): string {
const delta = (withSkill.rate - without.rate) * 100
return `不带 ${(without.rate * 100).toFixed(0)}% → 带 ${(withSkill.rate * 100).toFixed(0)}%,提升 ${delta.toFixed(0)} 个百分点`
}from dataclasses import dataclass
from typing import Callable
@dataclass
class Assertion:
id: str
describe: str
check: Callable[[str], bool]
@dataclass
class Case:
id: str
prompt: str
kind: str # positive | boundary | negative
assertions: list[Assertion]
@dataclass
class Report:
total: int
passed: int
rate: float
failures: list[str]
def score(cases: list[Case], runs: dict[str, str]) -> Report:
"""一条用例全部断言都成立才算通过。逐条记失败,因为失败明细才是改 skill 的依据。"""
failures: list[str] = []
passed = 0
for case in cases:
output = runs.get(case.id)
if output is None:
failures.append(f"{case.id}:没有这一条的运行记录")
continue
failed = [a for a in case.assertions if not a.check(output)]
if not failed:
passed += 1
else:
failures.extend(f"{case.id} / {a.id}:{a.describe}" for a in failed)
total = len(cases)
return Report(total, passed, passed / total if total else 0.0, failures)
def compare(with_skill: Report, without: Report) -> str:
"""对照的结论只有一个数:通过率差值。两组必须跑同一批用例。"""
delta = (with_skill.rate - without.rate) * 100
return f"不带 {without.rate:.0%} → 带 {with_skill.rate:.0%},提升 {delta:.0f} 个百分点"把它写成作品集条目
这次交付值得写进简历,但只有写对了才值得。一条经得起追问的条目有三样东西。
数字,以及它的测量条件。 「用 skill 提升了代码规范一致性」是空话;「在 20 条评审任务上,规范符合率从 55% 提升到 90%,条件是同一模型、同一提示、两组子代理只差是否预加载 skill」是可追问的。只给终值不给起点等于没给。
放弃了什么。 这是整条里唯一抄不来的部分,也是追问最集中的地方。比如「三个 skill 一共只有三百多行,一份三十页手册里的背景与沿革全部没进去——判据是不写这条模型会不会做错」,或者「确定性的格式校验没写进正文,沉淀成了一个脚本」。
为什么不是别的方案。 面试官一定会问「这些规则为什么不直接写进系统提示」。答案在第一天就给过了,今天要能一口气说完:系统提示每一轮都要重发,二十条规范会持续计费;更贵的是注意力,一份塞满不相干规则的系统提示会在做第三件事时被第十七条干扰。skill 的价值不在于装得多,而在于平时都关着。
七天复盘与接下来学什么
回头看这七天的主线:从「一个文件夹」到「一句可被追问的结论」。第一天讲清 skill 是什么,第二天写出第一个能触发的,第三天把写法变成方法,第四天加上脚本,第五天从运行时的角度看清它怎么被加载,第六天让它能交给别人,今天证明它确实有用。
如果只让你带走三句话:
第一,description 是唯一的触发面。 它是这套机制里你唯一每轮都在花钱、也唯一决定成败的那段文字。
第二,能力的缺口用工具补,经验的缺口用技能补。 这一刀切错,后面所有选型都是错的。
第三,确定性交给代码,判断性留给模型。 它同时解释了什么时候写脚本、什么时候写正文。
接下来两条路,都是同批发布的姊妹课,先走哪条取决于你缺什么。
缺接线,去学 MCP。 你现在能把经验交给模型了,但模型手上还没有你们公司的工具与数据。7 天 MCP:把工具接进任何 Agent 从协议三角讲到远程部署与安全治理,第六天那节提示注入与最小权限,是今天这个包真要在团队里铺开时绕不过去的一课。
缺取舍,去学上下文工程。 skill 帮你把不该常驻的东西关起来了,但上下文里还有系统提示、工具结果、检索片段、历史消息在抢位置。5 天上下文工程 讲的就是这盘账怎么算、长会话怎么压缩、失败模式怎么排查——第五天那套 token 账单与利用率的度量方法,可以直接拿来给你今天的评估再加一个维度。
源码导读
动手实验
今天最容易糊弄的是第 3 条。只要两组有第二个差异,你的数字就说不清是谁的功劳——换了模型、多了一个工具、提示词改了半句,都算。动手之前先把两份子代理定义并排放着 diff 一遍,确认只差那一行再开跑。
- 读 solution 的交付文档,先看它的三个 skill 是按什么触发场景切开的。
- 在 starter 里填写规范文档的拆分表,为每个 skill 写边界与不管什么。
- 填写评估用例表,为每个用例写提示、期望产出与两到四条可判定的断言。
- 记录带 skill 与不带 skill 各跑一遍的结果,逐条判定并算出通过率差值。
- 把整个交付压缩成一条作品集条目,每个数字都注明测量条件。
面试题
今天 3 道题在下方题库区,侧重 skill 包的拆分与验收、评估设计与基线对比、以及成果表达。展开后先看「分析过程」再看要点——照着推导练,比背要点管用。标注「国内高频 / 海外高频」方便按目标市场取舍。
检查清单与明日预告
- 能把一份团队规范文档拆成边界清晰、互不重叠的三个 skill
- 能设计一组评估用例,证明带 skill 与不带 skill 的产出差在哪
- 能把这次交付写成一条经得起追问的作品集条目
- 能说清为什么对照实验必须用干净的子代理,而不是在调试过的会话里试
- 实验的 5 条验收标准全部通过
- 3 道面试题不看要点也能答出至少 2 道
七天到这里结束了。回头看第一天那句「一个 skill 就是一个含 SKILL.md 的文件夹」,你现在应该能听出它省略了多少东西——描述怎么写才触发得准、正文分到几层、什么时候该配脚本、运行时怎么把它加载进来、一组 skill 怎么交给一支团队、以及怎么证明它真的有用。格式确实简单,把经验写清楚从来都不简单。 接下来去补你缺的那一半:缺接线走 7 天 MCP,缺取舍走 5 天上下文工程。
面试题库
你怎么证明一个 skill 真的有用,而不是感觉上更好?How do you prove a skill actually helps rather than just feeling better?
国内高频海外高频深入#agent-skills#evaluation#methodology分析过程 · 先想清楚再作答
- 这题在考评估能力,也在考诚实。答「我试了几次感觉好多了」直接出局,面试官要的是一个可复现的对照。
- 先给整体结构:同一批用例、两组只差一个变量、逐条判定、比通过率。**结论只有一个数:通过率差值。**
- 然后讲对照怎么做干净,这是本题最容易被忽略的一半。**绝对不要在你调试了两小时的那个会话里试**——那个上下文里散落着你手打的规范片段和你纠正过的措辞,模型产出得好是因为你自己把答案说了一遍。要用一个上下文干净的子代理,两份定义只差「预加载哪几个 skill」这一行,模型、工具集、提示词全部一致。
- 再讲用例集怎么配:正例、边界例、负例大约五比三比二。负例不能省,它测的是触发面有没有过宽,而**过宽是 skill 最常见的坏法**——少了负例,一个什么都抢的 skill 也能拿满分。
- 断言是全部重点。可判定的意思是不看好坏、只看事实成不成立:「类型字段取自那六个值之一」「范围等于仓库里真实存在的目录名」「首行不超过 50 个字符」是可判定的;「写得清楚」不是。一条断言只查一件事,失败时才知道是哪一条挂了。
- 最后补诚实这一层:有些判断写不出可靠断言,比如「这条评审意见有没有抓住真问题」。硬凑只会得到假绿,老实标成人工判定、抽查几条、并在结论里注明有几条是人工判的。**一份诚实的部分自动化评估远好过一份全绿的假评估。**
- 可预期的追问是「样本量这么小,结论站得住吗」。答话要坦率:小样本只能支撑「在这一批任务上」的结论,所以每个数字都要带测量条件,不要外推成通用效率提升。
How to reason about it · think before answering
- This tests evaluation skill and honesty. Saying it felt better ends the answer; the interviewer wants a reproducible comparison.
- Give the structure first: one set of cases, two arms differing in exactly one variable, per-assertion judging, and a pass-rate comparison. The conclusion is a single number, the delta.
- Then explain how to keep the comparison clean, the half most people skip. Never test in the session you spent two hours debugging: that context is littered with convention snippets you typed and corrections you made, so good output reflects you, not the skill. Use a fresh subagent, with the two definitions differing only in which skills are preloaded.
- Describe the case mix: positive, boundary and negative roughly five to three to two. Negatives are non-negotiable because they measure whether the trigger surface is too wide, which is the most common way a skill goes wrong. Without them, a skill that grabs everything scores perfectly.
- Assertions are the core. Decidable means checking facts, not quality: the type field is one of six values, the scope equals a real directory in the repository, the first line is under fifty characters. Written clearly is not decidable. One assertion checks one thing so failures point somewhere.
- Close on honesty: some judgments resist reliable assertions, such as whether a review comment found the real problem. Forcing an assertion yields false green. Mark those as human-judged, sample a few, and say so in the conclusion.
- Expected follow-up: does a small sample support the claim? Be candid. A small sample supports a claim about that batch of tasks only, so every number carries its measurement conditions and is never extrapolated into a general efficiency gain.
答题要点
- 同一批用例、两组只差一个变量、逐条判定、比通过率差值。
- 对照必须用上下文干净的子代理,不能在调试过的会话里试。
- 两份子代理定义只差预加载 skill 那一行,模型、工具、提示词全部一致。
- 用例要含负例,它测触发面有没有过宽,过宽是最常见的坏法。
- 断言要可判定、一条只查一件事;判不了的老实标人工判定并在结论里注明。
Key points
- Same cases, two arms differing in one variable, judged per assertion, compared by pass rate.
- The comparison needs a context-clean subagent, never the session you debugged in.
- The two subagent definitions differ only in preloaded skills; model, tools and prompt are identical.
- Include negative cases: they measure an over-wide trigger surface, the most common failure.
- Assertions must be decidable and single-purpose; mark human-judged cases honestly in the conclusion.
一份三十页的团队规范文档要拆成几个 skill,按什么切?How many skills should a thirty-page team convention document become, and how do you split it?
国内高频海外高频进阶#agent-skills#design#decomposition分析过程 · 先想清楚再作答
- 这题看着开放,其实有明确的对错。答「按章节切」几乎必错,能说清为什么错才是拿分点。
- 先给错的那条:**章节结构是为人的阅读顺序服务的**,通常从概念讲到细节;而 skill 的边界必须为触发场景服务——模型是在「用户刚说了一句话」这个时刻决定要不要翻开它。这两种结构几乎从不重合。
- 然后给正确的三步。第一步通读文档,只记「什么时候有人会用到这一段」,记场景不记内容,三十页通常能压出十来个场景。
- 第二步把场景按**同一个时刻**聚类。提交信息的格式、类型的取值、正文写什么,可能分散在三章里,但都在「我要提交了」这一刻被用到,它们是一个 skill;同一章里的「怎么写提交信息」和「怎么拆提交」是两个时刻,要拆开。
- 第三步为每个聚类写一句描述并检查互斥:各写三句会触发的话、两句形似但不该触发的话,跑一遍看有没有互相抢。**抢了说明聚类没聚干净,回第二步。**
- 还要主动说一件面试官爱追问的事:**文档里有一大半内容不该进任何 skill**。背景、沿革、当初为什么这么定,对人有价值,对模型是纯负担。判据仍是「不写这条,模型会不会做错」。三十页压成三四百行是正常的。
- 最后补一类特殊内容:确定性的规则(类型只能是这六个、版本号必须匹配某个格式)更适合沉淀成校验脚本,正文只留一句「写完跑一次校验」。
- 可预期的追问是「到底该切几个」。答案是数量由聚类结果决定而不是先定,但如果切出七八个还互相抢,通常是场景记得太细了;如果只切出一个,说明你还是按文档整体在想。
How to reason about it · think before answering
- It sounds open-ended but has a clear wrong answer. Splitting by chapter is almost always wrong, and explaining why is where the points are.
- Chapter structure serves a human reading order, usually concept then detail. A skill boundary must serve the trigger moment, because the model decides whether to open it right after the user speaks. The two structures rarely coincide.
- Give three steps. First, read the document recording only when someone would need each passage. Record situations, not content; thirty pages usually yields a dozen situations.
- Second, cluster situations by shared moment. Commit message format, allowed types and body content may sit in three chapters but all apply at the moment of committing, so they are one skill. Writing a commit message and splitting commits share a chapter but are two moments, so they split.
- Third, write one description per cluster and test mutual exclusivity with three triggering phrases and two near-miss non-triggers each. If they compete, the clustering is not clean; go back to step two.
- Raise something interviewers probe: most of the document belongs in no skill. Background and history matter to people and are pure overhead for a model. The test remains whether omitting a line would make the model get it wrong. Thirty pages compressing to a few hundred lines is normal.
- Add the special case: deterministic rules such as an allowed type set or a version format belong in a validation script, leaving the body to say run the validator.
- Expected follow-up: how many exactly? The count follows the clustering. Seven or eight that still compete usually means the situations were recorded too finely; exactly one means you were still thinking about the document as a whole.
答题要点
- 不能按章节切,章节服务人的阅读顺序,skill 边界服务触发时刻。
- 三步:只记使用场景、按同一个时刻聚类、写描述并用正负例查互斥。
- 互相抢说明聚类没聚干净,要退回重聚,不是改描述糊过去。
- 文档里一大半内容不进任何 skill,判据是不写这条模型会不会做错。
- 确定性规则沉淀成校验脚本,正文只留一句跑校验。
Key points
- Do not split by chapter: chapters serve reading order, skill boundaries serve trigger moments.
- Three steps: record situations, cluster by shared moment, write descriptions and test with positive and negative examples.
- Competing descriptions mean bad clustering; go back rather than patching the wording.
- Most of the document enters no skill; the test is whether omitting it would cause a mistake.
- Deterministic rules become a validation script, leaving one line in the body.
让子代理带着 skill 去执行任务,和在主会话里执行有什么区别?What is the difference between running a task in a subagent with skills and running it in the main session?
国内高频海外高频深入#agent-skills#subagent#evaluation分析过程 · 先想清楚再作答
- 这题考的是上下文隔离的价值,答得浅会变成「子代理就是开个新会话」。要说清它带来的三件事,以及每一件对应什么问题。
- 第一件是**上下文干净**。子代理不继承主会话的对话历史,你说过什么、纠正过什么它一概不知道。这一条在做评估时是决定性的:在调试了两小时的会话里试 skill,模型产出得好往往是因为你自己在会话里把答案说了一遍,这是评估 skill 时最常见的自欺。
- 第二件是**能力可以精确限定**。子代理定义里能声明可用工具、模型,也能直接声明预加载哪几个 skill。做对照时两份定义只差这一行,其它完全一致——任何第二个差异都会让结论说不清是谁的功劳。
- 第三件是**噪音不进主会话**。翻文件、试错、跑脚本这些过程留在子代理自己的上下文里,只把结论交回来。主会话的窗口因此能留给真正要连贯推进的那条线。
- 还要说清代价,只说好处会显得没做过。子代理拿不到主会话的上下文,意味着**交接摘要要写清楚**,任务描述含糊时它比主会话更容易跑偏;而且它多跑一遍系统提示与技能目录,不是免费的。
- 补一个实现细节能显出实感:skill 进子代理有两条路,一是在定义里预加载、启动时就注入完整正文,二是让它在执行中自己发现并激活。做对照实验用预加载,因为它把变量固定住了;做真实任务用自动发现,更接近日常。
- 可预期的追问是「什么时候不该用子代理」。答案是任务需要跟用户来回确认、或强依赖前面几十轮的上下文时——隔离带来的干净,这时候正好是缺陷。
How to reason about it · think before answering
- This tests the value of context isolation. A shallow answer reduces it to opening a new session. Name three effects and the problem each solves.
- First, a clean context. A subagent does not inherit the main conversation, so it knows nothing you said or corrected. This is decisive for evaluation: testing a skill in a session you debugged for two hours usually measures your own hints, the most common self-deception here.
- Second, precisely bounded capability. A subagent definition can declare its tools, its model, and which skills to preload. For a controlled comparison the two definitions differ only in that line, because any second difference makes the result unattributable.
- Third, noise stays out. File reading, trial and error and script runs live in the subagent's own context, and only the conclusion comes back, leaving the main window for the thread that must stay coherent.
- Name the costs too. Without the main context, the handoff prompt must be explicit, and a vague task description sends a subagent off course faster than the main session. It also pays for its own system prompt and skill catalog.
- An implementation detail shows real experience: skills reach a subagent either by preloading in the definition, which injects the full body at startup, or by letting it discover and activate them during execution. Use preloading for controlled comparisons and discovery for real work.
- Expected follow-up: when should you not use one? When the task needs back-and-forth with the user or depends heavily on dozens of earlier turns. There, isolation is the defect rather than the feature.
答题要点
- 子代理有独立上下文窗口,不继承主会话历史,这是做干净对照的前提。
- 定义里能限定工具、模型与预加载的 skill,对照时两份定义只差那一行。
- 过程噪音留在子代理里,只把结论交回主会话。
- 代价是交接摘要必须写清楚,任务含糊时更容易跑偏,且多付一次系统提示的开销。
- 预加载适合做对照实验,自动发现更接近真实使用;需要与用户反复确认的任务不适合隔离。
Key points
- A subagent has its own context window and no inherited history, which is what makes a clean comparison possible.
- Its definition bounds tools, model and preloaded skills, so a controlled pair differs in one line.
- Process noise stays inside the subagent; only the conclusion returns.
- The costs are an explicit handoff prompt, more drift on vague tasks, and paying for another system prompt.
- Preload for controlled experiments, discovery for real work, and skip isolation when the task needs user back-and-forth.
评论
登录后即可参与讨论
还没有评论,来说第一句。