mcpField
C
classifier.dev

classifier.dev

远程服务
classifier.devAI 与智能体4341 周前更新

关于 classifier.dev

classifier.dev 是零样本文本分类服务,输入文本与自定义标签,返回标签及校准后的置信度,无需 API key。它面向需要快速批量分类的开发者与 Agent,提供 HTTP 接口与命令行工具 classify。

主要功能

  1. 01零样本分类,标签由用户自定义
  2. 02每个结果附带校准后的置信度
  3. 03单次请求最多处理 1,000 条文本
  4. 04支持多标签分类
  5. 05提供 curl 与 classify 命令行接口

适用场景

  1. 01对用户反馈按类别(如 bug、feature)分类
  2. 02过滤垃圾信息等文本内容
  3. 03在脚本或 Agent 中批量调用文本分类

MCP 相关

输入中未提及 MCP。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://classifier.dev/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

5
参数类型必填说明
urlstring否使用一个公开 URL 抓取内容,而不是使用 inputs/items。需要工作区有可用余额。Context.dev 每次计费尝试收费 $0.0022,另加分类费用;长文章需要 Fast。错误信息会披露已产生的费用。不会自动重试抓取。
tierenum否fast(默认)或 smart;后者会将置信度低于 0.7 的答案交由推理模型重新判定(速度较慢,且仅支持单标签)。与 Laya 处理通道相互独立。fast | smart
modelenum否默认使用 Jev。默认或显式指定 jev 时,输入超过 32,000 个字符将使用付费的 Fast-only 长上下文:总计最多 250,000 个原始 cl100k_base 上下文 token、20 个文档、32 次判定和 1 MB 请求正文。需要付费工作区余额或有效的付费订阅,不可使用注册赠金。每 100 万个原始上下文 token 收费 $0.084,跨所有输入仅计一次,与维度数量无关。最终的 Jev 会使用所选证据;符合条件的分块可能被省略,并在 usage.long_context 中披露。没有证据时会返回 422 long_context_no_evidence,且不收费。显式指定 'chunklaya' 会保留旧版的选择加入行为(每个输入最多 4,000,000 个字符、20 个输入,并受请求正文大小限制)。'laya'(512-token 上下文)和 'kev'(8K 上下文)仍为实验性选项。jev | laya | kev | chunklaya
inputsarray否要分类的文本,数量为 1 至 1,000 条。结果按相同顺序返回。
labelsarray是2 至 100 个类别名称。描述性名称的分类效果更好:"urgent bug" 比 "p0" 更好。若“以上皆非”确实是可能结果,请添加类似 "none of these" 的标签。
includearray否与 url 一起使用:返回 article.markdown 和/或 article.html,不额外收取抓取费用。省略则返回精简输出。
processingenum否可选。若省略 model,则隐含使用 Laya;显式指定 Jev 时无效。使用 Laya 时,省略此项可根据情况自动为单次判定选择 fast,或为批次选择 bulk。显式指定 fast 时仅接受单次判定。共享容量限制可能导致返回 429。fast | bulk
share_databoolean否默认情况下,同步分类请求中的文本、标签、指令和模型结果会保留在 Cloudflare 私有存储中,用于模型训练和运营人员审核。共享请求的每分钟及每日分类配额均为双倍。设置 share_data: false 或 X-Classifier-Share-Data: false 可选择退出并使用标准限额。仅共享你有权提供的数据;请勿包含机密或个人信息。尽力进行内容脱敏。计费、支出上限和输入大小限制仍然适用。
instructionsstring否可选的附加标准,例如 "judge only the service, ignore the food"。

详细介绍

classifier.dev

零样本文本分类。输入纯文本,输出标签和经过校准的置信度。无需密钥,无需注册。每个请求最多可处理一千条文本。

curl https://classifier.dev/spam,not+spam/Win+a+free+iPhone
spam

curl "https://classifier.dev/?labels=spam,not+spam&text=Win+a+free+iPhone"   # 同一调用,查询参数形式
spam

单个 Cloudflare Worker。没有数据库,没有框架,除 esbuild 外无需构建步骤。

CLI

