mcpField
S
Spurvik EU AI Act

Spurvik EU AI Act

远程服务
spurvik.com其他0今天更新

关于 Spurvik EU AI Act

Spurvik EU AI Act 是面向开发者的合规工作控制基础设施,提供风险分类、审计记录与人工监督接口。其 MCP 工具可扫描 URL、生成多语言 Art. 50 标识并辅助检查 SDK 与审计记录;它不构成认证或法律意见。

主要功能

  1. 01实时 URL 扫描与风险分类
  2. 02生成 24 种欧盟语言标识
  3. 03检查 HMAC 收据与审计记录
  4. 04查找未包装的调用
  5. 05提供设置片段和标记说明

适用场景

  1. 01扫描线上 URL 并检查 AI Act 风险
  2. 02生成多语言 Art. 50 透明度标识
  3. 03解释 HMAC 收据并检查调用记录

MCP 相关

提供远程 Streamable HTTP MCP 服务,无需 API Key,包含 URL 扫描、风险分类、Art. 50 标识生成及 SDK 和审计辅助工具。另提供本地 stdio MCP 服务。

配置

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

服务地址https://console.spurvik.com/api/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 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

Spurvik

CI npm version mcp version n8n node version

Spurvik 是一个开发者控制平面,支持你开展 EU AI Act 相关工作:哈希链式记录保存、人类监督接口和透明度声明。它是基础设施,不是合规性评估、认证或法律建议。

Regulation (EU) 2024/1689 是法律文件。以下日期依据 AI Omnibus 时间表和欧盟委员会《AI 生成内容透明度行为守则》。请咨询法律顾问,确认这些规定如何适用于特定系统。

实时沙盒、托管式欧盟控制台和入门模板

不是开发者?在 Lovable、Bolt、Replit 或 WordPress 中进行氛围编程? 获取 24 小时《AI 法案》代办设置服务(一次性收费 €199,包含完整 1 年 Pro,价值 €190):我们会在 24 小时内为你安装支持 24 种语言的第 50 条声明、服务器调用日志记录和人工审批关卡。自助结账:console.spurvik.com/signup?plan=concierge。

界面URL说明
交互式沙盒和本地代码检查console.spurvik.com/sandbox无需登录、无 Cookie——预览 <AIDisclosureLabel />(支持 24 种欧盟语言),检查 HMAC 回执,并在浏览器中离线运行技术栈和代码片段检查。
24 种语言的第 50 条标签工作室console.spurvik.com/labels实时交互式预览,涵盖全部 5 种第 50 条场景、24 种欧盟官方语言和可选的欧盟 AI 图标——一键导出 spurvik/react JSX 或 badge.js <script>。
托管式欧盟控制台(法兰克福 fra1)console.spurvik.com/signup开放自助注册:免费 €0/月(每月 10k 个事件,保留 30 天)· Pro €19/月或 €190/年(每月 250k 个事件,保留 90 天,托管式人工审核队列,DPO .md 和附件 IV 草稿导出)· Team €79/月或 €790/年 · 24 小时《AI 法案》代办设置服务 €199 一次性收费,含 1 年 Pro(结账)(不含增值税 · 仅限 B2B)。
免费欧盟《AI 法案》风险检查和第 50(2) 条 C2PA 检查器console.spurvik.com/risk-check · console.spurvik.com/c2pa无需登录。回答几个问题即可自评《AI 法案》风险等级,并检查图像是否带有 C2PA 来源信息。不能替代法律建议。
Agent 技能(skills.sh)和官方 MCP 注册表(7 个免密钥工具)npx skills add spurvik/skills · com.spurvik/eu-ai-act → https://console.spurvik.com/api/mcp远程 Streamable HTTP,无需 API 密钥:spurvik_scan_live_url、spurvik_classify_ai_act_risk、spurvik_generate_art50_badge,以及 4 个 SDK/审计工具(spurvik_setup_snippet、spurvik_find_unwrapped_calls、spurvik_explain_receipt、spurvik_marking_hooks)。技能源码:spurvik/skills。
WordPress、Framer 和 shadcn/v0 资源spurvik-eu-ai-act-wp.zip · spurvik-framer-badge.tsx · article-50-badge.jsonWordPress 插件(上传插件)、Framer 代码组件,以及 npx shadcn@latest add https://spurvik.com/r/article-50-badge.json。它们都会渲染相同的 badge.js 声明;data-attribution="false"(React:attribution={false})可为 Pro/代办服务白标隐藏 “Art. 50 · Spurvik” 链接。
文档和框架指南spurvik.com/docs可复制粘贴的配置指南,适用于 Next.js / Vercel AI SDK、LangGraph、Mastra、OpenAI Agents、Lovable / Replit、WordPress / Shopify / Webflow、Cursor / Claude Code MCP,以及 n8n。
一键 n8n 入门工作流spurvik.com/r/n8n-art50-starter.json在可自托管的 n8n 中直接导入 URL(Import from URL),并使用 [email protected]。
一键 GitHub Actions PR 关卡spurvik.com/r/github-action-spurvik-check.yml放入 .github/workflows/spurvik-check.yml,即可使用 spurvik-mcp check . --ci 离线扫描 PR。

此代码仓库包含的内容

里程碑 1–4,面向欧盟市场。

