k-skill 实战:用 korean-character-count 技能对韩文文本做确定性字数/行数/字节数统计
2026/9/18 7:19:33 网站建设 项目流程

k-skill 实战:用 korean-character-count 技能对韩文文本做确定性字数/行数/字节数统计

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

本文以 k-skill 仓库中korean-character-count技能(核心文档位于 packages/k-skill-cli/skills/korean-character-count/instruction.md)为骨架,深入讲解如何对自我介绍书、申请书、自由叙述型表单等"字数限制敏感"的韩文文本进行零 LLM 估算、纯确定性的字符数、行数与字节数统计。读完本文,你将掌握该技能的default/neis两种计数契约、@nomadamas/k-skillCLI 的完整调用方式、JSON/Text 两种输出格式的含义,以及从源码与测试层面验证的底层实现原理。

为什么需要确定性计数:技能存在的前提

在 k-skill 的韩文 Agent 技能体系中,很多场景要求"一字不差"的精确统计:

  • "帮我精确数一下这篇自我介绍有没有超过 1000 字"
  • "按 UTF-8 字节数帮我计算这段文本"
  • "行数和字节数也一起告诉我"
  • "韩文、英文、emoji 混排的句子,不要估算,用代码数"

字数限制往往对 1 个字符的差异都非常敏感,而 LLM 靠"目测"预估字数存在不可复现的问题。因此该技能的设计核心是:不对输入做任何擅自的 trim 或规范化处理,只按照文档化的计数契约进行确定性统计。这与 SKILL.md 中定义的技能定位一致——"Count Korean text deterministically with exact grapheme, line, and byte contracts"。

计数契约:defaultneis两套规则

原文档用两份 Contract 明确定义了计数口径,这是整个技能的"法律条文",本文完整继承并做细化解释。

default契约

维度规则
characters(字符数)基于Intl.Segmenter("ko", { granularity: "grapheme" })的 Unicode extended grapheme cluster
bytes(字节数)Buffer.byteLength(text, "utf8"),即 UTF-8 实际编码长度
lines(行数)空字符串为0;非空字符串为"换行序列个数 +1";CRLF1 次换行计,而非 2 次

也就是说,在default契约下,"字符"不是 JavaScript 的 UTF-16 code unit,也不是 Unicode code point,而是用户感知的一个书写单位(grapheme cluster)。例如由"초성+중성+종성"组合而成的韩文字节序列会被正确合并为 1 个字符;\r\n这种双字节换行序列也只算 1 次换行。

neis契约

neis是专为 NEIS(나이스,韩国教育行政信息系统)/ 学校生活记录簿等需要单独字节规则的提交场景设计的兼容 Profile:

维度规则
charactersdefault相同(仍按 grapheme)
linesdefault相同
bytes韩文 grapheme 计3 字节;ASCII grapheme 计1 字节;Enter/换行序列计2 字节;其余字符回退为 UTF-8 实际字节长度

从源码 korean-character-count/scripts/korean_character_count.js 可以印证这一实现:countNeisGraphemeBytes依次判断"纯 ASCII(1B)"、"含韩文/组合标记(3B)",否则调用countUtf8Bytes做 UTF-8 回退(例如组合附加符\u0301和 emoji🙂都按 UTF-8 实际字节数计)。

环境准备

  • Node.js 18+:必须支持Intl.Segmenter(源码ensureSegmenter()在 Node 18 以下会直接抛错:Intl.Segmenter is required. Use Node.js 18 or newer.,见 korean-character-count/scripts/korean_character_count.js);
  • helper 脚本scripts/korean_character_count.js已随@nomadamas/k-skillCLI 打包;
  • 无需任何 API Key,纯本地确定性计算。

标准工作流

原文档定义的四步流程是 Agent 执行该技能时的主路径:

  1. 直接接收文本,或从文件 / STDIN 读取文本;
  2. 通过npx -y @nomadamas/k-skill@0 exec korean-character-count scripts/korean_character_count.js --执行确定性计数;
  3. 选择需要的 Profile(default/neis)与输出格式(json/text);
  4. 将结果原样返回,并同时告知"是依据哪一套契约统计的"。

注意命令中的--k-skill exec与子命令参数之间的分隔符,其后的--text--file--stdin--profile--format等选项都交给 helper 脚本自身解析。

CLI 用法与完整示例

原文档给出了 5 条可直接复制的示例命令,本文完整保留并补充其行为说明:

# 直接统计内联文本 "가나다"(默认 default 契约,JSON 输出) npx -y @nomadamas/k-skill@0 exec korean-character-count scripts/korean_character_count.js -- --text "가나다" # 统计包含 CRLF 换行与 emoji 的文本($'...' 让 bash 解释 \r\n) npx -y @nomadamas/k-skill@0 exec korean-character-count scripts/korean_character_count.js -- --text $'첫 줄\r\n둘째 줄🙂' # 换用 neis 契约 + text 纯文本输出 npx -y @nomadamas/k-skill@0 exec korean-character-count scripts/korean_character_count.js -- --text $'첫 줄\n둘째 줄🙂' --profile neis --format text # 从文件读取 UTF-8 文本,使用 default 契约 npx -y @nomadamas/k-skill@0 exec korean-character-count scripts/korean_character_count.js -- --file ./essay.txt --profile default # 从 STDIN 管道读取文本,使用 neis 契约 cat essay.txt | npx -y @nomadamas/k-skill@0 exec korean-character-count scripts/korean_character_count.js -- --stdin --profile neis

直接运行源码脚本也支持同样的参数(测试用例即按此方式调用,见 scripts/test_korean_character_count.js):