npm i -g classifier-dev
classify bug,feature,praise < feedback.txt

cli/ 是独立的 npm 包(classifier-dev,二进制文件为 classify):单个无依赖的 Node 文件,针对模拟 API 运行测试(npm test),使用 semver 并有自己的 CHANGELOG,通过 npm run release patch|minor|major 发布;该命令会创建 cli-v<version> 标签,并由 .github/workflows/publish-cli.yml 负责发布(需要设置 NPM_TOKEN 仓库密钥)。它与 API 的交互方式和 curl 完全相同。

目录结构

src/index.ts    路由、验证、层级、LLM 回退链、分析
src/query.ts    GET 查询形式,使用 nuqs 读写;错误信息会建议使用的 URL
src/jev.ts      TypeSafe 的 Jev:将输入打包为请求,并读取概率
src/limiter.ts  Durable Object:按 IP 限流
src/report.ts   摘要 — Analytics Engine SQL -> Resend,标记模型回退
src/alerts.ts   每 15 分钟运行一次;仅在出现问题时发送邮件
src/feedback.ts Agent 反馈,feedback.now 协议 -> 电子邮件
src/privacy.ts  带密钥的假名:保留的信息不会指向调用者
src/cost.ts     每个请求的上游支出,来自各提供商自己的记账数据
src/docs.ts     网站(GET / 和 GET /benchmark),纯文本
src/home.ts     同样的两份文档,仅为浏览器渲染
src/ui.ts       统一外观:终端中的 Markdown
cli/            `classify` 命令,以 classifier-dev 为名发布到 npm
eval/           基准测试;引用数据前请先阅读 eval/README.md
finish-dns.sh   一次性 DNS 配置,见下文
wrangler.example.toml  Worker 配置,不含特定账户的 ID

网站

curl classifier.dev 会输出纯文本,一如既往。浏览器会发送 Accept: text/html 并获取同一份渲染后的文档 — 包含标题、括号中的链接和复制按钮 — 由 src/home.ts 提供。内容不会重复:页面会在收到请求时根据 DOCS 和 BENCHMARK 生成,因此文本保持统一,两个版本不会出现偏差。可手动使用 ?format=text 选择纯文本,两种响应都会携带 Vary: accept。

Agent 反馈

实现了 feedback.now 协议(schema 1.1),任何支持该协议的 Agent 都可以直接报告问题,无需说明操作方式:

GET  /.well-known/agent-feedback.json   此主机接受的内容
GET  /api/v1/policy                     类别、严重程度、限制
POST /api/v1/feedback                   完整的结构化报告
POST /api/v1/observations               更简短的信号
POST /api/v1/feedback/{id}/attachments  稍后补充更多证据
GET  /api/v1/receipts/{id}              是否已收到,以及内容是否有效

已接受的提交会发送到 REPORT_TO 指定的邮箱。报告会在 KV 中保留 90 天。同一 domain + surface + category + title 的重复报告会被存储并确认为重复项,但不会再次发送邮件,因此循环运行的单个 Agent 无法把收件箱塞满;每个 IP 每小时限额为 100,剩余限额会在每张回执中返回。

推荐使用 signal.category: "testimonial"。这类推荐必须包含 reporter.agent_type 和 reporter.agent_description,确保推荐附带足够的背景信息,说明受益的 Agent 类型及其工作方式。

quality_score 是根据报告完整度计算的确定性函数 — Agent 可以查看规则,下次写出更好的报告。这里不会调用分类器或 Analytics Engine:这里接收的是报告这些服务故障的消息,因此即使它们无法工作,这里也必须正常运行。

部署

合并到 main 即会触发部署。.github/workflows/deploy.yml 会进行类型检查、运行 Worker 和 CLI 测试、执行 wrangler deploy,然后请求线上服务的 /v1/health 和一次分类,因此,如果上传的 Worker 有问题,部署会在 CI 中失败,而不是等到有人在终端中发现。

手动尝试尚未合并的改动:

cp wrangler.example.toml wrangler.toml     # 只需执行一次,然后填入你自己的 ID
npx wrangler deploy