部件作用
packages/sdk面向 OpenAI、Anthropic 和 Gemini 风格客户端的 withSpurvik() 包装器、适用于 Vercel AI SDK 的 spurvikMiddleware(),以及 Mastra、OpenAI Agents 和 LangGraph 适配器。
packages/react始终可见的第 50 条标签,支持全部 24 种欧盟语言。
packages/core哈希、来源签名、文本标记钩子、审计链检查、Webhook 签名。
packages/mcp本地 stdio MCP 服务。设置代码片段、未包装调用扫描、HMAC 回执说明、标记钩子说明、实时第 50(1) 条 URL 扫描、欧盟《AI 法案》风险等级映射,以及支持 24 种语言的第 50 条徽章生成器。以 [email protected](MIT)发布到 npm。工作区软件包 packages/mcp(1.0.5)。
packages/n8n-nodes-spurvik原生 n8n 社区节点(SpurvikEuAiActGuard)和可导入的 Make.com 蓝图(make-com-blueprint.json),用于第 50(1) 条通知,以及高风险 AI 系统的第 12 条 HMAC-SHA256 摘要和第 14 条 ask_human() 关卡;可选择与 console.spurvik.com 同步,另提供无需密钥的 扫描实时域名(第 50 条和客户简报) 操作。软件包版本 [email protected](MIT)。
examples/可运行的开发者模板:Next.js + Vercel AI SDK(nextjs-vercel-ai-sdk)、LangGraph + Mastra + OpenAI Agents(langgraph-mastra-openai-agents)、9 渠道 ask_human() 路由器(slack-telegram-linear-ask-human 和 multi-channel-hitl.ts)、n8n 和 Make.com 工作流(n8n-make-import),以及 GitHub Actions CI 检查(github-actions-ci-check)。

为支持远程生物识别系统(附件 III 第 1(a) 点;高风险要求自 2027 年 12 月 2 日起适用)第 12(3) 条日志记录而设计的功能位于控制平面中。双人确认是一项产品设置,会检查是否由两个不同的成员账户确认了该决定。图像标记支持位于 packages/c2pa。请从源代码构建该目录。它不是已发布的 npm 软件包。其 package.json 设置了 "private": true 和 "license": "MIT"。

快速入门

许可。 packages/sdk(以 spurvik 和 spurvik-sdk 发布)以及 packages/react(以 spurvik/react 导出项发布)采用 MIT 许可证(版权所有 (c) 2026 EyeTea Solutions ApS (CVR 37093378)),且不提供任何担保。packages/core 需从源代码构建,并打包在上述已发布的软件包中。packages/mcp 以 spurvik-mcp-server 发布。packages/c2pa 需从源代码构建,设置了 "private": true 和 "license": "MIT",且未在 npm 上发布。https://console.spurvik.com 上的控制台是托管服务。其源代码不在此代码仓库中,MIT 许可证也不涵盖该服务。请参阅下文的 商标。

操作指南见 docs/quickstart.md。测试过程中遇到的错误见 docs/troubleshooting.md。通俗易懂的概述见 docs/onboarding-startups-smes.md。

指南:docs/quickstart.md、docs/5-minute-quickstart.md、docs/sandbox-first-5-minutes.md、docs/langgraph-quickstart.md、docs/hitl-approval-mapping.md、docs/console-onboarding.md、docs/adapters-quick-cards.md、docs/claude-code-plugin.md、docs/faq-additions.md、docs/faq-sandbox-2x2.md、docs/faq-console-and-quickstart.md、docs/faq-hitl-and-plugin.md,以及 docs/faq-art50-marking-and-pl-locale.md。 获取软件包。 从 npm 安装实时 MIT 软件包。此前在 spurvik.com/sdk/latest.tgz 提供的构建版本不是此 SDK,不受支持,切勿依赖它来检查记录。

(a) npm:

npm install [email protected] [email protected]

spurvik 和 spurvik-sdk 发布的是同一个 SDK。请将其导入为 spurvik。子路径包括 spurvik/ai、spurvik/mastra、spurvik/langgraph、spurvik/openai-agents、spurvik/channels 和 spurvik/react。

(b) 本地 MCP 服务。自 1.0.3 起,必须指定 --root:

npm i -D [email protected]
./node_modules/.bin/spurvik-mcp-server --root .

在你的应用中(这是一个 ES 模块项目,因为示例使用了顶层 await):

npm pkg set type=module
npm install openai [email protected]

包装调用并检查记录:

import OpenAI from "openai";
import { provenanceOf, verifyProvenanceSignature, withSpurvik } from "spurvik";

const ai = withSpurvik(new OpenAI(), {
  apiKey: process.env.SPURVIK_API_KEY!, // spurvik_live_…
  signingSecret: process.env.SPURVIK_SIGNING_SECRET!,
  contentHash: { mode: "keyed", secret: process.env.SPURVIK_CONTENT_HASH_SECRET! },
  baseUrl: process.env.SPURVIK_BASE_URL!, // the SDK throws without it when NODE_ENV is production
  riskTier: "limited_art50", // Sample value. Set your own classification (as provider or deployer); Spurvik does not classify your use case.
  article50Disclosure: false, // set true only when an interaction notice is shown
  onTelemetryError: (error) => console.error("Spurvik telemetry not delivered:", error),
});

const completion = await ai.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
});
const record = await provenanceOf(completion);

// Argument order: record first, signing secret second. Swapped arguments return false.
const matches = await verifyProvenanceSignature(record!, process.env.SPURVIK_SIGNING_SECRET!);

await ai._spurvik.shutdown(); // scripts: send queued telemetry before exit

provenanceOf(res) 会返回附加到非流式响应的已签名来源记录。对于流,它会返回一个记录 Promise:读取流,然后 await provenanceOf(stream)。存在记录意味着可以检查签名。这并非符合性评估。

当已签名字段与使用该密钥生成的签名相匹配时,matches 为 true。任何已签名字段发生更改,都会导致检查返回 false,除非修改者也使用同一密钥重新签名。因此,匹配表明已签名字段仍与使用该密钥生成的签名相匹配。任何持有该密钥的人都能生成匹配的签名,因此请限制密钥持有者。

