ja-llm-guard 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GX Cafe LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # ja-llm-guard
2
+
3
+ 日本語LLM出力の「**読めるのに壊れている**」を機械で拾う出口検査。依存ゼロ・MIT。
4
+
5
+ ```bash
6
+ npx ja-llm-guard "検査したいテキスト"
7
+ cat output.txt | npx ja-llm-guard # 終了コード 0=合格 / 1=検知(CIの関所にそのまま置ける)
8
+ ```
9
+
10
+ ```js
11
+ const { check } = require('ja-llm-guard');
12
+ check('本日会議議事録送付確認依頼。');
13
+ // => [ 'kana_ratio_low:0.00<0.15' ] ← かなゼロの「日本語」は壊れの信号
14
+ ```
15
+
16
+ ## なぜ要るか(実測から)
17
+
18
+ ローカルLLM上で自律エージェント群を24時間動かし、**63日間で8853件の失敗**を
19
+ 記録した。その中で「言語の壊れ」系は:
20
+
21
+ | 実測件数 | 型 |
22
+ |---|---|
23
+ | 993 | 日英が無意味に混線した出力 |
24
+ | 414 | 日本語文への中国語(簡体字)混入 |
25
+ | 184 | 日本語で返ってこない |
26
+
27
+ これらは文字列としては正常に「読める」ので、**例外にもならずログにも何も出ない**。
28
+ 多言語モデル(Qwen系など)を日本語業務に載せると、英語圏では起きない壊れ方をする。
29
+
30
+ ## 2つの検査(本番で実際に故障を捕まえた形だけ)
31
+
32
+ 1. **かな比率** — ひらがな・カタカナがゼロの「日本語文」は最も安く最も強い壊れの信号。
33
+ 正常な日本語ビジネス文の実測はおおむね0.3〜0.6(既定の閾値は0.15)
34
+ 2. **簡体字混入** — 「CJKかどうか」の検査は日中両方を通してしまう。日本語の新字体に
35
+ 存在しない簡体字だけのコードポイント(们・这・时 など)を名指しで見る
36
+
37
+ ## フル版
38
+
39
+ 敬体・常体の混在検査、見張り・関所テンプレ8本(cron欠落検知・出力契約・承認キュー・
40
+ 心拍ほか)、わざと壊すBREAK試験込みの試験28本を同梱した
41
+ **Harness Templates Pro 日本語版(見張り・関所テンプレ8本+日本語出力検査)**(¥49,800(税抜)・単一組織の商用ライセンス)を提供しています。
42
+ お問い合わせ: **sales@gxcafe.co.jp**(件名に「日本語版テンプレ」とお書きください)
43
+
44
+ 運営: GX Cafe合同会社([特定商取引法に基づく表記](https://gxcafe.co.jp/tokushoho/))
@@ -0,0 +1,44 @@
1
+ # ja-llm-guard
2
+
3
+ 日本語LLM出力の「**読めるのに壊れている**」を機械で拾う出口検査。依存ゼロ・MIT。
4
+
5
+ ```bash
6
+ npx ja-llm-guard "検査したいテキスト"
7
+ cat output.txt | npx ja-llm-guard # 終了コード 0=合格 / 1=検知(CIの関所にそのまま置ける)
8
+ ```
9
+
10
+ ```js
11
+ const { check } = require('ja-llm-guard');
12
+ check('本日会議議事録送付確認依頼。');
13
+ // => [ 'kana_ratio_low:0.00<0.15' ] ← かなゼロの「日本語」は壊れの信号
14
+ ```
15
+
16
+ ## なぜ要るか(実測から)
17
+
18
+ ローカルLLM上で自律エージェント群を24時間動かし、**{{days}}日間で{{records}}件の失敗**を
19
+ 記録した。その中で「言語の壊れ」系は:
20
+
21
+ | 実測件数 | 型 |
22
+ |---|---|
23
+ | {{nBrokenLanguageMix}} | 日英が無意味に混線した出力 |
24
+ | {{nChineseInJapanese}} | 日本語文への中国語(簡体字)混入 |
25
+ | {{nNotJapanese}} | 日本語で返ってこない |
26
+
27
+ これらは文字列としては正常に「読める」ので、**例外にもならずログにも何も出ない**。
28
+ 多言語モデル(Qwen系など)を日本語業務に載せると、英語圏では起きない壊れ方をする。
29
+
30
+ ## 2つの検査(本番で実際に故障を捕まえた形だけ)
31
+
32
+ 1. **かな比率** — ひらがな・カタカナがゼロの「日本語文」は最も安く最も強い壊れの信号。
33
+ 正常な日本語ビジネス文の実測はおおむね0.3〜0.6(既定の閾値は0.15)
34
+ 2. **簡体字混入** — 「CJKかどうか」の検査は日中両方を通してしまう。日本語の新字体に
35
+ 存在しない簡体字だけのコードポイント(们・这・时 など)を名指しで見る
36
+
37
+ ## フル版
38
+
39
+ 敬体・常体の混在検査、見張り・関所テンプレ8本(cron欠落検知・出力契約・承認キュー・
40
+ 心拍ほか)、わざと壊すBREAK試験込みの試験28本を同梱した
41
+ **{{productProJaName}}**({{priceProJa}}・単一組織の商用ライセンス)を提供しています。
42
+ お問い合わせ: **sales@gxcafe.co.jp**(件名に「日本語版テンプレ」とお書きください)
43
+
44
+ 運営: GX Cafe合同会社([特定商取引法に基づく表記](https://gxcafe.co.jp/tokushoho/))
package/cli.js ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // 使い方:
4
+ // npx ja-llm-guard "検査したいテキスト"
5
+ // cat output.txt | npx ja-llm-guard
6
+ // 終了コード: 0=合格 / 1=壊れを検知(CIやパイプラインの関所にそのまま置ける)
7
+ const { check } = require('./index.js');
8
+
9
+ function run(text) {
10
+ const fails = check(text);
11
+ if (!fails.length) {
12
+ console.log('✓ 合格(かな比率OK・簡体字混入なし)');
13
+ process.exit(0);
14
+ }
15
+ console.log('✗ 壊れを検知:');
16
+ for (const f of fails) console.log(' - ' + f);
17
+ process.exit(1);
18
+ }
19
+
20
+ const arg = process.argv.slice(2).join(' ');
21
+ if (arg) { run(arg); } else if (!process.stdin.isTTY) {
22
+ let buf = '';
23
+ process.stdin.on('data', (d) => { buf += d; });
24
+ process.stdin.on('end', () => run(buf));
25
+ } else {
26
+ console.log('使い方: npx ja-llm-guard "テキスト" もしくは cat file | npx ja-llm-guard');
27
+ process.exit(2);
28
+ }
package/index.js ADDED
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+ /**
3
+ * ja-llm-guard — 日本語LLM出力の「読めるのに壊れている」を機械で拾う無料ミニ検査(MIT)
4
+ *
5
+ * 出所: GX Cafe の本番ハーネス(ローカルLLM上の自律エージェント群・24時間稼働)の実測。
6
+ * 63日で記録した失敗 8,853件のうち、言語の壊れ系は
7
+ * broken_language_mix 993 / chinese_in_japanese 414 / not_japanese 184。
8
+ * どれも文字列としては正常に「読める」ので、例外にならず検知もされない。
9
+ *
10
+ * 2つの検査(本番で実際に故障を捕まえた形だけを載せる):
11
+ * 1. かな比率 — ひらがな・カタカナがゼロの「日本語文」は最も安く最も強い壊れの信号。
12
+ * 2. 簡体字混入 — 「CJKかどうか」の検査は日中両方を通す。日本語の字体に無い
13
+ * 簡体字だけのコードポイントを名指しで見る(们・这・时 など)。
14
+ *
15
+ * フル版(敬体・常体の混在検査+見張り・関所テンプレ8本+試験28本)は
16
+ * Harness Templates Pro 日本語版として提供している(README参照)。
17
+ */
18
+
19
+ // 日本語の新字体には存在しない、簡体字だけの代表的コードポイント(誤検知しない字だけを載せる)
20
+ const SIMPLIFIED_ONLY = '们这应该现经说对发让见时间为样长东习头处务议论语读门问题击认识记级别战术运还进过买卖马';
21
+
22
+ /** かな比率。null = 日本語の文字が無い(言語そのものが違う疑い) */
23
+ function kanaRatio(text) {
24
+ const t = String(text || '');
25
+ const kana = (t.match(/[ぁ-ゖァ-ヺー]/g) || []).length;
26
+ const cjk = (t.match(/[ぁ-ゖァ-ヺー一-鿿]/g) || []).length;
27
+ return cjk === 0 ? null : kana / cjk;
28
+ }
29
+
30
+ /** 混入している簡体字(ユニーク)を返す。空配列=混入なし */
31
+ function simplifiedHits(text) {
32
+ const t = String(text || '');
33
+ const hits = new Set();
34
+ for (const ch of t) if (SIMPLIFIED_ONLY.includes(ch)) hits.add(ch);
35
+ return [...hits];
36
+ }
37
+
38
+ /**
39
+ * 検査の本体。fails配列を返す(空=合格)。
40
+ * opts.minKanaRatio 既定0.15(実測: 正常な日本語ビジネス文はおおむね0.3〜0.6)
41
+ */
42
+ function check(text, opts = {}) {
43
+ const fails = [];
44
+ const t = String(text || '');
45
+ if (!t.trim()) return ['empty'];
46
+
47
+ const ratio = kanaRatio(t);
48
+ const minKana = opts.minKanaRatio ?? 0.15;
49
+ if (ratio === null) fails.push('no_japanese_chars');
50
+ else if (ratio < minKana) fails.push(`kana_ratio_low:${ratio.toFixed(2)}<${minKana}`);
51
+
52
+ const simp = simplifiedHits(t);
53
+ if (simp.length) fails.push(`simplified_chinese:${simp.slice(0, 8).join('')}`);
54
+
55
+ return fails;
56
+ }
57
+
58
+ module.exports = { check, kanaRatio, simplifiedHits, SIMPLIFIED_ONLY };
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "ja-llm-guard",
3
+ "version": "0.1.0",
4
+ "description": "日本語LLM出力の『読めるのに壊れている』を機械で拾う出口検査(かな比率・簡体字混入)。実測8,853件の失敗ログから抽出。依存ゼロ。",
5
+ "license": "MIT",
6
+ "bin": { "ja-llm-guard": "cli.js" },
7
+ "main": "index.js",
8
+ "files": ["index.js", "cli.js", "README.md", "LICENSE"],
9
+ "keywords": ["japanese", "llm", "guardrails", "validation", "日本語", "ローカルLLM"],
10
+ "author": "GX Cafe LLC",
11
+ "repository": { "type": "git", "url": "https://gxcafe.co.jp/" }
12
+ }