HN 日本語サマリー

← 一覧へ戻る
科学・技術

Appleの単語リストをダンプした

I dumped Apple’s word list (helgesver.re)

113 pointsby speckx53 コメント

要約

この記事では、macOSのシステム辞書に含まれる単語にAppleがどのように「下品」「攻撃的」「機密」といったフラグを付けているかを調査しています。著者はプライベートAPIを通じてこれらのフラグを抽出し、特に「トランプ」という単語が他の故人やテロリストと共に「機密」カテゴリに分類されていることを発見しました。この分類は、キーボードの予測候補表示に影響を与える可能性があり、特定の単語の不適切なサジェストを防ぐためのものだと推測されています。

全文翻訳

Appleの単語リストをダンプした

2026年11月3日

TL;DR

  • ~/Library/Keyboard/VulgarWordUsage.db は実在します。これはアプリごと、受信者ごとに、どの下品な単語を使用するかを記録し、オートコレクトがあなたを「ducking」するのを防ぐように学習します。私のMacでは空で、ネイティブアプリに下品な単語を入力しても埋まりませんでした。
  • 興味深いのはアップストリームです。Appleのシステム辞書は、各単語に3つのティア(下品、攻撃的、機密)と最大11個のトピックフラグ(性、薬物、宗教、政治、暴力など)を付けています。
  • これらに対する公開APIはありません。私はLexicon.frameworkのいくつかのプライベートC関数でフラグを読み取りました。コードはCとSwiftで以下にあります。15言語の完全なダンプはこのgistにあります(検閲なし、コンテンツに関する注意書きを参照)。
  • ハイライト:オイディプスは下品です。トムとミックは攻撃的です。pee、poo、niggle、underlingは機密です。そして「トランプ」は、ヒトラー、毛沢東、ウサマ・ビンラディン、タリバンと共に、英語の機密ティアにおける唯一の現役政治家です。バイデン、オバマ、プーチンはクリーンです。

コンテンツに関する注意:この記事では、単語が下品かどうかの全体像を示すために、スラーを含む単語を検閲なしで印刷します。例外はnワードです。これは英語や他のいくつかの言語のリストに含まれていますが、私はそれを書き出すつもりはありません。

ツイートから始まった

[画像: Nick (@nicksdot) によるツイート:「TIL: macOSには、私たちの冒涜の使用を追跡するデータベースがあります」と表示され、Finderにuser_model_database.sqlite-walとVulgarWordUsage.dbが表示されている。Helgeが「どこにありますか?」と返信し、Nickが「~/Library/Keyboard/VulgarWordUsage.db」と答えている。]

Nickがこれを投稿しました。私はその場所を尋ね、彼は答えました。私の冒涜を追跡するデータベースは、私が放置できるものではありませんでした。そこで私は自分のものを見てみました。

データベース

$ sqlite3 -readonly ~/Library/Keyboard/VulgarWordUsage.db .schema
CREATE TABLE properties (ROWID INTEGER PRIMARY KEY, key, value, UNIQUE (key));
CREATE TABLE IF NOT EXISTS "vword_usage" (
    ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
    app                          TEXT, -- app identifier
    recipient                    TEXT, -- recipient identifier
    vword                        TEXT, -- vulgar word
    word_reading                 TEXT, -- the reading form of a word (relevant for Japanese)
    usage_count                  INTEGER DEFAULT 0,
    last_use_timestamp           REAL DEFAULT 0, -- last use timestamp (seconds since the reference date)
    journaled
);
CREATE UNIQUE INDEX app_recipient_vword_word_reading_idx ON vword_usage(app, recipient, vword, word_reading);

これにより、キーボードは、あなたが特定の友人に対してMessagesでfuckと言うが、上司へのMailでは言わないことを知ることができます。ユニークインデックスは(app, recipient, word, reading)にあり、それが粒度です。

私のものには行がゼロ件あります。propertiesテーブルにはversion = 2とそれ以外は何も保持されていません。ファイルは2024年4月に最後に書き込まれました。