密钥和环境变量。 项目 API 密钥的格式为 spurvik_live_ 后接至少 32 个 base64url 字符。它会作为 Bearer token 发送,服务器只存储其 SHA-256 哈希值。SPURVIK_SIGNING_SECRET 和 SPURVIK_CONTENT_HASH_SECRET 保留在调用方,不会发送到控制平面。请妥善保管这些密钥:丢失密钥后,将无法再检查使用该密钥签名的记录。这些密钥均没有内置默认值。SDK 不会自行读取 SPURVIK_API_KEY、SPURVIK_SIGNING_SECRET 或 SPURVIK_CONTENT_HASH_SECRET;你的代码需要将它们传入。项目密钥使用 spurvik_live_ 前缀。披露密钥使用 spurvik_pub_ 前缀。已发布的 spurvik 和 spurvik-sdk 软件包在运行时不会读取 SPURVIK_* 或 AEGIS_* 环境变量。请在代码中传入 apiKey、signingSecret、contentHash.secret 和 baseUrl。这些读取仅存在于此代码库中:packages/core/src/telemetry-policy.ts 中的 vendorTelemetryMode() 会读取 SPURVIK_TELEMETRY,然后读取 AEGIS_TELEMETRY,而已发布的软件包不会调用它。packages/c2pa/src/index.ts 会先读取 SPURVIK_C2PA_CERT_PEM,再读取 AEGIS_C2PA_CERT_PEM;并先读取 SPURVIK_C2PA_KEY_PEM,再读取 AEGIS_C2PA_KEY_PEM。该目录用于从源代码构建,不包含在已发布的 tarball 中。packages/sdk/src/telemetry-exit.child.ts 是代码库中的测试脚本,只会读取 SPURVIK_BASE_URL。packages/sdk/tsup.config.ts 会在代码库构建期间读取 SPURVIK_SDK_DIST。packages/mcp 会读取 SPURVIK_MCP_ROOT 和 SPURVIK_SIGNING_SECRET。这些读取不会出现在 spurvik 或 spurvik-sdk 中。

baseUrl 是 SDK 遥测数据和 halt 流的发送地址。对于托管控制台工作区,该地址为 https://console.spurvik.com。在生产环境中,如果省略此参数,SDK 会抛出错误。在开发和测试中,默认地址仍为 http://127.0.0.1:43123。 **如果 baseUrl 无法访问,**封装后的模型调用仍会成功并返回其记录(high_annex3 除外;该模式会在故障时拒绝执行)。在短脚本中,遥测事件会丢失:onTelemetryError 被调用一次,await shutdown() 返回,进程以退出码 0 退出。长时间运行的进程会调用一次 onTelemetryError。在此构建版本中,刷新失败后排队的事件会保留在内存中(最多 500 个事件;优先丢弃最早的事件),并在之后刷新时发送:下次执行封装后的调用时、执行 await ai._spurvik.shutdown() 时,或进程自行结束时发送一次。不会通过定时器重试。已经刷新失败的事件不会在进程自行结束时再次尝试,除非此后又有事件排队;调用 process.exit() 或使用 Ctrl+C 等信号会跳过最后一次刷新。在进程退出前调用 await ai._spurvik.shutdown(),可让排队的事件再尝试发送一次(默认最长等待 8 秒)。对于 high_annex3,超时的停止检查会抛出 SpurvikOversightTimeoutError(一种 SpurvikHaltedError);控制平面的错误响应则会抛出 SpurvikApiError,它是 SpurvikError,而不是 SpurvikHaltedError;这两种情况下都不会调用提供方。请参阅 docs/troubleshooting.md。在此版本中,不要将控制平面作为这些事件的唯一副本。也请自行留存记录。

article50Disclosure 默认为 false。只有在你明确说明已显示第 50(1) 条交互告知时,才将其设为 true。此标志用于配置,并不代表已确认显示该告知,也不代表该告知已充分。

riskTier 是你自己的分类(作为提供方或部署方);Spurvik 不会对你的用例进行分类。

  • minimal —— 默认不配置透明度或高风险控制。
  • limited_art50 —— 第 50 条透明度支持(交互告知、可选标记钩子)。
  • high_annex3 —— 适用于附件 III 下的高风险用途。封装器会在推理前检查人工停止信号。

第 12 条(记录保存)以及第 11 条和附件 IV(技术文档)自 2027 年 12 月 2 日 起适用于高风险(附件 III)系统。自 2027 年 12 月 2 日起,第 14 条适用于附件 III 所列的高风险 AI 系统。嵌入受监管产品的附件 I 系统适用 2028 年 8 月 2 日,且在此处不属于单独的等级。

文档

指南内容
完整快速入门安装已发布的 SDK,并封装一次模型调用。
5 分钟快速入门封装一次模型调用,保留来源记录,并检查其 HMAC 签名。
沙盒前 5 分钟设置密钥前,先体验公开的 2x2 沙盒控制台。
控制台入门沙盒和托管控制台。
LangGraph 快速入门封装编译后的 LangGraph 工作流(spurvik/langgraph),读取 HMAC 回执,渲染 <AIDisclosureLabel />(包括波兰语 locale="pl" 文案),并将 interrupt() / Command({ resume }) 映射到 /api/v1/hitl。
HITL 审批映射将 Vercel AI SDK 的 interrupted、OpenAI Agents 的 needsApproval 和 LangGraph 的 interrupt() 映射到 Spurvik 的人工监督队列。
适配器速查卡withSpurvikMastra、withSpurvikModel / withSpurvikModelProvider 和 withSpurvikLangGraph。
Claude Code 插件/spurvik:check、/spurvik:wrap 和 /spurvik:engineering-summary。
FAQ 补充定价、安装、MCP 工具、HITL、波兰语 locale="pl" 和第 50(2) 条标记问题。
FAQ:沙盒 2x2沙盒控制台行为和 Shell 环境优先级。
FAQ:控制台和快速入门注册、密钥和 5 分钟快速入门流程。
FAQ:HITL 和插件工具审批、检查点暂停/恢复,以及 Claude Code 插件安装。
FAQ:第 50(2) 条标记和波兰语区域设置2026 年 12 月 2 日之前的第 50(2) 条标记(第 111(4) 条)、波兰语 locale="pl" 文案和 LangGraph。
Claude Code 提交草案分阶段目录提交草案。
网站市场清单为 spurvik.com/.claude-plugin/marketplace.json 准备的网站市场清单。

来源信息不等于第 50(2) 条标记