wrangler.toml 已加入 gitignore,其中保存了特定于某个 Cloudflare 账户的两个值:account_id,以及通过 npx wrangler kv namespace create STATS 返回的 STATS KV 命名空间 ID。已纳入版本控制的 wrangler.example.toml 包含其他所有内容——cron、绑定和迁移——因此部署配置保存在仓库中,只有标识符例外。

CI 没有 wrangler.toml,因此 .github/render-wrangler.mjs 会根据示例文件和三个仓库密钥生成一个文件。这样,示例文件就是实际部署配置的来源,而不是它的副本:如果只修改 wrangler.toml 中的绑定,CI 仍会部署旧配置。

部署所需的仓库密钥:

CLOUDFLARE_API_TOKEN    dash.cloudflare.com > My Profile > API Tokens >
                        Create Token > "Edit Cloudflare Workers"
CLOUDFLARE_ACCOUNT_ID   wrangler.toml 中的 account_id
STATS_KV_ID             wrangler.toml 中的 STATS 命名空间 ID
REPORT_TO               每日摘要的接收地址

通过 wrangler secret put 设置的密钥保存在 Worker 上,不会打包进脚本中,因此部署不会改动它们,CI 也无需知道这些密钥。

Worker 读取的密钥:TYPESAFE_API_KEY、AI_GATEWAY_API_KEY(Vercel 的 AI Gateway,每月提供免费额度供 Jev 使用;设置后会优先调用它,遇到拒绝请求时再由 TypeSafe 处理)、OPENROUTER_API_KEY、CONTEXT_API_KEY(context.dev,用于聊天中的网页搜索和页面读取)、RESEND_API_KEY、CF_ANALYTICS_TOKEN、REPORT_KEY、PRIVACY_SALT。使用 npx wrangler secret put NAME 添加密钥;这些密钥都不会从仓库中读取。其余密钥列在 src/index.ts 的 Env 接口中。

比较密钥时会使用 secretEquals(src/secrets.ts),绝不使用 ===:普通比较会在遇到第一个错误字节时返回,并泄露猜测正确了多少。

模型

两个层级都基于 TypeSafe's Jev 作答。它是一种决策模型,而非语言模型:接收状态和带类型的问题,并在约 150ms 内为每个选项返回校准后的概率。这种设计让 API 能做到 LLM 版本无法做到的三件事。

每次请求处理一千条输入。 状态是一个由 {id, text} 组成的数组,每条输入都有自己的问题,因此整个批次只需调用一次上游服务。文档中规定的限制是每次请求 64k 个 token;jev.ts 会按保守的预算打包,并让生成的请求一次并行运行八个。实测:端到端分类 400 条新闻标题耗时 650ms;打包 100 条输入得到的评分,与逐条发送相同。

有意义的置信度。 在 400 条六分类情绪数据中,置信度 >= 0.9 的答案有 82% 正确,而置信度低于 0.5 的答案有 29% 正确。此前模型的 logprob“置信度”将 87% 的新闻条目评为高于 0.9,其中只有 68% 答对。因此,tier: "smart" 现在的含义是:对于快速推理模型给出的单标签答案,若置信度低于 0.7,就重新提问并替换答案,同时标记 escalated: true。其他一切保持不变。模型的选择很重要:在 Jev 不确定的那些条目上,deepseek-v4-flash、qwen3.7-flash 和 mercury-2.5 的表现都不如 Jev;gemini-3.8-flash 将新闻主题准确率从 87.5% 提升到 90.0%,将情绪准确率从 61.8% 提升到 63.7%,因此采用了这条链路。前沿模型(claude-fable-5.1)的准确率为 72.3% / 90.7%,价格约为 3 倍;如果觉得这笔权衡值得,相关数据见 /benchmark。

一次完成多标签分类。 每个标签对应一个是/否问题,返回分数 >= 0.7 的标签,按最可能到最不可能排序,并附上完整的分数映射。在七案例数据集上的 F1 为 0.887,而它取代的“扫描并验证”LLM 级联为 0.799;耗时 230ms,而非 1.5s。使用推理模型重新判断候选结果反而降低了表现(且耗时 23s),因此多标签分类不受层级设置影响。

