Show HN:让公司 AI Agent 在行动前查阅 Git 原生规则手册
英文标题:🔶 Show HN: A company brain AI agents check before acting
gnt 提供了一套“公司大脑”规则系统,要求团队中的 AI Agent 通过 MCP 调用 `check_action`,在退款、删除数据或联系客户等高风险操作前获取允许、阻止或转人工的判定。规则以带 YAML frontmatter 的 Markdown 文件存放在 Git 仓库中,并通过已合并的 Pull Request 完成审批,因此每项决策都能追溯到具体规则文件和批准 PR。系统提供 5 个 MCP 工具,包括规则检查、语义搜索、规则溯源和技能包管理;当没有已批准规则、检索失败或检查未完成时,默认采取 fail-closed 的 `needs_human` 策略。该项目支持免费自托管,也提供 gntai.dev 托管服务;对开发者而言,其核心价值在于将 Agent 治理、审批和审计流程纳入现有 Git 工作流。
22.8 KB
40.2 KB
中文
只需运行一次以下设置,你团队运行的每个 Agent 都会拥有一份必须在行动前通过 MCP 检查的 Git 原生规则手册;其审批方式与你现有代码相同:通过一份已合并的 Pull Request。
- 规则以文件形式存放在你的仓库中,并通过常规 PR 发布,而不是通过仪表盘点击操作。
- Agent 会在执行任何高风险操作前通过 MCP 调用
check_action(例如退款、删除内容、向客户发送消息),并获得允许、阻止或升级人工处理的判定。 - 每条规则都可追溯至 Git 文件及批准它的 PR,因此对于“Agent 为什么这么做”,始终有据可查。
不想亲自运行这些组件?gntai.dev 上的托管版本可提供同样的功能,无需你部署 Postgres 实例。
gnt prebrain 扫描仓库、创建 PR 并将其合并。这是一次真实的终端会话,不是模拟图。
npm install -g @gnt-ai/cli
gnt login
gnt connect github
gnt prebrain
# 在 GitHub 上合并已创建的 PR;这次合并即构成审批
这次合并会将一个规则文件写入你已连接的仓库,结构如下:
your-repo/
└── rules/
├── refund-approval-threshold.md
└── contract-legal-cc.md
每个文件都是包含 YAML frontmatter 的纯 Markdown:
---
title: Never refund over $500 without a manager
status: approved
confidence: 0.91
owner_id: finance-team
source_citations: [...]
source: slack
tags: [refunds, finance]
last_validated_at: 2026-07-20
version: 1
superseded_by: null
approved_by: jane@company.com
approved_at: 2026-07-21T14:03:00Z
created_at: 2026-07-18T09:12:00Z
pr_number: 142
pr_url: https://github.com/your-org/your-repo/pull/142
---
Refunds over $500 need manager sign-off before they go out...
目前还没有可展示的已捕获调用记录(请参见本 README 底部提到的缺口)。以下是直接来自工具契约的 check_action 调用实际返回结构:
{
"verdict": "blocked",
"reason": "Refund exceeds the $500 threshold without manager sign-off (rules/refund-approval-threshold.md)",
"cited_rules": [
{ "id": "refund-approval-threshold", "title": "Never refund over $500 without a manager" }
],
"rules_retrieved": 3
}
verdict 的取值为 allowed、blocked 或 needs_human。needs_human 是默认的失败关闭(fail-closed)策略:没有已批准规则覆盖该操作、检索失败,或检查无法完成时均会返回该结果。系统绝不会猜测。
一个 MCP 端点,五个工具:
| 工具 | 功能 |
|---|---|
check_action |
在 Agent 执行某项描述的操作前,根据已批准规则进行检查。返回 allowed、blocked 或 needs_human,并附带引用规则和一行原因。 |
search_rules |
对组织已批准规则进行语义搜索,可按标签筛选。空列表表示没有已批准规则覆盖该查询。 |
get_rule |
按 ID 获取一条已批准规则及其来源信息(谁批准、何时批准、引用自什么来源)。 |
list_skill_packs |
列出组织的每个已编译技能包版本,按最新版本优先排序。 |
get_skill_pack |
按 ID 获取已编译技能包的清单和文件列表。 |
| 要求 | 检查方式 | 获取方式 |
|---|---|---|
| Node >=22.13 | node --version |
nodejs.org |
| 方式 | 命令 |
|---|---|
| curl | `curl -fsSL gntai.dev/install.sh |
| npm | npm install -g @gnt-ai/cli |
gnt 需要 Node >=22.13。如果 CLI 因版本错误无法启动,请先更新 Node,并通过
node --version确认版本。
gnt login # 登录,并在本地存储 API key
gnt connect github # 连接规则 PR 将针对其创建的仓库
gnt prebrain # 扫描来源、提取候选规则、创建 PR
gnt review # 审查等待批准的规则
gnt status # 显示 brain 状态
gnt pull # 下载最新技能包
gnt gaps # 列出没有已批准规则覆盖的查询
| 变量 | 默认值 | 控制内容 |
|---|---|---|
GNT_API_URL |
https://api.gntai.dev |
CLI 和 MCP 调用访问的 API 端点 |
GNT_WEB_URL |
https://gntai.dev |
gnt login 浏览器步骤使用的 Web 应用 |
GNT_CONFIG_DIR |
~/.gnt |
credentials.json 和本地配置的存放位置 |
-
CLI 和 Web 应用均不依赖分析或遥测服务。
-
gnt prebrain的默认提取模式是云端,而非设备端:你的源文本会直接发送至 Anthropic 的 API(或者,如果你进行了配置,则发送至具有零数据保留机制的 Vercel AI Gateway),绝不会发送至 gnt 自身服务器。如需完全在设备端提取,须针对本地 Ollama daemon 使用--mode local。 -
提取出的候选规则仍会发送至 gnt API 以创建 PR。在云端模式下,原始源文本不会保留在 gnt 服务器上;但生成的规则文本会保留。
-
规则存放在你已连接的 GitHub 仓库和 gnt 自身数据库中。MCP 工具从 gnt 存储读取,而不是每次调用时都克隆你的仓库。
-
自托管:仅当你自行设置
SENTRY_DSN时,apps/api才会向 Sentry 发送错误数据。保持未设置状态则不会有任何数据外发。 -
谁可以编写规则:任何有权访问你已连接仓库的人,均可通过
gnt prebrain(从真实来源批量提取)或gnt review(手动提议)创建规则。 -
审批如何进行:合并 PR 即代表审批,无需额外的发布步骤。
-
提交什么内容:
rules/<rule-id>.md文件,包含上述 frontmatter 和纯 Markdown 正文。
自托管时,
gnt login的浏览器步骤没有可访问的页面。gnt login会在浏览器中打开/cli-login页面,并轮询 API 获取生成的 key——该页面由托管产品的 Web 应用提供,而该应用并不属于这个仓库。目前没有纯 CLI 登录流程(无论是设备代码还是其他方式),也没有可手动设置 key 的gnt命令。当前自托管这套组件意味着你需要为这一条路由自行构建一个轻量前端(它只需完成登录流程并向 CLI 提供一个 key)。这是自托管路径中真实且公开的缺口,并非配置问题;要妥善解决它,需要增加纯 CLI 登录流程。
ValueError: refusing to start: these settings still have their .env.example placeholder value...apps/api/.env中仍存在change-me-...字符串。错误信息会列出每个有问题的字段;请为每项生成真实值后重试。
store启动失败,提示GNT_STORE_INTERNAL_API_SECRET is not set。apps/store/.env未填写,或未被正确读取。请确认该文件存在于该精确路径,而不是仍然命名为.env.example。
每次 store 到 API 的调用都会被 401 或 403 拒绝,即使两个服务均已运行。
apps/api/.env中的STORE_INTERNAL_API_SECRET/APPROVAL_SIGNING_SECRET与apps/store/.env中的GNT_STORE_INTERNAL_API_SECRET/GNT_APPROVAL_SIGNING_SECRET并非逐字节一致。这是有意采用的失败关闭设计。请重新生成两组值,使两个文件保持一致。
规则保存失败,并出现 embedding 或 rerank 错误。
apps/store/.env缺少ZEROENTROPY_API_KEY,或者其值仍为空。请从 zeroentropy.dev 获取一个有效 key。
gnt login
gnt logout
gnt connect <app> github, slack, notion-mcp, monday-mcp, linear-mcp, jira-mcp,
sentry-mcp, granola-mcp, zoom-mcp, figma, datadog,
gitlab-threads, hubspot, airtable, openclaw, hermes
gnt disconnect <app>
gnt status
gnt billing
gnt review
gnt pull
gnt gaps
gnt prebrain 扫描本地来源、提取候选规则、创建批量草稿
PR(约 60 个用于来源路径和提取模式的参数,参见
`gnt prebrain --help`;--mode cloud|local,默认使用 cloud)
gnt stale
gnt keys list|create|revoke|rotate
gnt webhook list|create|revoke
gnt org show|rename|invite|remove
自托管 gnt 永远无需付费:克隆项目、运行 docker compose up,并使用你自己的 key。其商业化销售的是自托管无法提供的部分:在 gntai.dev 上托管、托管式 OAuth 连接器(GitHub、Slack、Linear、Notion、Zendesk——你无需自行完成应用审批流程),以及按用量计费的 AI 功能。如果你更愿意自行运行,这是一条完整支持且完全免费的路径,并非功能受限的试用版。
开发环境设置及如何创建 PR,请参阅 CONTRIBUTING.md。每次提交都需要包含 Signed-off-by trailer(使用 git commit -s);项目采用 Developer Certificate of Origin 而不是 CLA。无需填写单独表单,只需使用该标志。
English / 原文
Run the setup below once and every agent your team runs has a git-native rulebook it has to check over MCP before it acts, approved the same way your code already is: a merged pull request.
- Rules live in your repo as files and ship through normal PRs, not a dashboard click.
- Agents call
check_actionover MCP before anything risky (a refund, a delete, a message to a customer) and get back an allow/block/escalate verdict. - Every rule traces back to the git file and the PR that approved it, so "why did the agent do that" always has a paper trail.
Prefer not to run any of this yourself? The hosted version at gntai.dev does the same thing without you standing up a Postgres instance.
gnt prebrain scanning a repo, opening a PR, and getting it merged. A real terminal session, not a mockup.
npm install -g @gnt-ai/cli
gnt login
gnt connect github
gnt prebrain
# merge the opened PR on GitHub. that merge is the approval
That merge lands a rule file in your connected repo, shaped like this:
your-repo/
└── rules/
├── refund-approval-threshold.md
└── contract-legal-cc.md
Each file is plain markdown with YAML frontmatter:
---
title: Never refund over $500 without a manager
status: approved
confidence: 0.91
owner_id: finance-team
source_citations: [...]
source: slack
tags: [refunds, finance]
last_validated_at: 2026-07-20
version: 1
superseded_by: null
approved_by: jane@company.com
approved_at: 2026-07-21T14:03:00Z
created_at: 2026-07-18T09:12:00Z
pr_number: 142
pr_url: https://github.com/your-org/your-repo/pull/142
---
Refunds over $500 need manager sign-off before they go out...
There's no captured transcript to show yet (see the gap noted at the bottom of this README). Here's the actual response shape a check_action call returns, straight from the tool's contract:
{
"verdict": "blocked",
"reason": "Refund exceeds the $500 threshold without manager sign-off (rules/refund-approval-threshold.md)",
"cited_rules": [
{ "id": "refund-approval-threshold", "title": "Never refund over $500 without a manager" }
],
"rules_retrieved": 3
}
verdict is one of allowed, blocked, or needs_human. needs_human is the fail-closed default: no approved rule covers the action, retrieval failed, or the check couldn't complete. It never guesses.
One MCP endpoint, five tools:
| Tool | What it does |
|---|---|
check_action |
Checks a described action against your approved rules before an agent takes it. Returns allowed, blocked, or needs_human with cited rules and a one-line reason. |
search_rules |
Semantic search over your org's approved rules, optionally filtered by tag. An empty list means no approved rule covers the query. |
get_rule |
Fetches one approved rule by id, with its provenance (who approved it, when, what it was cited from). |
list_skill_packs |
Lists every compiled skill pack version for your org, newest first. |
get_skill_pack |
Fetches a compiled skill pack's manifest and file list by id. |
| Requirement | Check |
| --- | --- |
| Node >=22.13 | node --version |
| Method | Command |
| --- | --- |
| curl | `curl -fsSL gntai.dev/install.sh |
| npm | npm install -g @gnt-ai/cli |
gnt needs Node >=22.13. If the CLI fails to start with a version error, update Node first and confirm with
node --version.
gnt login # sign in, store an API key locally
gnt connect github # connect the repo your rules PRs open against
gnt prebrain # scan sources, extract candidate rules, open PRs
gnt review # review rules awaiting approval
gnt status # show brain status
gnt pull # download the latest skill pack
gnt gaps # list uncovered queries with no approved rule
| Variable | Default | What it controls |
|---|---|---|
GNT_API_URL |
https://api.gntai.dev |
API endpoint the CLI and MCP calls hit |
GNT_WEB_URL |
https://gntai.dev |
Web app used for gnt login's browser step |
GNT_CONFIG_DIR |
~/.gnt |
Where credentials.json and local config live |
-
No analytics or telemetry dependency in the CLI or the web app.
-
gnt prebrain's default extraction mode is cloud, not on-device: your source text goes straight to Anthropic's API (or Vercel AI Gateway with zero-data-retention, if you configure it), never to gnt's own servers. Fully on-device extraction needs--mode localagainst a local Ollama daemon. -
The extracted rule candidates still get sent to gnt's API to open the PR. Raw source text stays off gnt's servers in cloud mode; the resulting rule text doesn't.
-
Rules live in your connected GitHub repo and in gnt's own database. The MCP tools read from gnt's store, not by cloning your repo on every call.
-
Self-hosting:
apps/apionly sends error data to Sentry if you setSENTRY_DSNyourself. Leave it unset and nothing goes out. -
Who writes rules : anyone with access to your connected repo, either through
gnt prebrain(batch-extracted from real sources) orgnt review(hand-proposed). -
How approval works : merging the PR is the approval. There's no separate publish step.
-
What gets committed :
rules/<rule-id>.mdfiles with the frontmatter shown above and a plain markdown body.
Self-hosting:
gnt login's browser step has nowhere to land.gnt loginopens a browser to a/cli-loginpage and polls the API for the resulting key — that page is served by the hosted product's web app, which isn't part of this repo. There's no CLI-only login flow (device code or otherwise) today, and nogntcommand to set a key manually. Self-hosting this stack currently means building your own thin frontend for that one route (it just needs to complete the sign-in flow and hand the CLI a key). This is a real, open gap in the self-host path, not a config issue — closing it properly means adding a CLI-only login flow.
ValueError: refusing to start: these settings still have their .env.example placeholder value...Achange-me-...string is still sitting inapps/api/.env. The error names every offending field; generate a real value for each and retry.
storefails to start withGNT_STORE_INTERNAL_API_SECRET is not set.apps/store/.envwasn't filled in, or wasn't picked up. Confirm the file exists at that exact path, not still named.env.example.
Every store-to-api call gets rejected with 401 or 403, even though both services are up.
STORE_INTERNAL_API_SECRET/APPROVAL_SIGNING_SECRETinapps/api/.envdon't byte-for-byte matchGNT_STORE_INTERNAL_API_SECRET/GNT_APPROVAL_SIGNING_SECRETinapps/store/.env. This fails closed by design. Regenerate both pairs so the two files agree.
A rule fails to save with an embedding or rerank error.
apps/store/.envis missingZEROENTROPY_API_KEY, or it's still empty. Get a real one from zeroentropy.dev.
gnt login
gnt logout
gnt connect <app> github, slack, notion-mcp, monday-mcp, linear-mcp, jira-mcp,
sentry-mcp, granola-mcp, zoom-mcp, figma, datadog,
gitlab-threads, hubspot, airtable, openclaw, hermes
gnt disconnect <app>
gnt status
gnt billing
gnt review
gnt pull
gnt gaps
gnt prebrain scan local sources, extract candidate rules, open batched draft
PRs (~60 flags for source paths and extraction mode, see
`gnt prebrain --help`; --mode cloud|local, cloud is the default)
gnt stale
gnt keys list|create|revoke|rotate
gnt webhook list|create|revoke
gnt org show|rename|invite|remove
Copyright © 2026 gnt.ai. Licensed under Apache-2.0 — see LICENSE for the terms and NOTICE for the trademark rule on forks.
Self-hosting gnt costs you nothing, forever — clone it, run docker compose up, bring your own keys. What we sell is the part self-hosting doesn't give you: hosting at gntai.dev, managed OAuth connectors (GitHub, Slack, Linear, Notion, Zendesk — no app-approval process on your end), and usage-based AI features. If you'd rather run it yourself, that's a fully supported, fully free path, not a crippled trial of the real thing.
See CONTRIBUTING.md for dev setup and how to open a PR. Every commit needs a Signed-off-by trailer (git commit -s), the Developer Certificate of Origin instead of a CLA. No separate form, just the flag.