何のためにあるのか

2023年6月のWWDCで、Craig FederighiはiOS 17のオートコレクト書き換えをこの言葉で発表しました:「あなたがただダッキングしたい単語をタイプしたい瞬間には、キーボードもそれを学習します。」(TechCrunch, NPR)。

このデータベースは、それが学習する方法です。macOSの共有ライブラリキャッシュ内のシンボル名は、フローを物語っています:

TI::VulgarWordUsageDatabaseWrapper::set_current_app_id(CFString)
TI::VulgarWordUsageDatabaseWrapper::set_current_recipient_ids(vector<string>)
TI::VulgarWordUsageDatabaseWrapper::increment_usage_count(word, reading, recipients)
TI::VulgarWordUsageDatabaseWrapper::decrement_usage_count(...)
TI::VulgarWordUsageDatabaseWrapper::can_autocorrect(word, app, recipients)
TI::VulgarWordUsageDatabaseWrapper::can_autocorrect_somewhere(word, reading)
KB::FilterNonVulgarIfTopCandidateVulgar::filter_candidates(...)
KB::Candidate::every_vulgar_word_is_allowlisted(VulgarWordUsageDatabaseWrapper*, ...)

さらに、Passing recipient IDs to the vulgar word usage database wrapper; number of IDs: %luのようなログ文字列もあります。

平易な言葉で言うと:

  1. あなたがタイプを始めると、キーボードエンジンはラッパーに、あなたがどのアプリにいて、誰に書いているかを伝えます。
  2. 下品な単語をタイプしてそれを保持すると、その単語のカウントがそのアプリと受信者に対して増加します。単語を元に戻すと、カウントは元に戻ります。
  3. エンジンが候補をランク付けする際、候補内のすべての下品な単語がこのコンテキストで許可されているかどうかを尋ねます。許可されていない場合、クリーンな代替案が勝ちます:ダッキング。

_KSUserSynchroniser sharedAcrossLanguagesVulgarWordUsageValueというシンボルは、他の学習済み単語のようにデバイス間で同期することを示唆しています。

私のは空です

それを埋めようとしました。agent-desktopを使用して、新しいTextEditドキュメントを開き、well fuck this shit, damn it.とタイプしました。まずテキスト挿入として、次に個々のキープレスとして。何も変わりませんでした:行もログ行もなく、ファイルの変更日は2024年のままでした。

理由はわかりませんし、解明できませんでした。おそらくMacはここで何も記録しないか、あるいは特定のアプリや設定でのみ記録するのかもしれません。もしあなたのものに行があるなら、何をしましたか教えてください。

それは短い記事になるでしょう。しかし、データベースはすでに下品だと知られている単語しかカウントしません。では、誰がそれを決めるのでしょうか?

単語リストはどこにあるのか

dyld共有キャッシュで「vulgar」を検索すると、LXプレフィックス(LXVulgarWordUsageDatabaseCreate, LXVulgarWordUsageDatabaseCanAutocorrect, …)を持つC APIと、より有用なことに、辞書エントリ上の2つの関数が見つかりました:

_LXEntryGetCategoryFlags
_LXEntryGetMetaFlags

LXはLexicon.framework、つまり/System/Library/LinguisticData/の下にある言語ごとの辞書を読むプライベートフレームワークです。それらの辞書のすべての単語は、2つの32ビットフラグフィールドを持つLXEntryです。下品さの評価があるとしたら、それはそれらのビットの中にあります。

公開APIはない

調べました。NSSpellChecker, UITextChecker, NaturalLanguage, UILexiconは下品さを公開していません。SensitiveContentAnalysisは画像とビデオをカバーしますが、テキストはカバーしません。「profanity」という言葉がdeveloper.apple.comに現れる唯一の場所は、App Storeの年齢評価とレビューガイドラインです。