index.ts 中的 LLM 链路仍作为 TypeSafe 不可用时的回退方案;由于每条输入都需要单独调用一次,因此限制为二十条输入。摘要会报告实际作答的模型,并标记 FALLBACK;此前的主模型被上游下架后,其备用模型在数周内持续提供 F1 为 0.546 的结果,却没有任何提示。

更新列表

表单和 POST /subscribe 会通过 Resend 发送确认邮件。 API 返回 202 {"ok":true,"status":"pending_confirmation"}。在将邮件中的令牌提交到 POST /subscribe/confirm,作为 {"token":"..."}(或通过确认表单提交)之前, 不会向 newsletter 数据库写入任何内容。GET 只会呈现表单,因此邮件扫描器无法确认订阅。

令牌使用 NEWSLETTER_CONFIRMATION_SECRET 签名,有效期不超过 24 小时, 注册时绝不会返回令牌。Resend 的幂等键会在每个整点时段内对来自同一邮箱的重复请求进行去重。现有的每 IP 限制也继续适用。轮换签名密钥会使尚未过期的链接失效。

部署前请使用 npm run db:migrate 应用 migrations/postgres/。订阅者表与应用数据库共用。 现有未确认的订阅者仍保持未确认状态;不要回填 confirmed_at,也不要在他们确认前向其发送更新。确认操作或重放旧令牌都不会清除现有的退订状态。

必需的 Worker 密钥:DATABASE_URL、NEWSLETTER_RESEND_API_KEY,以及至少 32 字节的随机 NEWSLETTER_CONFIRMATION_SECRET。wrangler.example.toml 中的 NEWSLETTER_FROM 必须使用已验证的 Resend 发件域名。REPORT_TO 是回复地址,仅会在新记录确认时收到通知。

订阅者表保存邮箱、来源、注册/确认/退订日期、勾选的路线图项目(wants text[],存储 ROADMAP 键;勾选项会随确认令牌传递,并在确认时写入)、选择更快推理时请求的延迟,以及内部 ID。表中不保存 IP、请求 ID 或分类流量。待确认的注册不会被存储。不得记录令牌和邮件服务提供商的错误响应正文。 migrations/postgres/0007_newsletter.sql 定义了该表;重复确认仅在勾选了项目时才会替换勾选项,且绝不会清除退订状态或更改首次确认日期。

发送更新时,只读取已确认且仍在订阅的收件人:

SELECT email, wants, desired_latency_ms FROM subscriber
WHERE confirmed_at IS NOT NULL AND unsubscribed_at IS NULL;

人们最先请求的内容,用于安排工作顺序:

SELECT unnest(wants) AS item, count(*) FROM subscriber
WHERE unsubscribed_at IS NULL GROUP BY 1 ORDER BY 2 DESC;

Worker 使用应用的 DATABASE_URL 存储 newsletter 和账户数据。 订阅者记录没有账户外键或 API 流量标识;共用存储不会让账户持有人自动订阅,也不会更改现有的同意状态。旧 newsletter 项目作为只读迁移存档保留。经验证的切换和恢复流程请参阅 docs/postgres-setup.md。

文案由一个常量提供——src/newsletter.ts 中的 ROADMAP。curl classifier.dev 输出的纯文本、渲染页面上的表单和 index.md 都读取该常量,因此路线图变更会同时影响这三处,或都不受影响。

Jev 长上下文

默认 Jev 和显式设置 model: "jev" 的输入如果超过 32,000 个字符,则会使用 Chonkie RecursiveChunker,将内容切分为 600 个 token 的 cl100k_base 分块;随后并行调用 Jev,筛查相关或不确定的证据(包括相反证据和例外情况);最后按来源顺序,将所有符合条件的分块交由 Jev 处理。最终证据预算为 20,000 个 cl100k_base token,并会进行保守的提供商上下文检查。预算用尽时,符合条件的分块可能会被省略;usage.long_context 会报告筛选数量、token 数、调用次数和耗时。 这并不保证最终处理会阅读完整文档,也不保证结果始终准确。