provenanceOf(res) 从 spurvik 导出。它会读取来源记录:时间戳、模型 ID、带键指纹、第 50(1) 条披露标志、上游标记状态以及 HMAC-SHA-256 签名。markingApplied 和 evidenceTrailerAttached 包含在该签名中。同一值也位于 res._spurvik_provenance 上。provenanceOf 也会读取较早版本响应中的旧来源属性。使用 verifyProvenanceSignature 检查签名。匹配表示签名字段仍与使用你的签名密钥生成的 HMAC-SHA-256 签名一致。这并不能证明已显示声明、输出已添加标记,或你的系统符合该法案。

withSpurvik 是包装器。该函数的旧名称已移除;请使用 withSpurvik。旧名称并不代表被包装的客户端符合该法案。

API 对象上的字段在对象被丢弃后不会随内容传递,因此它本身并不是第 50(2) 条所指的机器可读标记。

标记模块是一个钩子:

  • signed-trailer 会将来源记录嵌入文本。这是应用层绑定,不是 C2PA 清单,也不代表已判定符合第 50(2) 条。
  • packages/c2pa(从源代码构建;未发布到 npm)为 PNG 和 JPEG 实现了 MediaMarkingHook。POST /api/v1/provenance/verify 会读取清单。匹配的签名可验证该清单,但这不是符合性评估。私有 CA 会报告为 not_on_trust_list。

第 50 条的透明度义务自 2026 年 8 月 2 日起适用。对于该日期之前投放市场的 AI 系统,第 50(2) 条规定的标记和检测义务将持续至 2026 年 12 月 2 日。Code of Practice on Transparency of AI-generated Content 的签署方承诺在 2027 年 2 月 2 日前采用互操作解决方案进行检测。

假名化指纹

提示词和输出内容的哈希方式可配置:

contentHash.mode行为
keyed(默认)使用客户端持有的密钥或盐值进行 HMAC-SHA-256。服务端无法重新计算。
on不加盐的 SHA-256。
off不计算或存储指纹。

与可识别个人相关的文本指纹仍可能属于 GDPR 下的个人数据。keyed 模式旨在支持假名化(GDPR 第 4(5) 条):附加信息 HMAC 密钥由客户端持有。这并非匿名化。请勿将这些值描述为非个人数据。

遥测请求正文包含指纹、模型版本、温度和延迟。只有在嵌入了 C2PA 清单、水印钩子更改了内容,或上游状态为 provider_confirmed(响应或标记标头表明存在标记)时,contentMarkingApplied / markingApplied 才为 true。对于已签名的文本尾注、元数据钩子、仅发出请求、根据支持表进行推断、未知模型以及失败的调用,该值为 false。evidenceTrailerAttached 单独记录尾注或元数据钩子,也包含在来源签名中。记录上的状态为 upstreamMarking:requested(请求中包含标记参数)、provider_confirmed、not_requested(请求或响应表明未启用标记)、inferred(模型 ID 在有日期的支持表中,且 SDK 对象没有相关信号)或 unknown。默认值为 unknown。这并不表明标记具有抗篡改性、可检测性,也不表明其符合第 50(2) 条的要求。旧的接收布尔字段名在一个次要版本内仍可使用,并会存储为 contentMarkingApplied。重命名前封存的记录仍能匹配:同一个布尔值曾使用旧字段名进行哈希。接收路由会拒绝提示词或输出文本。

packages/sdk/README.md 列出了 withSpurvik 会记录以及不会处理的方法。嵌入、图像生成、语音、内容审核、批处理和文件上传均不会生成来源记录。Chat、messages、responses、Gemini generateContent 和 Gemini chat sendMessage 均会被包装,包括该表所涵盖的流式辅助函数。spurvik/ai 导出供 wrapLanguageModel 使用的 spurvikMiddleware。spurvik/mastra 会将该中间件传递给 wrapLanguageModel,用于 Mastra Agent 模型。spurvik/openai-agents 会包装 Agents SDK 的 Model 和 ModelProvider。抛出异常的提供方调用不会生成记录。遥测会排队并批量发送,也会在调用 shutdown() 时以及进程退出时发送一次。单次调用本身不会清空队列。

除非集成方将 beacon.consent 设为 true,否则披露标签不会写入浏览器存储。网站运营方负责获取该同意。未获得同意时,标签仍会渲染,但不会发送任何内容。服务端记录某个包含该标签的页面已被提供,不会使用信标。

上游标记证据

封装第三方模型的部署方,只有在能够证明标记有效时,才能依赖该提供商的输出标记。withSpurvik 会为每次封装调用记录一个签名证据事件。该事件会存储提供商、模型、模态、请求和响应实际公开的标记设置,以及 upstreamMarking。设置仅从 SDK 对象携带的标志和标头中读取(watermark、synthid、c2pa、溯源标头,以及 metadata、generationConfig 或 withResponse() 正文中的同名字段)。如果公开的 SDK 对象没有这类字段,状态就为 unknown,包括 OpenAI 文本(没有逐请求参数)、日期标注的帮助中心表格未列出的 Anthropic 模型、Gemini 文本和 Mistral。不会根据一方支持表推断云合作伙伴路由(Bedrock、Vertex、Foundry、Azure)。packages/core/src/upstream-support.ts 中的支持表标注了日期,并在每一行列出来源 URL。

证据使用客户端持有的签名密钥进行 HMAC-SHA-256 签名,并与审计链一同存储。它不属于记录哈希的一部分。每个事件都会记录 routeKind(direct、bedrock、vertex、azure 或 foundry)和 markingSource(response、request、header 或 none)。如果 SDK 路径不包含路由名称,请在 withSpurvik 上设置 upstreamRoute。控制平面会检查载荷结构以及事件 ID 是否匹配。它不持有密钥,因此不会重新计算签名。已发布的 [email protected] 软件包没有导出用于验证此签名的函数。该功能旨在支持你开展 EU AI Act 相关工作。