したがって:プライベート関数です。Lexiconにはヘッダーがありませんが、C関数はエクスポートされており、CoreFoundationの規約に従っているため、そのシグネチャを推測するのは簡単です。このプログラムは、ロケールの辞書を開き、すべてのエントリをウォークし、両方のフラグフィールドを印刷します:

// lx.c — dump every word in a system lexicon with its flags.
// clang -O1 -o lx lx.c -F/System/Library/PrivateFrameworks -framework Lexicon -framework CoreFoundation
#include <CoreFoundation/CoreFoundation.h>
#include <stdbool.h>
#include <stdio.h>

typedef const void *LXLexiconRef, *LXCursorRef, *LXEntryRef;
extern CFStringRef kLXLexiconLocaleKey;
LXLexiconRef LXLexiconCreate(CFDictionaryRef options, CFErrorRef *error);
LXCursorRef  LXLexiconCreateRootCursor(LXLexiconRef);
void         LXCursorEnumerateEntriesRecursively(LXCursorRef, void (^)(LXEntryRef, bool *stop));
CFStringRef  LXEntryCopyString(LXEntryRef);
uint32_t     LXEntryGetCategoryFlags(LXEntryRef);
uint32_t     LXEntryGetMetaFlags(LXEntryRef);

int main(int argc, char **argv) {
  CFStringRef locale = CFStringCreateWithCString(NULL, argc > 1 ? argv[1] : "en_US", kCFStringEncodingUTF8);
  const void *keys[] = {kLXLexiconLocaleKey}, *values[] = {locale};
  CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, &kCFTypeDictionaryKeyCallBacks,
                                               &kCFTypeDictionaryValueCallBacks);
  LXLexiconRef lexicon = LXLexiconCreate(options, NULL);
  if (!lexicon) return 1;

  LXCursorEnumerateEntriesRecursively(LXLexiconCreateRootCursor(lexicon), ^(LXEntryRef entry, bool *stop) {
    char word[512] = "";
    CFStringRef s = LXEntryCopyString(entry);
    if (s) { CFStringGetCString(s, word, sizeof word, kCFStringEncodingUTF8); CFRelease(s); }
    printf("%08x\t%08x\t%s\n", LXEntryGetCategoryFlags(entry), LXEntryGetMetaFlags(entry), word);
  });
}
$ ./lx en_US | wc -l
  199019
$ ./lx en_US | awk -F'\t' '$3 == "fuck" || $3 == "table" || $3 == "Trump"'
00000000	00800002	fuck
00000000	00000000	table
00002000	02000081	Trump

Swiftでの同じこと。プライベートフレームワークにリンクする必要がないように、dlopenとdlsymで実行時に関数をロードします。ティアのいずれかを持つ単語のみを印刷します:

// lexflags.swift — swiftc -O lexflags.swift -o lexflags && ./lexflags en_US
import Foundation

let lexicon = dlopen("/System/Library/PrivateFrameworks/Lexicon.framework/Lexicon", RTLD_NOW)!
func sym<T>(_ name: String, as _: T.Type) -> T { unsafeBitCast(dlsym(lexicon, name)!, to: T.self) }

typealias LXRef = UnsafeRawPointer
let create     = sym("LXLexiconCreate", as: (@convention(c) (CFDictionary, UnsafeMutablePointer<Unmanaged<CFError>?>?) -> LXRef?).self)
let rootCursor = sym("LXLexiconCreateRootCursor", as: (@convention(c) (LXRef) -> LXRef?).self)
let enumerate  = sym("LXCursorEnumerateEntriesRecursively", as: (@convention(c) (LXRef, @convention(block) (LXRef, UnsafeMutablePointer<Bool>) -> Void) -> Void).self)
let copyString = sym("LXEntryCopyString", as: (@convention(c) (LXRef) -> Unmanaged<CFString>?).self)
let metaFlags  = sym("LXEntryGetMetaFlags", as: (@convention(c) (LXRef) -> UInt32).self)
let category   = sym("LXEntryGetCategoryFlags", as: (@convention(c) (LXRef) -> UInt32).self)
let localeKey  = dlsym(lexicon, "kLXLexiconLocaleKey")!.load(as: CFString.self)