请使用由付费余额或有效付费订阅支持的 Fast 工作区密钥;匿名访问和注册赠金不符合条件。同步限制: 所有输入的原始上下文 token 总数不超过 250,000 个,文档不超过 20 份,判定不超过 32 项,正文不超过 1 MB。零售价为每百万个原始 cl100k_base 上下文 token 收取 $0.084;无论维度或实际推理用量如何,所有输入只计费一次。 连续的空白字符或非空白字符序列长度上限为 8,192 个 UTF-16 代码单元。超长序列会在文档 token 化或分块之前返回 400 long_context_input,以限制病态输入导致的分词器工作量。 没有符合条件的证据时,会返回 422 long_context_no_evidence,且不收费。 显式设置 model: "chunklaya" 会保留其独立的旧版选择启用行为。

使用已充值的工作区密钥,通过 POST /v1/classify 发送一份完整文档,最多可包含 1,000 万个输入 token(100 MB)。使用常规 JSON 输入和标签,或发送 text/plain,并通过 labels 查询参数指定标签。大文件上传会返回 202 和 status_url;较小文档也支持 Prefer: respond-async。服务端会自动拆分、筛查、重试并完成处理。 仓库 CLI 可通过 node cli/classify.js a,b --document document.txt --json 处理上传和轮询。

完整文档的精确 token 数用于设置预留金额和 $0.084/M 费用。排队期间,源文本会以私密方式存储,并在筛查过程中逐步删除。最终由 Jev 阅读的已选证据不超过 20,000 个 token。任务完成、失败、取消或满 24 小时后,剩余源文本和证据都会被删除;失败或取消的任务会退款。结果在过期前仍可获取。

分析

每个请求都会写入一条 Analytics Engine 数据点(层级、标签集指纹、国家/地区、状态、数量、延迟)。分析数据中不会写入请求文本。

长上下文聚合数据也会写入 classifier_long_context_events,其中包含上下文/文档总数、分块筛查/选中/省略数量、各阶段输入 token 数(包括数量未知标记)、已回答的调用次数和各阶段耗时。账户事件会追加相应字段;其有序列契约见 src/server/analytics/schema.ts。 文档数和原始上下文 token 数只计一次;分块和阶段计数器会在不同维度的处理过程中累加。专用数据集中不会写入文档文本或调用方标识符。

每个请求也会记录我们的成本:OpenRouter 在收到询问时会返回调用费用;Jev 则按其报告的输入 token 数,并按照 eval/bench.py 为基准测试定价的费率计费。支出会累计在每请求计量器(src/cost.ts)中,并写入 double3。该列在上线后才添加,因此在该次部署之前的数据中显示为 0。

cron 会在 15:00 UTC 查询该数据,并通过 Resend 发送摘要。

告警

一个独立的 cron 每十五分钟运行一次,除非触发告警,否则不会发出通知。它只监控关联了操作的条件:Jev 密钥被拒绝、Jev 无响应(备用链会静默接手,这种情况确实发生过)、5xx 比率、智能层级升级失败(耗尽的 OPENROUTER_API_KEY 会出现这种情况)、平均延迟、相较于过去一天的支出激增,以及流量完全停止。4xx 会被忽略——那是扫描器在探测 /wp-admin,不属于故障。

Jev 额度。 TypeSafe 不提供余额端点——它的 API 只有 /v1/systemone 和 /v1/models,没有其他端点——因此没有可供监控的余额数字。作为替代,检查程序每十五分钟使用密钥调用 /v1/models,并报告 TypeSafe 返回的内容:如果该端点返回 401、402 或 403,就表示额度用尽、密钥已撤销或密钥错误,并会发出严重告警,引用 TypeSafe 自身的消息,而不是猜测每种状态码代表什么。由于它会主动探测,而不是等待流量到来,因此即使主机处于空闲状态,也能在任何调用者遇到备用链之前触发;即使 Analytics Engine 宕机,它也会继续运行。

每种情况开始时发送一封邮件,持续期间每六小时再发送一次,解除时再发送一次;状态存储在 KV 的 alert: 下。阈值位于 src/alerts.ts 顶部的 T 对象中。