packages/core/src/marking-registry.ts 列出了用于文本、图像、音频和视频的 OpenAI、Anthropic、Google、Mistral 和开放权重模型。每个条目都有来源 URL 和读取该来源的日期(sourceReadOn)。公开页面变更时,请编辑该列表。

项目页面 Marking 会为文本输出撰写一份关于文档化限制的声明,说明为何存储的 SDK 信号无法证明存在稳健标记,并按模型和模态列出覆盖情况。可从该页面下载 JSON。所有者项目导出中也包含相同的行。删除项目会将其移除。

人类监督

人类审核队列已内置于此控制平面。监督页面和 submitHumanDecision() 会写入相同的决策行。任何组织成员都可以在控制台中暂停或作出决定。通过 API 作出决定需要审核者令牌,该令牌只能由组织所有者签发。由你选择组织中负责执行人类监督的人员(《条例》第 26(2) 条,适用于高风险 AI 系统)。第 14 条适用于自 2027 年 12 月 2 日起列于附件 III 的高风险 AI 系统。

对于高风险系统,第 14 条要求的不只是批准/拒绝关卡,还包括覆盖系统以及中断系统的能力。

  • requireHumanApproval(actionName, payload) 会创建一条待处理记录,并轮询 /api/v1/hitl/:id,直到状态不再是 pending 和 pending_confirmation,或等待结束。从 1.0.7 起,requireHumanApproval 在状态为 rejected 和 overridden 时会抛出 SpurvikHitlRejectedError;只有在返回状态 approved 时才继续。

  • submitHumanDecision(id, { status, reason }) 会记录一项 API 决策。decisionSource 为 api。控制台设置为 console。批准、拒绝和覆盖都需要提供原因。原因会保留在决策记录中,不会作为输入参与记录哈希的计算。

  • 最终决策,以及双人确认中的第一项确认,都会追加一条 human_decision 哈希链记录。该记录会存储批准 ID、状态和来源。在此字段加入之前封存的记录不包含该字段,因此其哈希仍然匹配。

  • overrideHumanDecision(id, { reason }) 会记录人工撤销。调用方是 reviewerToken,而不是自由文本 ID。

  • engageKillSwitch({ reason, actionName }) 会暂停整个项目或某项操作,releaseKillSwitch({ reason, actionName }) 会解除暂停(针对整个项目时省略 actionName)。两者都需要 reviewerToken,并会发送 x-spurvik-reviewer。在 SDK 中,两者的 reason 都是可选的。务必始终传入原因。接续上方 quickstart 中的 ai 绑定。此片段不是独立文件:

    await ai._spurvik.releaseKillSwitch({ reason: "Operator released the stop." });
    

    存储的原因是由某人输入的自由文本。Spurvik 不会检查它。

  • 当原因缺失或为空白时,SDK 会改为发送 Halted via SDK (no reason given) 或 Released via SDK (no reason given)。控制平面不会补上该值:直接调用 POST /api/v1/oversight 时,如果原因缺失或为空白,会返回 HTTP 400 reason_required(“Halting a project or action requires a reason.” 或 “Enter a reason for releasing.”)。你也可以在控制台中暂停或解除暂停:在项目的监督页面输入原因,然后选择 Engage stop 或 Release stop。

  • SDK 会随这些调用发送 reasonSource:传入原因时为 caller,替换为上述句子时为 sdk_default。该值由客户端声明,服务器不会验证。控制台写入的值为 NULL。省略该字段的原始 API 调用会存储 NULL。暂停响应会将 previousReason 设为 null。已签名的 oversight.changed webhook 会发送该写入:reason 是新原因;暂停时 previousReason 为 null,解除暂停时则为暂停原因。

  • 解除暂停响应中的 reason 是刚刚存储的解除原因。生效中的暂停原因则是 previousReason。在 GET /api/v1/oversight 响应中,previousReason 为 null,而 reason 是最近一次暂停的原因;解除暂停后也是如此。projectHalted 和 actionHalted 表示暂停是否生效。

  • 暂停已处于暂停状态的对象会返回 HTTP 409 already_halted(“This is already halted. Release it first to change the reason.”);首次暂停及其原因会保持不变。解除未处于暂停状态的对象会返回 HTTP 409 not_halted(“This is not halted.”);不会发生任何变化。

  • 对于 high_annex3,包装后的推理会检查最近一次已知的暂停状态,并在无法确认时默认拒绝。oversight.cacheMs 设置缓存窗口(0 表示每次调用都刷新)。启用暂停强制执行时,oversight.pushInvalidation(默认开启)会监听 GET /api/v1/oversight/stream 并清除缓存。该流仅限单进程。已签名的 oversight.changed webhook 可覆盖其他实例。invalidateHaltCache() 会直接清除缓存。 任何组织成员都可以在控制台中暂停或作出决定。通过 API 作出决定需要审核者令牌,且只有组织所有者可以签发该令牌。由你选择组织中负责人工监督的人员(针对高风险 AI 系统,依据第 26(2) 条)。控制台会将审核者作为组织成员登录。摄取决策需要使用项目所属组织成员的 spurvik_reviewer_ 令牌,并通过 x-spurvik-reviewer 发送。存储的审核者 ID 是该成员的用户 ID。会话 Cookie 为 spurvik_session。

双人确认是一项产品设置。它会检查是否由两个不同的成员账户确认了决定。对于标记为 Annex III point 1(a) 远程生物识别(high_annex3 和向导标志)的项目,批准和覆盖操作都要等待另一位不同的成员确认(pending_confirmation)。一位成员可以拒绝。组织所有者可以在监督页面为就业类别项目开启相同的双人确认。开启后,批准和覆盖操作都要等待另一位不同的成员确认。一位成员可以拒绝。这是一项可选设置,不是生物识别规则。执法部门在公共场所进行的实时远程生物识别属于第 5(1)(h) 条禁止的实践。向导会将其标记为“禁止”,并且不会生成 SDK 设置。