let locale = CommandLine.arguments.dropFirst().first ?? "en_US"
guard let lex = create([localeKey: locale] as CFDictionary, nil), let root = rootCursor(lex) else {
    fatalError("could not open lexicon for \(locale)")
}

let tiers: [(UInt32, String)] = [(0x0080_0000, "vulgar"), (0x0100_0000, "offensive"), (0x0200_0000, "sensitive")]
enumerate(root) { entry, _ in
    let meta = metaFlags(entry)
    guard let tier = tiers.first(where: { meta & $0.0 != 0 })?.1,
          let word = copyString(entry)?.takeRetainedValue() else { return }
    print(tier, String(format: "%05x", category(entry)), word, separator: "\t")
}

どちらも読み取り専用です。キーボードが使用するのと同じ辞書を開き、それを印刷します。

ビットのデコード

Appleはこれらのフラグを文書化していないため、以下のすべての意味は推測です。ビットごとに単語をグループ化し、各グループのテーマが明らかになるまでサンプルを読みました。システムコードは、そのうちの1つに役立ちます。offensiveVulgarSensitiveという列挙型ケースが、下品な単語コードのすぐ隣にあり、3つの隣接するメタビットがそれに一致します。

3つのティア(メタフラグ)
ビットティアen_US 単語例
0x00800000下品1,050fuck, shit, cunt, cock, crap, wtf, fml, bullshitting, fucktard, shizzle, merde
0x01000000攻撃的663kike, wop, dago, fag, Paki, japs, Klansman, retard, Oriental, ass, asshole
0x02000000機密2,558damn, bitch, idiot, LSD, abortion, gun, suicide, anus, pee, poo

en_USでは、単語は最大で1つのティアを持ちます:それらは決して重複しません。199,019エントリのうち、4,271が1つのティアを持っています。

大まかに言うと:下品は罵り言葉と性的なスラング、攻撃的は集団に向けられたスラー、そして機密はキーボードが不意に提供すべきではないすべてです:軽い罵り言葉、侮辱、薬物、武器、過激主義、病気、身体機能。

トピック(カテゴリフラグ)

もう一方のフィールドはトピックビットマスクであり、単語は複数のトピックを持つことができます:

ビットトピックen_US 単語例
0x00100排泄123feces, barf, crapper, piddle, pooped
0x00200体の部分958nipples, navel, buttock, perineum, triceps
0x00400侮辱、アイデンティティ関連823idiot, cretin, hick, pleb, sexist, homophobic, blacklist
0x00800病気93Covid, herpes, PTSD, leprosy, monkeypox
0x01000薬物222heroin, shroom, crackhead, hotbox, OD
0x02000政治、過激主義266Hamas, Goebbels, Leninism, democrat, swastikas, Trump
0x04000宗教、冒涜420Sikhism, jihadi, Beelzebub, damn, hell, jeez
0x08000性473nude, nookie, lecher, harlots, Pornhub, Hooters
0x10000暴力、死373suicide, lynch, murders, hangings, slave, slaveholder
0x20000武器、テロ268AK-47, grenadier, jihad, sarin, kamikaze, yellowcake
0x40000包括的な「機密コンテキスト」1,080God, Allah, Jews, gay, trans, bi, crazy, fat, ugly, sex, die

トピックフラグとティアは独立しています。2,052の英語の単語にはトピックがありますがティアはありません:gay, fat, God, Allah, sex はすべて「機密コンテキスト」としてタグ付けされていますが、下品、攻撃的、または機密ではありません。私の推測では、トピックはヒント(「これをランク付けする際は注意してください」)であり、ティアはルールです。

下位のメタビットは退屈です:固有名詞、略語、iMacやtvOSのようなキャメルケースのブランド名。そこには見るべきものはありません。

変なもの

ここからが面白くなります。いくつかのフラグは明らかに正しく、いくつかはおかしくさせられました。