curl -H "authorization: Bearer $REPORT_KEY" https://classifier.dev/alerts
curl -H "authorization: Bearer $REPORT_KEY" "https://classifier.dev/alerts?demo=1&send=1"

第一条命令会预览,不发送邮件,也不更改状态;第二条命令会通过实际流程发送一封示例邮件,以验证投递正常。

随时预览摘要,不发送邮件:

curl -H "authorization: Bearer $REPORT_KEY" https://classifier.dev/report

Jev 提供商的尝试记录会通过 JEV_AE 单独存储在 classifier_jev_attempts 中,包括已恢复的故障、重试和网关冷却期间的跳过记录。报告会列出每个提供商的状态、原因、次数和平均延迟;即使通知被抑制,/alerts 仍会显示当前事件。现有的 15 分钟告警检查会在任一提供商至少有三次尝试失败,且失败率超过 5% 时发出警告。次数会考虑 Analytics Engine 的采样。不会存储任何输入文本、调用者标识符或上游消息。成功的简单分类器和多标签分类器名称会在单独的聚合 KV 记录中保留 90 天,其中不含调用者或源文本字段。其带密钥的指纹也会出现在每次请求的分析数据中,使运维人员能够在这些假名化记录中查询标签名称。

wrangler.example.toml 中的 AI_GATEWAY_DISABLED = "true" 会让生产环境直接使用 TypeSafe;这是因为网关在 9 月 19 日反复返回 429。网关密钥会保留。若要恢复优先使用网关的路由,请确认网关容量正常,在示例配置和本地配置中将此变量改为 "false",然后部署。重新启用后,请检查提供商尝试记录和实时 API 测试。

请求头是唯一的访问入口。查询字符串会进入访问日志、浏览器历史记录,以及之后点击的任何链接的 Referer 请求头中,因此已移除 ?key=。添加 ?send=1 才会真正发送邮件。

Cloudflare 的 Analytics Engine SQL 是 ClickHouse 的精简子集——不支持 uniq()、SELECT DISTINCT,而单独使用 SELECT col ... GROUP BY col 也会被拒绝。因此,去重计数会使用 SELECT col, count() ... GROUP BY col,并对返回的行计数。每条查询都会单独执行,因此单条查询失败不会导致整份报告空白。

隐私

该数据集中的两列曾用于标识调用方:IP 地址,以及合并并转换为小写的标签集。现在这两列都经过密钥哈希处理(src/privacy.ts),因此统计数据仍能计算不同调用方和不同分类器的数量,但无法反推出地址或某人的措辞。调用方哈希还会使用 UTC 日期,因此明天就会变成不同的值——这就是为什么 7d 或 30d 内的独立调用方数量实际上统计的是调用方日数。

设置一次密钥,并像对待其他密钥一样将其保密:

npx wrangler secret put PRIVACY_SALT     # 32 random bytes

轮换密钥会重新编号所有指纹,因此轮换前后的独立计数会重复计算。密钥会依次回退到 ADMIN_SIGNING_KEY、REPORT_KEY,然后是每个 isolate 随机生成的值,因为对 IPv4 地址或常见标签集进行无密钥哈希,几秒钟内就能反推出原值。

评估

npm run bench                 # 多标签,7 个用例:jev 与任意 OpenRouter 模型
npm run single -- --dataset emotion --backend jev
npm run single -- --dataset ag_news --backend openrouter:qwen/qwen3.7-flash
python3 eval/escalate.py --dataset emotion     # 智能层带来的收益

single.py 首次运行时会下载 AG News 和 dair-ai/emotion 的测试行,并将原始结果缓存到 eval/data/results/,以便 escalate.py 合并后端结果,而不必再次付费。eval/README.md 列出了注意事项。

速率限制

按 Durable Object 中的 IP 地址限流,按分类次数计数:fast 为每分钟 3,000 次、每天 20,000 次;smart 为每分钟 200 次、每天 2,000 次。

我们尝试并否决了另外两种方案:

  • Cloudflare 的原生 ratelimit 绑定可以正常注册,但计数从未递减(对 60 次的限制发起 70 次调用,全部返回 success: true)。
  • KV 会在边缘缓存且最终一致,因此这一秒写入的计数器对下一次读取不可见——每个请求都看到 remaining: 59。