node scripts/korean_character_count.js --text "가나다" --format json node scripts/korean_character_count.js --file ./essay.txt --profile default node scripts/korean_character_count.js --stdin --profile neis

参数解析规则(源码级)

从 parseArgs 可以看到严格的参数约束:

  • 输入源三者(--text/--file/--stdin必须且只能指定一个,重复或混用会抛出Provide exactly one input source with --text, --file, or --stdin.
  • --profile只接受defaultneis,否则报Unknown profile: ...
  • --format只接受jsontext,否则报Unknown format: ...
  • 未显式指定输入源时:若 stdin 是 TTY(交互终端)则报错,否则自动回退为--stdin模式;
  • --help/-h打印完整帮助信息后退出。

输出字段详解

json格式(默认)返回结构化报告,text格式则逐行输出同样字段。一个完整 JSON 报告的counts对象包含:

字段含义
charactersgrapheme cluster 个数(契约中的"字符数")
characters_without_whitespace去除纯空白 grapheme 后的字符数
code_pointsUnicode code point 个数(Array.from(text).length
utf16_code_unitsJS 字符串length(UTF-16 code unit 数)
lines行数(空串为 0)
bytes当前契约下的字节数(neis时等于bytes_neis,否则等于bytes_utf8
bytes_utf8UTF-8 实际编码字节数
bytes_neisNEIS 兼容规则字节数

同时contract字段会携带本次计数所依据的字符 / 字节 / 行契约描述,Agent 可直接将其原样呈现给用户。例如"韩文/英文/空格/换行/emoji 混排"样本"한🙂\r\n둘째 줄"在测试中统计为 7 个字符、2 行,见 scripts/test_korean_character_count.js。

源码实现剖析:三个核心算法

仓库根目录的 korean-character-count/scripts/korean_character_count.js 是完整实现(另在 packages/k-skill-cli/skills/korean-character-count/scripts/korean_character_count.js 与 scripts/korean_character_count.js 存在 CLI 打包/转发入口,后者require前者并转发main)。

1. 字符计数:grapheme 分词

function segmentGraphemes(text) { return Array.from(ensureSegmenter().segment(text), ({ segment }) => segment); }

Intl.Segmenter以韩语区域设置("ko")、grapheme粒度切分,遵循 Unicode Standard Annex #29(UAX #29)的 extended grapheme cluster 规则,保证组合韩文、带组合符号的字母、emoji 与 ZWJ 序列都被当作单一可见字符。

2. 行数计数:五种换行序列统一折算

const LINE_BREAK_PATTERN = /\r\n|[\n\r\u2028\u2029]/gu;

countLinesCRLFLFCRU+2028(行分隔符)、U+2029(段分隔符)全部视为"1 次换行";空字符串返回0,否则返回匹配次数+1。测试"가\r\n나\r다\u2028라\u2029마"统计为 5 行,正是五种换行序列各计 1 次的结果(见 scripts/test_korean_character_count.js)。

3. NEIS 字节数:逐 grapheme 计价

countNeisBytes先按换行序列切块,每块内的 grapheme 走countNeisGraphemeBytes计价:ASCII 记 1 字节、含韩文/组合标记记 3 字节、其余回退 UTF-8 字节;每个换行序列额外记 2 字节。测试用例给出两个可手算的验证值:

  • countNeisBytes("가A 1\n나🙂") === 15:韩文=3、A=1、空格=1、1=1、换行=2、=3、🙂=4(UTF-8 回退),合计 15;
  • countNeisBytes("한글") === 6countNeisBytes("ABC") === 3

测试验证与质量保障

仓库为该技能提供了完整的 Node 内置测试套件 scripts/test_korean_character_count.js,覆盖:

  • createReport的默认契约统计正确性(grapheme、行数、UTF-8 字节);
  • 五种换行序列(CRLF/CR/LF/U+2028/U+2029)均按 1 次计;
  • NEIS 规则下韩文 3B / ASCII 1B / 换行 2B / 非韩文 UTF-8 回退(如组合符与 emoji);
  • 参数解析的单输入源约束与 profile 校验(混用输入源、重复--text、非法 profile 均报错);
  • CLI 三种输入方式(--text/--file/--stdin)的端到端正确性。

这些用例同时印证了技能文档中 "Done when" 的验收标准:返回结果必须同时包含字符数、行数与字节数;defaultneis的契约差异必须在文档中明确;--help可用;且必须存在混合韩/英/空格/换行/emoji 输入下的测试。

响应策略(Agent 使用规范)

原文档明确了 Agent 输出时的行为边界,本文完整继承:

  • 不要估算,直接使用 helper 结果原样输出;
  • 同时告知用户本次使用的是哪个 Profile;
  • 默认情况下使用default契约;
  • 仅当提交目标(如 NEIS / 学校生活记录簿)明确要求独立契约时,才切换到neis

底层标准参考

实现所依赖的三项公开标准(原文档 Notes 部分):

  • Unicode extended grapheme cluster 规则:Unicode Standard Annex #29(UAX #29);
  • 字符编码规范:WHATWG Encoding Standard;
  • Node.jsBuffer.byteLength语义:Node.js Buffer API 文档。

小结

korean-character-count是 k-skill 中一个"小而精确"的确定性工具型技能:以Intl.Segmenter的 grapheme 切分定义字符数,以统一换行模式折算行数,以 UTF-8 与 NEIS 双契约定义字节数,并通过严格参数校验与自动化测试保证可复现。对任何需要在韩文表单、自我介绍书或 NEIS 提交场景中精确控制文本长度的 Agent 工作流,都可以直接复用本文给出的命令与契约说明。

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询