下品
  • オイディプス: 下品。おそらくmotherfuckerに隣接するジョーク、またはコンプレックスのため。ソフォクレスは喜ぶでしょう。
  • reams: 下品。「誰かをこっぴどく叱る」という意味で。
  • cooties: 下品。あなたの9歳児が罵っているということです。
  • orgy, sext, merde: まあ、納得です。
攻撃的
  • トムとミック: 攻撃的。「アンクル・トム」とアイルランド人へのスラーですが、非常に一般的なファーストネームでもあります。
  • オリエンタル: 攻撃的。
  • パプーゼス: 攻撃的。
  • conservatards: 攻撃的。スラーティアで見つかった唯一の政治的侮辱です。
  • niggardly: 攻撃的。これは「けち」を意味し、古ノルド語に由来し、スラーとは無関係です。これは実際の論争を引き起こしており、おそらくそれがそこにある理由です。
  • assとasshole: 下品ではなく、攻撃的です。
機密
  • peeとpoo: 排泄トピックを持つ機密。premenstrual, leprosy, herpesvirusも同様です。
  • niggle(小さな心配事、スカンジナビア起源)とunderling(古英語で部下を意味する)は機密であり、侮辱トピックを共有しています。似たような単語はフラグが付けられていません:sniggerはクリーンですがniggleはフラグが付けられており、minion, lackey, flunky, stoogeはクリーンですがunderlingはフラグが付けられています。これらはルールではなく、手作業で選ばれたエントリのように見えます。
  • blacklistとwhitelistは、侮辱/アイデンティティトピックを持つ機密です。これは、業界がblocklistとallowlistに移行したことと一致します。Apple自身のフレーズフィルターファイルはblocklist.datという名前です。
  • BravesとChiefs(ネイティブアメリカンのマスコットを持つチーム名)、Londonderry(Derryの論争のある名前)、Gentile, Jehovah, Mongol, Frenchierはすべて機密です。
  • Isisは政治トピックを持つ機密です。エジプトの女神には申し訳ありません。
  • slave, slavery, slaveholderは暴力トピックを持つ機密です。
  • idiotは英語では機密です。ノルウェー語はより厳しく、idiotを攻撃的ティアに分類しています。

トランプフラグ

機密ティアには109個の大文字の単語があります。そのすべてを以下に示します:

Al-Qaeda, Al-Qaida, Aryan, Aryans, Auschwitz, Bacchus, Beelzebub, Birkenau, Brave(s), Buchenwald, Chief(s), Chippendale(s), Christ-y, Christer(s), Crip(s), Dachau, Eichmann, Frenchier, Gentile(s), Gestapo(s), Goebbels, Goering, Hamas, Hezbollah, Himmler, Hitler, Hitlerian, Hitlerism, Hitlerite(s), Hitlerjugend, Hooters, Isis, Islamophobe(s), Islamophobic, Jehovah(s), Jewfro(s), Jezebel(s), Kalashnikov(s), Kristallnacht, Kuomintang, Londonderry, Luftwaffe, Mao, Mauthausen, Mickie(s), Mollie(s), Mongol(s), Mossad, Nazi(s), Nazism, Osama, Pornhub, Quaalude(s), Reich, Reichsmark, Reichstag, Sachsenhausen, Satan, Satanism, Shoah, Sinophobe(s), Sinophobic, Sodom, Stasi, Taliban, Treblinka, Trump, Trumps, Unabomber, Uzi(s)

(複数形と所有格は簡潔さのために省略)

そのリストにある他のすべての実在の人物は死んでおり、ほとんどがナチス関係者、独裁者、またはテロリストです。そこにトランプがいます:

category  meta      word
00002000  02000081  Trump        sensitive tier + politics topic
00002000  02000081  Trumps
00002000  02000081  Trump's
00000000  00000000  trump        (the card-game word: clean)
00000000  00000000  trumped

比較のために:

単語en_US
Trump機密、政治トピック
Hitler機密、政治トピック
Bidenクリーン
Obamaクリーン
Putinクリーン
Stalinクリーン
Musk辞書にない