Durable Object 是单线程且强一致的,这正是计数器所需要的。已在原本每分钟 60 次的限制下验证:75 个请求 -> 60 个返回 200,15 个返回 429。

DNS

域名在 Porkbun 注册;Worker 部署在 Cloudflare 上。Cloudflare Workers 自定义域名要求区域托管在 Cloudflare,而这里的两个 API 令牌都没有 zone.create 权限,因此其中一步需要手动完成:

  1. https://dash.cloudflare.com -> 添加域名 -> classifier.dev -> Free 套餐
  2. ./finish-dns.sh — 读取分配的名称服务器,通过 Porkbun API 将 Porkbun 指向这些服务器,并将 Worker 绑定到根域名和 www。

Agent 技能

npx skills add https://classifier.dev

该技能通过 RFC 8615 well-known 发现机制从此域名提供,因此无需经由代码仓库:

src/SKILL.md                          技能文件,以 Text 模块打包
GET /skill.md                         资源文件
GET /.well-known/agent-skills/index.json   发现入口,schema v0.2.0

索引必须包含资源文件的 sha256 值,而索引与文件内容不一致会导致技能无法安装。为了避免提交的摘要在之后编辑时被悄悄作废,src/skill.ts 会在每个 isolate 中对实际提供的字节计算一次哈希。因此,编辑 SKILL.md 就够了,无需更新其他内容。

该技能讲解了 API 宣传中容易忽略的一点:你本身已经是模型,可以对所有可见内容进行分类,因此调用该工具的理由不是能力,而是上下文——无需阅读 40 条搜索结果,就能将其筛选到 6 条。

测试中碰到两个问题,因此文档特别说明了它们。Cloudflare 会在请求到达 Worker 之前拦截 Python 标准库 urllib 的 User-Agent 并返回 403,因此示例会显式设置 User-Agent。此外,应告诉筛选器“拿不准时就保留”:在一个包含 10 条片段的研究筛选测试中,这让保留的有效信息从 4/6 提升到 6/6,且没有增加噪声;添加第三个“可能相关”标签则毫无作用。

发现入口

GET /openapi.json               OpenAPI 3.1,也可通过 /.well-known/openapi.json 访问
GET /llms.txt                   面向 Agent 的简短索引,由 robots.txt 链接
GET /benchmark                  准确率、成本和延迟的实测数据

GET / 的第三段中链接到了这两者,因此 Agent 阅读着陆页时就能立即找到它们。

已知问题:Cloudflare 托管的 robots.txt

启用该区域后,Cloudflare AI Crawl Control 会在 /robots.txt 前置一个托管规则,禁止 GPTBot、ClaudeBot、CCBot、Google-Extended、Bytespider、Amazonbot 和 meta-externalagent 抓取。Worker 自身的 robots.txt 会附加在其后,无法覆盖该规则。

这会阻止用于训练的爬虫,而不会阻止运行时 API 使用者——任何 Agent 仍然可以调用 API。但这确实会让文档无法进入未来模型的训练数据,不利于被发现。更改 dash.cloudflare.com -> classifier.dev -> AI Crawl Control -> Security 中的开关后,设置并未保留,因此可能需要在套餐级别进行更改或联系支持团队。

运营方 Agent 访问权限

对于运营方自有的大批量 Agent 任务,请设置专用的 AGENT_API_KEY Worker 密钥,并通过 Authorization: Bearer ... 发送。分类配额不设上限,但推理使用独立的运营方每日 $2 额度(OPERATOR_DAILY_USD),由多个 IP 共享,并采用与免费使用相同的请求和并发限制。它既不消耗也不会扩大匿名额度,也不能替代 ENTERPRISE_API_KEY。CLI 可通过 CLASSIFY_API_KEY 或 CLASSIFIER_API_KEY 接受该密钥。此密钥不能用于访问私有报告或管理功能。请将其保存在被忽略的密钥文件中;切勿交给公共客户端。未进行身份验证的流量仍受匿名配额限制。

