关于 NEAT
NEAT 将源代码静态分析与 OpenTelemetry 运行数据融合为系统实时图,供开发团队和编码 Agent 调查故障、依赖及架构偏差。它以带来源标记的图查询结果提供证据,不依赖 LLM 推理。
主要功能
- 01融合代码与运行时数据
- 02按文件和行定位关系
- 03生成故障事件卡与原因链
- 04分析影响范围和依赖
- 05检测代码与生产环境偏差
- 06持续检查架构策略
适用场景
- 01调查生产故障并定位代码
- 02评估变更可能影响的系统部分
- 03查找代码声明与实际流量的差异
- 04检查架构策略是否被违反
MCP 相关
NEAT 的 MCP 服务向 Agent 提供系统图查询工具,包括故障原因、影响范围、依赖、事件卡、偏差和策略检查。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
24收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| project | string | 否 | 当核心服务托管多个项目时,填写项目名称(设置 NEAT_PROJECTS=...)。省略则使用默认项目。 |
| question | string | 是 | 自然语言问题,例如 "why is checkout failing?" 或 "what breaks if I change the orders table?" |
详细介绍
NEAT
Agent 不擅长调查,也不擅长推理。但只要获得恰当的上下文,它们就很擅长编写代码。NEAT 负责调查和推理,让你的 Agent 专注于编写代码。
最直观的例子是事件卡片。当系统中的某处发生故障时,NEAT 会为其整理出一份工作单:故障发生的位置(如果运行时记录了位置,则精确到文件和行号)、导致故障的因果链、修复可能影响到的所有内容、约束这段代码的架构规则,以及代码与生产环境不一致之处。每项结论都会说明 NEAT 是如何得出它的——从源代码读取、在运行时观察到,还是推断得出——绝不猜测:如果 NEAT 无法追溯某个原因,就会将其留空,而不是擅自补上。Agent 读取卡片并编写修复代码,无需再搜索文件、猜测原因。
NEAT 如何开展调查:它会维护一张系统运行状态的实时图谱。图谱中的实际对象是节点——文件及其中的符号、服务、数据库、路由、配置和基础设施;节点之间由边连接,每条边都会记录 NEAT 得知它的方式:从源代码提取(EXTRACTED)、从 OpenTelemetry观测(OBSERVED)、由弥合缺口的拼接器推断(INFERRED)、运行时不再确认某条边时标记为过期(STALE),以及用于暂存提案的前沿(FRONTIER)。融合会以相同的粒度——文件和行号、符号、主机、数据库表——将代码声明的内容与生产环境中的实际情况关联起来,答案就来自这些关联。图谱是确定性的,产品中没有任何地方会调用 LLM:靠的是方法,而非模型。
NEAT 的每项能力都直接读取这张图谱,而不是在图谱之上叠加一层——根因、影响范围、依赖关系、代码与生产环境之间的差异、策略检查、事件和评级。处理自己的任务时,先查询图谱——事件、差异、根因、影响范围、依赖关系——再搜索代码。上文的事件卡片是 NEAT 发现值得处理的故障时直接交给你的内容,无需你主动获取。
NEAT 正在积极开发中。新能力会通过补丁版本发布,并在 npx neat.is 入口提供;请参阅未解决的问题,了解后续计划。
一条命令
npx neat.is
在项目目录中运行(或使用 npx neat.is <path>)。它会发现你的服务、构建静态图谱、在不修改源代码的情况下接入 OpenTelemetry,并为项目启动后台守护进程——无需配置。然后,在 NEAT 接入的情况下启动应用——对于 Node,加载 NEAT 生成的 .env.neat(运行 set -a; . ./.env.neat; set +a,然后执行你平常的启动命令);对于 Python,在 opentelemetry-instrument 下运行启动命令——图谱中的运行时部分会随着应用运行逐步补全。
请求发生故障时,你的 Agent 会通过 MCP 请求工作单:
get_incident_card { "nodeId": "service:checkout" }
并在一份答复中获取故障位置、附带各跳来源信息的因果链、影响范围、适用的策略,以及该事件的差异。每当出现新事件,neat monitor 都会打印一行信息。
在 Windows 上,请使用
neat命令,而不是npx neat.is。 npm 会生成一个名为neat.is的垫片,而 Windows 不会执行.is文件——它会将该文件交给文件关联程序处理。安装一次,然后运行不带点号的二进制文件:npm i -g neat.is,然后运行neat(或neat <path>)。如果不进行全局安装:npx -p neat.is neat。以下所有npx neat.is <verb>命令都可以按此方式改为neat <verb>。
更深入的说明:
NEAT 的核心是一张实时图谱,它将两条数据流融合为一个模型,你可以通过多种方式查询:
- 静态分析 — 使用 tree-sitter 分析你的源代码、
package.json和 yaml / env 配置。支持十一种语言,解析到符号粒度:JavaScript、TypeScript、Python、Go、Ruby、PHP、C#、Java、Kotlin、Rust 和 C++。大多数语言都能识别路由和数据库调用;运行时与代码的融合支持 JavaScript、TypeScript 和 Python;服务间的出站 HTTP 调用仅从 JavaScript 和 TypeScript 中读取,因此其他语言需要依靠运行时遥测来构建跨服务边。每个源文件都会成为一个节点;文件之间的导入关系会成为边;每个文件对数据库、队列和外部主机的调用都会从代码中提取出来。 - 运行时遥测 — OpenTelemetry 跨度会被关联回发起调用的确切文件和行。NEAT 会为你配置检测,因此运行时边会落在与静态边相同的文件节点上。
两条数据流都落在相同的节点上,因此图谱并列呈现代码声明的内容和系统实际执行的行为。由此,只需一个模型就能回答许多实用问题:如果某个节点失效,哪些部分会受到影响(影响范围);什么最先出错(根本原因);某项变更会违反哪些架构规则(策略);以及声明意图与观测到的实际情况在哪些地方不一致(偏差)。同一张图谱,不同的遍历方式。
文件是主要单位。 图谱中的关系从文件出发——src/services/billing.ts ──CALLS──▶ api.stripe.com——而不是从一个模糊的服务块出发。将关系锚定到文件和行,才能让每个答案都清晰明确:发现会指出这个文件调用了这个目标,而不是含糊其辞地指向某个服务。
每条边都带有 provenance 标签,让使用者准确判断这项声明的可信程度:
- 从源代码中
EXTRACTED(提取)。不会随时间衰减。 - 从跨度中
OBSERVED(观测)。包含lastObserved和callCount。 - 当 OTel 覆盖存在缺口时,由跟踪拼接器
INFERRED(推断)。置信度有上限。 - 因运行时不再上报而标记为
STALE(过时)。保留原始的lastObserved。
AI Agent 可通过二十四个 MCP 工具访问图谱。十四个工具用于读取图谱——ask、get_root_cause、get_blast_radius、get_dependencies、get_observed_dependencies、get_incident_history、get_incident_card、get_divergences、get_graph_diff、get_recent_stale_edges、check_policies、semantic_search、expand、relate——六个工具(neat extend)允许 Agent 为捆绑的 OTel 集合未覆盖的库补齐检测缺口,并由带版本的检测注册表驱动;另外四个工具用于将托管项目连接到提供商。
CLI
同一个 neat 二进制文件处理所有子命令。全局安装(npm i -g neat.is)或通过 npx neat.is 运行后:
neat <path> orchestrator: extract, instrument, spawn daemon, open dashboard
neat init <path> extract only; patch-by-default, --apply to write
neat watch <path> keep the graph live as files change
neat deploy emit deployment artifacts for a hosted target
neat sync --to <url> push the local EXTRACTED snapshot to a remote daemon (v0.3.9)
neat divergences where your code and your production traffic disagree
neat root-cause <id> walk inbound edges to find what broke first
neat blast-radius <id> BFS outbound; what would break if this node dies
neat dependencies <id> transitive outbound dependencies
neat incidents recent error events
neat policies current policy violations
neat search <query> semantic match on node names and ids
每个查询子命令都支持 --json 和 --project <name>。退出码分别表示成功(0)、服务器错误(1)、误用(2)和守护进程不可达(3)。
示例:偏差是什么样的
偏差是图谱能够回答的问题之一,也是最难通过其他方式回答的问题——它需要同时使用两条数据流。应用运行后,neat divergences 会报告声明意图与观测行为不一致的地方:
[missing-extracted] src/services/prices.ts ──CALLS──▶ folio-api.example.com confidence 0.87
Production observed this call, but static analysis never surfaced the edge.
→ dynamic dispatch or a coverage gap. The code reaches a host it doesn't visibly name.
[missing-observed] src/db/client.ts ──CONNECTS_TO──▶ postgres:primary confidence 0.85
Code declares this connection, but no production traffic has exercised it.
→ dead path, feature flag, or an unshipped branch. The declared dependency is idle.
两个发现,对应两个不同的 bug。第一个是代码发起了调用却没有声明——在它让你措手不及之前,了解这一点很有价值。第二个是代码包含了却从未使用的依赖——它可能是无用负担,也可能是你以为仍在运行、实际上却已失效的路径。两者都来自将同一个文件与自身对照:它声明了什么,以及它实际做了什么。
策略:图谱上的规则
偏差报告描述的是现状。策略让你可以声明应然状态。项目中的 policy.json 会将架构规则声明为针对同一图谱的断言,例如:“只有 service:billing 和 service:orders 可以连接到 postgres:primary”,或“任何文件都不得调用 legacy-api.internal”。由于规则针对实时图谱运行,因此会同时评估代码声明的内容和生产环境中的实际情况。
NEAT 会在图谱变化时持续评估每项策略。当某条边违反规则时,系统会显示违规情况,而不是将其埋没在一次性 lint 运行中。你可以通过以下两种方式查看:
neat policies列出当前违规项,可使用--node限定到某个节点,或使用--hypothetical-action对变更进行试运行。check_policies通过 MCP 将相同的结果提供给 AI Agent,这样编写新功能的 Agent 就能看到它可能违反哪些规则,以及它需要遵循哪些断言——这些规则可能由之前的功能、其他 Agent 或你的工程师设定。
block 操作会限制 FrontierNode(图谱中新发现的外部主机)的晋升,避免未经批准的外部依赖悄然进入模型。核心思路是:图谱已经了解你的架构,因此你关心的规则可以成为针对图谱的断言,并在系统变化时始终保持有效。
在服务上运行 NEAT
容器镜像 ghcr.io/neat-technologies/neat:latest 会启动 neatd start,并在 :8080 上提供 REST、在 :4318 上提供 OTLP、在 :6328 上提供 Web UI。生成令牌、运行镜像,并将 OTel SDK 指向该镜像:
NEAT_AUTH_TOKEN=$(openssl rand -hex 32)
docker run -d --name neat \
-e NEAT_AUTH_TOKEN="$NEAT_AUTH_TOKEN" \
-p 8080:8080 -p 4318:4318 -p 6328:6328 \
-v /var/lib/neat:/neat-out \
ghcr.io/neat-technologies/neat:latest
每个公共接口都必须设置 NEAT_AUTH_TOKEN。如果未设置令牌,守护进程会拒绝绑定到非回环地址。REST 和 SSE 调用方应在 Authorization: Bearer <token> 中发送令牌;OTel 导出器也应发送相同的标头。使用 NEAT_OTEL_TOKEN 单独轮换 OTLP 令牌。
更简单的方式:neat deploy 会生成令牌、写入 docker-compose.neat.yml,并打印应用部署平台所需的环境变量块:
OTEL_EXPORTER_OTLP_ENDPOINT=https://<your-host>:4318
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20<generated-token>
在反向代理后运行
如果 TLS 终止和身份验证已由上游代理处理,请设置 NEAT_AUTH_PROXY=true,让守护进程跳过请求端的 Bearer 检查。绑定权限检查仍会在未设置 NEAT_AUTH_TOKEN 时拒绝公共绑定,因此两者都要设置:
neat.example.com {
reverse_proxy localhost:8080 {
header_up Authorization "Bearer {env.NEAT_AUTH_TOKEN}"
}
reverse_proxy /events localhost:8080
@otlp path /v1/traces
reverse_proxy @otlp localhost:4318 {
header_up Authorization "Bearer {env.NEAT_AUTH_TOKEN}"
}
}
然后运行 docker run … -e NEAT_AUTH_TOKEN=… -e NEAT_AUTH_PROXY=true …,并让 Caddy 控制公共访问入口。
将 NEAT 接入你的 Agent
NEAT 的 MCP 服务已列入官方 MCP Registry,条目为 io.github.neat-technologies/neat,因此支持注册表的编辑器可以一键安装:
每个按钮都会通过 npx -y @neat.is/mcp 接入 @neat.is/mcp 服务,并将其指向你的本地守护进程;设置 NEAT_CORE_URL 可指定非默认守护进程。对于 Claude Code:
claude mcp add neat -- neat-mcp
或者手动编辑 ~/.claude/settings.json:
{
"mcpServers": {
"neat": {
"command": "neat-mcp",
"env": { "NEAT_CORE_URL": "http://localhost:8080" }
}
}
}
上面的 neat-mcp 二进制文件假定已进行全局安装。若未全局安装,请改为运行 neat skill --apply——它会使用 npx -y @neat.is/mcp 写入相同的 mcpServers.neat 条目,因此无需全局二进制文件也能解析该服务。两种方式都会读取 NEAT_CORE_URL 以获取守护进程 URL;设置该变量即可让 Agent 指向非默认守护进程。
在任意 Claude Code 会话中,询问:“checkout-svc 为什么会失败?” NEAT 会遍历图谱,并给出遍历路径、边的来源依据、置信度评分以及建议的修复方案。
先查图谱,再用 grep 搜索
neat hooks --apply
这会安装两项引导,让你的 Agent 在退回到原始文本搜索前先查询图谱:
- Claude Code 搜索引导钩子 — 一个
PreToolUse钩子;当 Agent 准备使用Grep/Glob或 Bash 的grep/rg/find时,会注入一条提示,建议先使用semantic_search、get_dependencies和get_divergences。这只是温和且不会阻止操作的引导:搜索仍会运行。它会合并到~/.claude/settings.json,不会改动其他钩子,重复运行也不会产生额外影响。 - 与 Agent 无关的图谱优先指南 — 一个 Markdown 区块(
GRAPH_FIRST.md,也会写入~/.neat/neat-graph-first.md),可粘贴到CLAUDE.md/AGENTS.md/.cursorrules中,让任何运行环境中的 Agent 都能获得相同引导。
该钩子专用于 Claude Code;其他运行环境(Codex、Gemini、Cursor)则依靠指南区块。neat hooks --print-hook、--print-guide 和 --print-settings 可分别显示各部分内容,而不会安装。
Claude Code 插件——一键安装方式
上面的 neat skill 和 neat hooks 命令是按需接入 NEAT 的方式。在 Claude Code 中,你可以通过一次插件安装获得全部功能——MCP 图谱工具、图谱优先搜索引导钩子以及技能:
claude plugin marketplace add NEAT-Technologies/Neat
claude plugin install neat@neat
该插件位于此仓库的 plugin/ 目录中,可直接从 GitHub 安装——无需额外发布。它打包的 MCP 服务配置和搜索引导钩子与按需命令写入的内容完全相同,因此两种方式的行为一致;任选其一即可。设置 NEAT_CORE_URL(默认为 http://localhost:8080)可让打包的 MCP 服务指向非默认守护进程。
仓库布局
packages/
types/ shared Zod schemas: node, edge, event, result types
core/ graph engine, tree-sitter extraction, OTel ingest, REST API, neat CLI
mcp/ stdio MCP server exposing the twenty-four tools to AI agents
web/ Next.js dashboard
claude-skill/ Claude Code skill metadata
neat.is/ umbrella package
plugin/ Claude Code plugin — bundles the MCP server, hook, and skill (repo-hosted)
文档
docs/guide/:用户指南,涵盖入门、核心概念、查询、AI Agent 和故障排除。请从这里开始。PROVENANCE.md:四种边状态,以及置信度如何沿路径传递。CLAUDE.md:供在此代码库中工作的 Agent 和贡献者参考的指南。docs/architecture.md:软件包边界和数据流。docs/api-reference.md:REST 端点和 MCP 工具签名。docs/runbook.md:日常命令和恢复操作指南。docs/contracts.md:每个 PR 都必须遵守的约束规则。CONTRIBUTING.md:分支规范、PR 形式和开发环境设置。SECURITY.md:如何报告漏洞。
贡献
欢迎提交 PR。请先阅读 CONTRIBUTING.md,了解分支规范、PR 形式,以及用于审核每项变更的约束框架。
许可证
Apache 2.0。请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。