en_GBはen_USと一致します。他の言語は異なります:ドイツ語の辞書にはTrumpはクリーン(そしてHitlerは攻撃的ティアに分類)されており、スウェーデン語はPutinを機密としてフラグ付けしています。

フラグが何をするかがここで重要です。私が知る限り、機密単語とは、キーボードが単独で提案すべきではない単語です。それでもタイプでき、修正されることはありません。「ユーザーが明らかにそちらに向かっている場合を除き、QuickTypeバーからこれを除外する」と考えてください。これは禁止よりもはるかに穏やかなものです。

特定の名前に対してAppleがそれを望むもっともらしい理由があります。2025年2月、iPhoneの音声入力で、人々が「racist」と言ったときに一時的に「Trump」と表示されました。それはバイラルになり、Appleはそれを音声モデルの「音韻的重複」と呼び、1日以内に修正をリリースしました(9to5Mac)。私のMac上の辞書ファイルは2025年7月のものです。この名前を不意の提案から除外するルールがあれば、同様のことがキーボードを通じて再び起こるのを防ぐことができます。それが理由だと証明することはできませんし、比較のために古い辞書も持っていません。しかし、それは理にかなっています。

ノルウェーの政治、比較のために

私はノルウェー人であり、確認する必要があったので:

単語トピックティア
FrP, Høyre, Venstre, Rødt, SV, KrF, MDG政治なし
Støre政治なし
Solberg, Erna, Sylviなしなし
Listhaugn/a辞書にない
Breivik, Quisling, Hitlerなし機密

すべての政党は政治トピックを受け取り、どれもティアを受け取りません。機密ティアに含まれるノルウェー人は、大量殺人犯とナチスの協力者だけです。

他の言語

同じ3つのティアは、私が試したすべてのヨーロッパの辞書に存在し、キリル文字のものも含まれています。カウントはエントリであり、レンマではないため、ポーランド語やロシア語のような高度に屈折する言語は、実際よりも悪く見えます:罵り言葉のすべての格と活用形が別々のエントリになっています。

ロケール下品攻撃的機密注目すべき点
en_US1,0506632,558idiot は機密
en_GB1,0558722,337chav は攻撃的;chink は攻撃的ではなく下品として分類
nb_NO2,3931,3246,446idiot は攻撃的
da_DK1,1793,3148,551fjols(「愚か者」)は攻撃的
sv_SE6371,24716,193idiot は下品;Putin は機密
fi_FI56987247機密ティア全体がkakka(「うんち」)、kakkakasa(「うんちの山」)、saakeli
de_DE3,2183,5189,446Hitler と beknackt(「愚かな」)は攻撃的;Trump はクリーン
nl_NL571,1803,805下品な単語は57個のみだが、kanker(「癌」、典型的なオランダ語の罵り言葉)はそのうちの1つ
fr_FR2,1512625,562boche は攻撃的
es_ES3,93131313,431sudacas と fachas は攻撃的
it_IT3,8863776,543terrone は攻撃的、nazismi も同様
pt_BR1,5901,8913,332machista と velhinhos(「小さなお年寄り」)は攻撃的
pl_PL9,6981,4366,190ここで最大のティアは下品、主に活用形(dupczysz, srasz)
ru_RU10,8213,23924,721同じ話:мат は多く活用する

ビットはどこでも同じ意味を持つわけではないようです。アラビア語とヘブライ語は数十万の「機密」エントリを返しますが、それらの辞書はおそらくビットを別の目的で再利用しており、私はそれらを省略しました。韓国語、カタラン語、ハンガリー語は何も返さず、日本語は私のダンプツールをクラッシュさせます。

ノルウェー語からのサンプル(英語以外でタイプするときに使うので):

  • 下品: faen, jævla, dritt, fitte, kuk, pule, pissehull, rævhull, pulekanin, kåt, morrabrød。
  • 攻撃的: idiot, sigøyner, kinamann, riskokers(文字通り「炊飯器」、アジア人へのスラー)、ノルウェー語のnワード。
  • 機密: helvete, satan, homo, quisling, Breivik, skinhead, abortnekt, trusene(「パンティ」)。

