internal-classifier
GitHub从生产环境导出内部内容过滤分类器的裁决结果与指纹数据,生成供供应商审计的伪匿名样本。支持通过脚本抓取日志、转换格式并打包README,用于分类器结果检查或供应商沟通。
触发场景
安装
npx skills add theopenco/llmgateway --skill internal-classifier -g -y
SKILL.md
Frontmatter
{
"name": "internal-classifier",
"description": "Export the self-hosted internal content-filter classifier's verdicts (passes and blocks, with prompt fingerprints) from production, and build the pseudonymized sample sent to the classifier vendor. Use when asked for a classifier export, verdict or fingerprint dump, a sample for the classifier admins or vendor, or to check classifier results over a time window."
}
Internal classifier export
The classifier keeps no state. Every verdict, passes included, is stored on the
request's log.gateway_content_filter_response (internal classifier entries
have model: "internal-classifier") and is cleared by log retention after 30
days. Fingerprints are present only while the classifier runs with its hash-all
option. See the gateway skill for how the gateway calls it.
Admin dashboard export
Content Filter page → "Internal classifier checks", backed by
GET /admin/content-filter/internal-checks/export
(apps/api/src/routes/admin-internal-classifier-checks.ts): up to 24 hours per
download, real request and organization ids. Its CSV formula guard prefixes '
to minhash_b64 values starting with +, so do not send dashboard downloads to
the vendor; use the scripts below.
Vendor sample
Load the database skill first: this reads log in production. The scripts
read only the content filter columns, never prompts or completions, inside a
read-only transaction, through log_content_filter_created_at_idx.
-
Dump. Needs
kubectlaccess to the production cluster. Run per window of about 20 minutes (~9k rows); longerkubectl execstreams drop and are retried from scratch:KUBE_CONTEXT=<production context> sh .agents/skills/internal-classifier/scripts/fetch.sh \ "2026-10-27 15:00:00" "2026-10-27 15:20:00" <dir>/raw-1500.ndjson.gzTimes are UTC,
[from, to). Each file ends with{"__total": N}. Retried attempts are skipped: the final attempt carries the same verdicts and the model that served the request. -
Convert with the admin export's own code. It imports workspace packages from their
dist/, so runpnpm build:corefirst on a fresh checkout:pnpm exec tsx --tsconfig apps/api/tsconfig.json \ .agents/skills/internal-classifier/scripts/convert.mts <out> <dir>/raw-*.ndjson.gz<out>/send/checks.csv: one row per verdict in the vendor audit CSV's column order (ts…band_keys,account_id,decision), thenrequest_keyandchunk_index. Request ids are replaced byrequest_key, organization ids byacct-NNN(acct-001= most checks).<out>/send/rule-summary.csv,<out>/send/hourly.csv.<out>/internal/export-all.csvand<out>/internal/account-pseudonyms.csvhold real ids. Never send them.
It prints totals for the README.
-
README. Write
<out>/send/README.md: window, classifier image digest and cyber profile (from the running deployment), whether fingerprints were on, the file list and column notes below, the totals, and the questions for the vendor. Thencd <out> && zip -qr -9 <name>.zip send.
Keep <out> and the dumps outside the repository or under .context/.
Column notes
tsis when the gateway logged the request (microseconds), not the classifier's clock.ruleis empty on passes;reasonscan still list signals that fired.fp_status=too_shortrows have empty hash columns and nominhash_b64.chunk_indexis 0 unless the content filter reads the whole conversation and splits it into several classify calls.
版本历史
- c6810b7 当前 2026-11-02 20:57