项目页面可以为该项目签发 provenance HMAC 密钥和 content-fingerprint HMAC 密钥。每个明文只会显示一次。控制平面会存储 SHA-256 值和最后四个字符,无法重新计算任一 HMAC。每个项目都应使用一组不同的密钥。

第 12(3) 条所述的引用信息(使用期间、参考数据库、输入引用以及检查结果的成员 ID)可以随遥测事件发送。存在时会纳入记录哈希;不存在时则省略。请发送 URI 或带密钥的指纹,而不是样本、图像、嵌入向量或模板。

项目可以设置 webhook URL。决策和暂停状态变更会以规范 JSON 格式通过 POST 发送。x-spurvik-signature 的值为 v1= 加上 `${timestamp}.${body}` 的 HMAC-SHA-256,x-spurvik-timestamp 为 Unix 秒数。请使用 verifyHitlWebhook 进行验证。匹配表示时间戳和请求正文仍与使用 webhook 密钥生成的 HMAC-SHA-256 签名相符,且时间戳与本地时钟相差不超过五分钟(默认值)。这并不能证明你的监督措施符合适用于高风险 AI 系统的第 14 条。若投递失败,状态路由仍是事实来源。保存 webhook 时,签名密钥只会显示一次。新保存的密钥会在 SPURVIK_WEBHOOK_KEK 下存储为 AES-256-GCM 信封(spurvik-enc:v1),密钥长度为 32 字节(base64url、hex 或 32 字节 utf8)。每种模式下都必须提供该密钥。若未提供,应用将拒绝启动或封存密钥。唯一例外是在非生产环境中设置 SPURVIK_ALLOW_TEST_KEYS=1:此时应用会为该进程生成一个随机密钥并警告一次;使用该密钥封存的密钥在重启后将无法解封。该标志仅用于本地测试,不提供完整性保护,并且当 NODE_ENV 或 VERCEL_ENV 为 production 时会被拒绝。使用旧开发回退机制封存的 webhook 密钥将无法解封。请重新输入每个 webhook 密钥。本次变更前以明文存储的密钥仍可用于签名。

人工审批摘要采用 spurvik.payload_summary.v1:规范 JSON,字段名须符合标识符格式(最多 32 个,每个最长 64 个字符),并可包含可选的十六进制指纹。长度最多为 500 个字符。不包含字段值。请勿在字段名中放入个人数据。摄取路由会拒绝自由文本。旧记录中可能仍有自由文本;新写入的数据不允许包含自由文本。 对于 high_annex3,队列满时遥测数据不会被丢弃。SDK 会先将事件同步写入磁盘缓冲区(或你传入的 DurableTelemetryBuffer / KvTelemetryBuffer),然后才将调用视为已在本地记录。如果写入失败,enqueue 会因 SpurvikTelemetryBufferError 而被拒绝。其他层级在队列满时仍会丢弃最早的内存事件。同一进程的 clientSeq 跳号会作为 chain_gap 行存入哈希链,因此账本可以显示缺失的序列号。删除磁盘缓冲区会移除尚未确认的事件。

运行 SDK

SDK 和 MCP 服务采用 MIT 许可证,可在你自己的技术栈中运行。

https://console.spurvik.com 上的托管控制台是一项托管服务。其源代码不在此代码库中,MIT 许可证也不涵盖它。

生成由客户端持有的密钥(不要将这些密钥发送给 Spurvik):

node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
数据接收路由

这些路由都需要 Authorization: Bearer spurvik_live_…。

  • POST /api/v1/telemetry
  • POST /api/v1/hitl 和 GET /api/v1/hitl/:id
  • POST /api/v1/hitl/:id/decision
  • GET /api/v1/oversight 和 POST /api/v1/oversight
  • POST /api/v1/disclosure 也接受可发布的 spurvik_pub_ 密钥。GET 不接受。

审计行按项目形成链。追加操作会对 audit_chain_heads 加行锁,因此同一项目的并发插入不会导致链分叉。账本中的 Verify hash chain 按钮会重新计算每条记录的哈希,并检查 prev_log_hash。匹配表示已存储的行仍然相连。这并不代表对 AI 系统的认证。

日志保留

保留期限为(计划中)。此代码库不会应用这些期限。

计划默认保留期限(计划中)
Developer(免费)30 天
Team90 天
Business12 个月
Enterprise按项目设置的期限,以天为单位。未设置期限的 Enterprise 项目会保留 365 天,直到所有者设置期限。

Business 是介于 Team 和 Enterprise 之间的计划。这些规则为(计划中)。该计划将适用于整个组织。对于记录为 high_annex3 的项目,计划的最低期限为六个月。在所有者确认风险层级之前,计划规则会将该项目按 high_annex3 处理,以确定保留期限。第 19 条和第 26(6) 条要求至少保留日志这么长时间,除非其他法律另有规定。层级确认后,所有者可以用简短备注记录该其他法律,此后便不再应用最低期限。Spurvik 不会核查该法律。这是一项产品规则,并非认定该项目符合上述条款。

清除功能已经存在。Spurvik 操作员会在托管控制平面上手动运行该功能。没有任何机制会安排其运行。表中的保留期限为(计划中)。检查点匹配表示该检查点的字段(项目、序列号、该哈希和清除时间)仍与使用操作员检查点密钥生成的 HMAC-SHA-256 签名相符。这并非认定你的系统符合该法案。清除并不等于删除整个项目。

项目导出和删除

组织所有者可以下载 GET /dashboard/projects/:id/export。JSON 包含项目资料、审计日志、人类决策、监督信息、披露信息、API 密钥元数据(类型、末四位字符、撤销时间)、清除检查点以及 webhook URL。它不包含 webhook 密钥和 API 密钥哈希。删除项目会移除项目行。相关日志、密钥和检查点会随之级联删除。成员帐户和审核者令牌会保留。该删除操作与保留期限清除是分开的。

调用去向