ティアの単語はほとんど予想通りですが、エッジは言語ごとに異なり、そこには人間が編集した部分が現れます。ノルウェー語はidiotを攻撃的と呼び、英語はそれを機密と呼びます。ドイツはヒトラーをスラーと考えています。

フレーズ、単語だけでなく

2番目の独立したフィルターがあります。すべての英語言語モデルにはblocklist.bundleがあり、QuickPath(スワイプキーボード)にはqp_blocklist.bundleがあります:

/System/Library/LinguisticData/RequiredAssets_en.bundle/AssetData/en.lm/
├── blocklist.bundle/{blocklist.dat, blocklistidmap.dat}
└── qp_blocklist.bundle/{blocklist.dat, blocklistidmap.dat}

blocklistidmap.datは20バイトのヘッダーに続き、(lexicon token ID, class ID)のペアの32ビット整数です。トークンIDを辞書にマッピングすると、930クラスの2,544単語が得られます。ほとんどのクラスは屈折グループです:

931   fuck | fucked | fucking | fucks
1181  molest | molestation | molested | molester | molesting
1514  died | dies | dying
1611  Holocaust | holocaust | holocausts
1614  denied | denies | deny | denying
923   Semite | Semites | Semitic
1487  ghetto | ghettoes | ghettos
1720  animals | brown | cats

blocklist.datはそれらのクラスID上のパックされたトライであり、シーケンスをブロックします:「deny」の後に「Holocaust」、そして1720がbrown、animals、catsをペアにするもの。brownをanimalsとcatsの隣に置くクラスは、リストが単一の単語ではなく特定のフレーズをターゲットにしていることを示唆していますが、どのフレーズかはトライをデコードしないとわかりません。実行時のチェックはLanguageModeling.frameworkのLMLanguageModelTokenSequenceIsBlocklistedです。私は、その4番目と5番目の引数に出力ポインタが含まれていることを学ぶところまで行きましたが、私のプローブはまだ断続的にクラッシュするため、実際のフレーズはまだ読んでいません。それはフォローアップ用です。

注意事項

  • 意味は推測です。 Appleはこれらのビットのいずれも文書化していません。ティア名はシステムコードの列挙型から来ており、トピックは数千のサンプルを読むことから来ています。どちらも一貫していますが、それでも解釈です。
  • フラグ付けは検閲ではありません。 私が知る限り、これらのフラグはキーボードが提案するものを決定するのであって、あなたがタイプできるものを決定するのではありません。
  • 1台のマシン。 ここにあるすべては、macOS 15.6 (24G84) のLinguisticDataビルド438(2025年7月)から来ています。iOSや他のmacOSバージョンでは異なる辞書が出荷される可能性があります。
  • プライベートAPI。 関数は、アップデートごとに変更されたり、消滅したりする可能性があります。これをアプリに出荷しないでください。

自分で試す

# あなた自身の学習済み冒涜データベース(Macではおそらく空)
sqlite3 -readonly ~/Library/Keyboard/VulgarWordUsage.db 'select * from vword_usage'

# 上記のSwiftバージョンをビルドし、ティアでフィルタリングする
swiftc -O lexflags.swift -o lexflags
./lexflags en_US | awk -F'\t' '$1 == "vulgar" {print $3}' | sort -u | less
./lexflags nb_NO | awk -F'\t' '$3 == "faen" || $3 == "helvete" || $3 == "idiot"'

何かをビルドしたくない場合は、gistに15ロケールのティア付き単語すべてがTSV形式で、コードとそれらを再生成するスクリプトがあります。これはmacOS 15.6のスナップショットであり、最新の状態に保たれる予定はありません。

オイディプスよりも面白いものを見つけたら、ぜひ教えてください。


[画像]