Captcha 证明你是人类。HATCHA 证明你不是。
Captcha proves you're human. HATCHA proves you're not

原始链接: https://github.com/mondaycom/HATCHA

**HATCHA (计算启发式评估超快速代理测试)** 是一种“反向 CAPTCHA”,旨在通过呈现对机器来说轻而易举、但对人类来说却很困难的挑战(如复杂数学计算、字符串反转和二进制解码)来验证 AI 代理。 主要功能包括: * **安全性:** 服务器端验证确保答案永远不会到达客户端。该系统是无状态的,使用 HMAC 签名令牌,无需数据库。 * **灵活性:** 内置五种挑战类型,并允许开发者在运行时注册自定义挑战。 * **对开发者友好:** 提供对 Next.js 和 Express 的开箱即用支持,通过 React Hook 和 Provider 组件可轻松集成。 * **可定制性:** 界面完全支持通过 CSS 自定义属性进行主题设置(深色、浅色或自动)。 HATCHA 提供了一种精简、安全的方式来专门限制对自动化代理的访问,从而有效地颠覆了传统的 CAPTCHA 模型。该项目为开源项目(MIT 许可),可在 npm 上通过 `@mondaycom/hatcha-react` 和 `@mondaycom/hatcha-server` 获取。

这篇 Hacker News 帖子讨论了一个名为“HATCHA”的项目,这是一款旨在区分人类与 AI 机器人的反验证码(counter-CAPTCHA)工具。与传统的证明你是人类的测试不同,HATCHA 试图证明你“不是”机器人。 社区对此反应非常怀疑。许多用户质疑该工具的实际用途,并指出现代 AI 可以轻松解决这些挑战,或者人类完全可以将挑战外包给 AI 代理来完成。评论者指出,测试给出的时间限制非常宽松,足以让人将挑战内容复制并粘贴到大语言模型中。 这场讨论突显了在 AI 与人类协作日益紧密的时代,使用视觉或逻辑谜题作为门槛正变得愈发徒劳。一些参与者怀疑该项目是否具有讽刺意味,而另一些人则建议,相比与验证码技术玩猫鼠游戏,通过付费或信誉机制来设置内容访问门槛会是更有效的反机器人策略。最终,大家的共识是 HATCHA 更像是一个巧妙的概念,而非稳健的安全解决方案;还有几位用户打趣道,“通过”测试的唯一方法就是故意做错。
相关文章

原文

CAPTCHA proves you're human. HATCHA proves you're not.

npm License CI


HATCHA modal in action

HATCHA (Hyperfast Agent Test for Computational Heuristic Assessment) is a reverse CAPTCHA that gates access behind challenges trivial for AI agents but painful for humans — large-number multiplication, string reversal, binary decoding, and more.

  • Server-side verification — answers never reach the client. HMAC-signed tokens, stateless, no database required.
  • 5 built-in challenge types — math, string reversal, character counting, sorting, binary decode.
  • Extensible — register custom challenge generators at runtime.
  • Themeable — dark, light, or auto mode via CSS custom properties.
  • Framework adapters — Next.js App Router and Express middleware out of the box.
npm install @mondaycom/hatcha-react @mondaycom/hatcha-server
// app/api/hatcha/[...hatcha]/route.ts
import { createHatchaHandler } from "@mondaycom/hatcha-server/nextjs";

const handler = createHatchaHandler({
  secret: process.env.HATCHA_SECRET!,
});

export const GET = handler;
export const POST = handler;
// app/layout.tsx
import { HatchaProvider } from "@mondaycom/hatcha-react";
import "@mondaycom/hatcha-react/styles.css";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <HatchaProvider>{children}</HatchaProvider>
      </body>
    </html>
  );
}
"use client";
import { useHatcha } from "@mondaycom/hatcha-react";

function AgentModeButton() {
  const { requestVerification } = useHatcha();

  return (
    <button
      onClick={() =>
        requestVerification((token) => {
          console.log("Agent verified!", token);
        })
      }
    >
      Enter Agent Mode
    </button>
  );
}
# .env.local
HATCHA_SECRET=your-random-secret-here
Client                            Server
  │                                 │
  │  GET /api/hatcha/challenge      │
  │────────────────────────────────►│
  │                                 │  Generate challenge
  │                                 │  Hash answer
  │                                 │  HMAC-sign { hash, expiry }
  │  { challenge (no answer), token }
  │◄────────────────────────────────│
  │                                 │
  │  Agent solves the challenge     │
  │                                 │
  │  POST /api/hatcha/verify        │
  │  { answer, token }              │
  │────────────────────────────────►│
  │                                 │  Verify HMAC signature
  │                                 │  Check expiry
  │                                 │  Compare answer hash
  │  { success, verificationToken } │
  │◄────────────────────────────────│

The answer never reaches the client. The signed token is opaque and contains only a hashed answer + expiry. Verification is stateless — no database needed.

Type Icon What it does Time limit
math × 5-digit × 5-digit multiplication 30 s
string Reverse a 60–80 character random string 30 s
count # Count a specific character in ~250 characters 30 s
sort Sort 15 numbers, return the k-th smallest 30 s
binary 01 Decode binary octets to ASCII 30 s
import { registerChallenge } from "@mondaycom/hatcha-server";

registerChallenge({
  type: "hex",
  generate() {
    const n = Math.floor(Math.random() * 0xffffff);
    return {
      display: {
        type: "hex",
        icon: "0x",
        title: "Hex Decode",
        description: "Convert this hex number to decimal.",
        prompt: `0x${n.toString(16).toUpperCase()}`,
        timeLimit: 30,
        answer: String(n),
      },
      answer: String(n),
    };
  },
});

HATCHA uses CSS custom properties scoped under --hatcha-*. Override them on any parent element:

[data-hatcha-theme] {
  --hatcha-accent: #3b82f6;
  --hatcha-accent-light: #60a5fa;
  --hatcha-bg: #060b18;
  --hatcha-fg: #e4eaf6;
  --hatcha-success: #22c55e;
  --hatcha-danger: #ef4444;
}

Pass theme="dark", theme="light", or theme="auto" to <HatchaProvider> or <Hatcha>.

import express from "express";
import { hatchaRouter } from "@mondaycom/hatcha-server/express";

const app = express();
app.use(express.json());
app.use("/api/hatcha", hatchaRouter({ secret: process.env.HATCHA_SECRET! }));

app.listen(3000);
git clone https://github.com/mondaycom/HATCHA.git
cd HATCHA
pnpm install
pnpm build
cd examples/nextjs-app
pnpm dev

Contributions are welcome! See CONTRIBUTING.md for setup instructions and guidelines.

MIT

联系我们 contact @ memedata.com