SDK 遥测数据和停止流会发送到 baseUrl。对于托管控制台工作区,该地址为 https://console.spurvik.com。披露信标会发送到你传入的端点。Webhook 会发送到项目 Webhook URL。没有许可证 ping、错误报告器、更新检查或分析调用。除非 SPURVIK_TELEMETRY 的值为 off,否则它会被忽略;GET /api/v1/health 会报告 vendorTelemetry: "off"。没有任何开关可以启用供应商接收端。控制台使用系统字体栈,因此构建时不会向字体主机发起请求。

披露标签

import { AIDisclosureLabel, AIDisclosureDetails } from "spurvik/react";

export function DisclosureExample() {
  return (
    <>
      <AIDisclosureLabel
        notice="interaction" // or "generated" | "deepfake" | "public-interest"
        presentation="inline" // pill; "block" is the default
        locale="de" // all 24 EU languages, or registerDisclosureLocale
        euIcon // optional Commission icon; always paired with visible text
        // attribution is off by default; pass attribution to show an "Art. 50 · Spurvik" link
        beacon={{ endpoint: "https://your-endpoint.example/beacon", apiKey: process.env.NEXT_PUBLIC_SPURVIK_PUB_KEY! }}
      />
      <AIDisclosureDetails riskTier="limited_art50" modelSummary="gpt-4o" provenance={{ signature: "unchecked" }} />
    </>
  );
}

示例值。请自行设置分类(作为提供者或部署者);Spurvik 不会对你的用例进行分类。

页面上无需点击即可看到标签文本。对话框仅作补充说明。IntersectionObserver 报告标签显示在屏幕上后,每个会话会触发一次信标。请传入 spurvik_pub_…,而非实时密钥。欧盟图标(基础、AI 生成、AI 修改)是欧盟委员会针对第 50(4) 条提供的可选标记。使用其中之一并不意味着单凭此举就满足第 50 条。

attribution 默认关闭。在 <AIDisclosureLabel /> 上传入 attribution={true},即可在披露文本后显示一个小型“Art. 50 · Spurvik”链接,指向 https://spurvik.com。披露文本仍然排在前面且始终可见。该链接不带查询参数,也不会设置 Cookie 或发起网络调用。

/labels 会呈现各个变体,包括适用于第 50(3) 条的 AIArticle50Section3Notice。控制台位于 /login。

操作员控制台

组织成员使用电子邮件地址和 scrypt 密码登录。任何组织成员都可以在控制台中触发停止或作出决定。通过 API 作出决定需要审核者令牌,该令牌仅组织所有者可以签发。由你选择组织中负责人工监督的人员(高风险 AI 系统适用第 26(2) 条)。只有组织所有者可以创建、轮换或撤销实时密钥和披露密钥。成员可以撤销自己的审核者令牌。只有组织所有者可以签发审核者令牌。保留期限为(计划中)。清除功能已经存在,但需要操作员手动运行。没有任何任务会自动安排清除。你可以运行欧盟风险向导、阅读旨在支持第 12 条记录保存要求的哈希链日志、查看上游标记覆盖情况、处理人工监督队列、启动停止操作、以 Markdown 或 PDF 格式下载 Annex IV 技术文档(草案),并以所有者身份导出或删除项目。数据清单页面会列出所有者可以导出的内容和不予提供的内容。本软件不收取切换费用。

向导会询问系统是否投放于欧盟市场、第 5 条中的做法是否属于禁止行为、附件 III 中哪些领域适用,以及哪些第 50 条触发条件适用。对于禁止行为的回答不会生成 SDK 代码片段。社会评分涵盖公共和私人主体(第 5(1)(c) 条)。未经同意的私密深度伪造(第 5(1)(ba) 条)和生成儿童性虐待材料(第 5(1)(bb) 条)也包括在内,并自 2026 年 12 月 2 日起适用。记录的风险等级由你的回答决定。

附件 IV 文件是根据项目字段和账本计数汇编的草案。第 2 节包含系统描述,包括向导中的回答。第 5 节,即第 9 条风险管理系统,标注为“由提供者补充”。合格评定、欧盟符合性声明和 CE 标志均为独立步骤,不会由导出功能生成。

非法律建议

Spurvik 可帮助团队实施与第 12、14 和 50 条部分内容以及附件 III/第 50 条产品分类相对应的技术措施。使用它并不意味着系统符合要求。它不会执行符合性评估、签发欧盟符合性声明、加贴 CE 标志、运行质量管理体系,也不会在欧盟数据库中注册系统。附件 IV 下载内容是草稿。风险向导会记录你的回答,并将第 5 条所列做法标记为 Prohibited,但不会判定某种用途是否属于第 6 条规定的高风险用途。

本代码库不声称数据会留在欧盟。网络弹性法案(CRA)报告流程草案见 docs/cra-article-14-reporting.md。数据法案导出说明见 docs/data-act.md。开源软件包根据 MIT License 发布([email protected]、[email protected]、[email protected]、[email protected]),并同步至 https://github.com/spurvik/spurvik;参见 LICENSE。

MCP 服务

spurvik/ai 导出供 Vercel AI SDK(ai 7)使用的 spurvikMiddleware。将其传给 wrapLanguageModel。它会记录调用并附加 HMAC 来源凭证,但不会标记内容。标记钩子由调用方提供。

组件MCP 设置
packages/mcp已作为 [email protected](MIT)发布到 npm;在此代码库中,工作区软件包 packages/mcp 在版本 1.0.5 下仍为 "private": true。只读工具:spurvik_setup_snippet、spurvik_find_unwrapped_calls、spurvik_explain_receipt、spurvik_marking_hooks、spurvik_scan_live_url(唯一会使用网络的工具:访问 console.spurvik.com 上的一个公开 URL)、spurvik_classify_ai_act_risk 和 spurvik_generate_art50_badge。plugins/spurvik/.mcp.json 会运行 node ${CLAUDE_PLUGIN_ROOT}/bin/spurvik-mcp.mjs --root ${CLAUDE_PROJECT_DIR};该文件通过 node packages/mcp/scripts/bundle-plugin.mjs 从 packages/mcp 1.0.5 打包而来。
plugins/spurvikClaude Code 插件。相同的七个只读工具为 spurvik_setup_snippet、spurvik_find_unwrapped_calls、spurvik_explain_receipt、spurvik_marking_hooks、spurvik_scan_live_url(唯一会使用网络的工具:访问 console.spurvik.com 上的一个公开 URL)、spurvik_classify_ai_act_risk 和 spurvik_generate_art50_badge。plugins/spurvik/.mcp.json 会运行 node ${CLAUDE_PLUGIN_ROOT}/bin/spurvik-mcp.mjs --root ${CLAUDE_PROJECT_DIR};该文件通过 node packages/mcp/scripts/bundle-plugin.mjs 从 packages/mcp 1.0.5 打包而来。