对于已安排大批量配额的预付费工作区密钥,请将 API_KEY_RATE_LIMIT_MULTIPLIERS Worker 密钥设置为一个 JSON 对象,其中将每个密钥的 SHA-256 十六进制摘要映射到一个整数倍数(1–1,000)。覆盖设置只会提高该密钥的准入配额;账户计数器、余额扣费、模型容量限制和其他密钥均保持不变。移除对应条目即可恢复套餐配额。

查找分类代码

领域术语定义见 CONTEXT.md。

模块职责
src/index.tsHTTP 验证、配额、模型选择、智能升级、回退和响应格式化。
src/jev.tsJev 问题与答案、共享批次预算和恢复机制、网关/直连传输以及提供方验证。
src/dimensions.ts维度定义,以及输入–维度决策与 Jev 问题之间的双向映射。

普通分类和维度分类都使用相同的 Jev 批处理模块。 问题组是恢复机制会整体保留的最小请求单元: 普通分类中,一个输入的问题;维度分类中,一个决策。 批次准备会将共享输入文本只计算一次,检查两个提供方的预算,并在维度分类扣除配额前运行。执行过程会限制并发请求,并在问题组之间拆分超大批次。

在 src/jev.ts 中更改提供方预算和恢复机制;在 src/dimensions.ts 中维护维度含义。通过 jevClassify 和 Worker HTTP 接口测试提交的请求和返回的分类结果,不要依赖内部打包实现。

多维度

POST /v1/classify 也接受 items 和 dimensions:

{
  "items": ["Checkout charges me twice"],
  "dimensions": {
    "team": ["billing", "identity", "platform"],
    "urgency": {
      "labels": ["immediate", "normal", "low"],
      "instructions": "Active financial harm is immediate."
    },
    "kind": ["bug", "request", "question"]
  }
}

每个 results[i].dimensions[name] 都包含自己的标签、置信度、分数、模型和延迟。Jev 会在条目与维度问题之间共享状态,同时兼顾两者的上下文限制。智能升级针对每个字段单独执行,并会清除原始分数;Jev 不可用时,仅对最多 20 个决策进行回退。API 最多接受 20 个维度和 1,000 个决策,每个决策都会计入配额。classify_dimensions MCP 工具使用相同路径。

分析数据新增了 blob9(单项/多项/多维度)、double6(成功处理的输入条目数)、double7(维度数)、double8(不确定或未评分的字段数)和 double9(由回退处理的字段数)。double1 统计成功决策数。维度配置使用键控指纹,不会逐字存储。管理面板会单独查询维度流量,包括失败和调用方天数。现有的告警 cron 会在一小时内维度请求中 5xx 错误达到 3 次或以上、且占维度请求的比例超过 10% 时发出告警;任何维度回退使用也会触发告警。

使用 Node 22.18+ 运行 npm run test:e2e,并连接真实生产 API;也可以将 CLASSIFIER_BASE_URL 设为预发布环境的源站。这些是使用 node:test 编写的具名 TypeScript 测试,会发起真实的 HTTP 请求并调用模型,不使用 fetch 或推理模拟。共享 IP 配额用尽时,可将 CLASSIFIER_API_KEY 设为已授权的密钥;该设置为可选项。测试套件会使用推理,并计入常规配额。

测试会检查 300 个决策的确切结果和排序、每个字段允许的标签与概率分布、真实的智能升级、提供方分数保留情况、别名、验证错误、MCP、OpenAPI 和旧版调用。 响应最初被视为 unknown,经过验证后才会转换为类型化矩阵。 智能测试要求确实发生升级;如果模型漂移导致所有测试样例都被判定为高置信度,测试会失败,而不会静默跳过推理提供方。

npm run typecheck 会检查 Worker 和 TypeScript 实时测试。部署 CI 会在发布后运行实时测试套件;npm test 仍保持离线运行。故障注入测试仍位于 test/dimensions.test.ts 和 test/dimensions-observability.test.ts。

可从 GitHub Actions 手动运行 live API tests 工作流(或运行 gh workflow run e2e.yml),在不部署 Worker 的情况下检查生产环境。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。