packages/mcp(packages/mcp)和 plugins/spurvik 提供相同的七个只读 MCP 工具:spurvik_setup_snippet、spurvik_find_unwrapped_calls、spurvik_explain_receipt、spurvik_marking_hooks、spurvik_scan_live_url(唯一会使用网络的工具:访问 console.spurvik.com 上的一个公开 URL)、spurvik_classify_ai_act_risk 和 spurvik_generate_art50_badge。packages/mcp 是供 Cursor、VS Code 和其他 MCP 客户端使用的本地 stdio MCP 服务。它已作为 [email protected](MIT)发布到 npm;在此代码库中,工作区软件包 packages/mcp 在版本 1.0.5 下仍为 "private": true。使用 npm i -D [email protected] 安装并启动,然后运行 ./node_modules/.bin/spurvik-mcp-server --root .。从 1.0.3 版本开始,必须指定 --root。Claude Code 插件会读取 plugins/spurvik/.mcp.json,该文件会运行 node ${CLAUDE_PLUGIN_ROOT}/bin/spurvik-mcp.mjs --root ${CLAUDE_PROJECT_DIR}。该服务文件通过 node packages/mcp/scripts/bundle-plugin.mjs 从 packages/mcp 1.0.5 打包而来。这些工具不会调用 Spurvik API 或任何网络服务。SDK 会记录调用并附加 HMAC 凭证,但不会标记内容。代码片段中的 riskTier 是示例值。请自行设置分类(作为提供者或部署者);Spurvik 不会对你的用例进行分类。扫描器会跳过名为 .env 或 .env.* 的文件(不区分大小写),也会跳过通过符号链接和硬链接指向的此类文件。配置示例见 packages/mcp/README.md。

多渠道 ask_human() 路由器与 n8n / Make.com 工作流防护

  • packages/sdk/src/channels.ts(createMultiChannelApprovalRouter 和 verifyChannelApprovalToken):通过 HMAC-SHA256 摘要以及已签名的 Approve / Block 链接,在 Slack、Telegram、Email(Resend)、Discord、Microsoft Teams、Linear、Jira 和 Asana 上分发人工介入审批请求。Monday.com 只会创建条目,不会发送 Approve 或 Block 链接。verifyChannelApprovalToken 会检查 Spurvik 自有的审批链接令牌,并返回 true 或 false。它不会验证平台 webhook 签名。从 1.0.5 开始,若相同令牌匹配,verifySignedChannelCallback 会返回 { ok: true, decision, gateId, actionHmac, issuedAtUnix, nonce };否则返回 false。缺少签名时会返回 false,且不会抛出异常。
  • packages/n8n-nodes-spurvik:n8n 节点和可导入的 make-com-blueprint.json。不同操作分别用于添加 AI 交互通知、记录旨在支持第 12 条记录保存要求的 HMAC-SHA256 摘要,以及发送旨在支持第 14 条人工监督要求的 ask_human() 请求。
  • 从 1.0.5 开始,createSignedApprovalLinks 生成的链接包含一个 nonce。默认有效期仍为 24 小时(86400 秒),与 1.0.4 相同。若需要 15 分钟的时限,请传入 maxAgeSeconds: 900。链接在过期前可以重复使用。接收方必须记录 nonce 并拒绝重复请求。1.0.4 令牌没有 nonce;省略 nonce 时,仍可通过 verifyChannelApprovalToken 验证。从 1.0.5 开始,必须提供 callbackBaseUrl:传入一个可接受 GET 点击请求的 URL。SDK 不会默认使用控制台 HITL 创建路由。
  • 完整的快速入门和回调验证示例:docs/multi-channel-hitl-and-n8n.md。
  • examples/ 中可运行的示例:examples/nextjs-vercel-ai-sdk、examples/slack-telegram-linear-ask-human、examples/n8n-make-import 和 examples/github-actions-ci-check。

仍待解决

  • Code of Practice 检测。 签署方承诺在 2027 年 2 月 2 日前实现可互操作的检测。C2PA 挂钩是清单写入器和读取器,并非该检测计划。
  • 公开的 C2PA 信任。 私有 CA 会进行签名,验证路由会报告 not_on_trust_list。将证书加入公开信任列表是运营方的工作。
  • 第 5 条。 禁止性做法不是风险等级值。若答案得出某个等级,向导会显示 SDK 设置。若答案属于禁止情形或适用范围在欧盟之外,则显示 “No SDK setup is offered for this answer set.”。未作答的表单不会显示任何内容。即使调用方忽略向导,向导也不会阻止调用方。
  • 附件 I。 嵌入产品的系统遵循 2028 年 8 月 2 日的规定,不属于单独的等级。
  • 共享限制。 数据摄取速率限制和 halt SSE 总线均为单进程。
  • 商标。 仓库中的 MIT License 文本适用于 packages/sdk、packages/core、packages/react、packages/mcp 和 packages/c2pa。这些工作区包仍设置为 "private": true。已发布的版本为 [email protected]、[email protected]、[email protected] 和 [email protected]。托管控制台 https://console.spurvik.com 是一项托管服务。其源代码不在此仓库中,MIT licence 不适用于该服务。

评论

支持 Markdown

第一次接触 MCP?

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

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