ariadne
Ariadne
Ariadne 的线索 — 微服务迷宫的出口。
微服务架构的跨服务 API 依赖图和语义代码导航。 为 AI 编码助手(Claude Code, Cursor, Windsurf)提供的 MCP stdio 服务器,并附带用于脚本编写的 CLI 工具。基于 SQLite + TF-IDF + 嵌入(embeddings)的只读静态分析。
适用对象
AI 编码助手(Claude Code, Cursor, Windsurf)—— 提供适合上下文窗口的结构化跨服务依赖视图,替代原始的
grep输出。后端工程师 —— 追踪跨 4 个以上服务的业务功能,一次查询即可解析 GraphQL、REST、Kafka 和前端调用。
平台和评审人员 —— 进行跨服务影响分析,在发布前展示某项服务变更所触及的完整调用链。
入职工程师 —— 通过单个业务术语映射不熟悉的微服务拓扑。
Related MCP server: TempoGraph
为什么选择 Ariadne
Ariadne 仅索引契约层(Contract Layer)—— GraphQL mutations、REST 端点、Kafka 主题、前端查询——不包含其他内容。这种聚焦确保了结果能够适配 AI 的上下文窗口。
方法 | Ariadne 解决的问题 |
跨仓库 | 淹没在 DTO、测试和配置中 |
IDE "查找引用" | 在服务边界处中断 |
服务网格仪表板 | 需要生产流量;缺乏功能映射 |
完整 AST / 调用图工具 | 构建缓慢;细节过多 |
示例
你问 Claude:“createOrder 在整个技术栈中位于何处?”Claude 在对话中调用 query_chains 并得到:
Top Cluster #1 [confidence: 0.91]
Services: gateway, orders-svc, billing-svc, web
- [web] Frontend Mutation: createOrder
- [gateway] GraphQL Mutation: createOrder
- [orders-svc] HTTP POST /orders: createOrder
- [orders-svc] Kafka Topic: order-created
- [billing-svc] Kafka Listener: order-created → chargeCustomerClaude 随后总结道:“createOrder 是 gateway 中的一个 GraphQL mutation,通过 POST /orders 转发给 orders-svc,后者发布一个 order-created Kafka 事件,由 billing-svc 消费以向客户收费。”
往返约 500 个 token。而在四个仓库中执行等效的 grep -r createOrder 会返回 40 多个匹配项(包含 DTO、测试和配置),总计约 2000 个 token,且契约层被淹没其中。
黄金路径
当 AI 助手通过 MCP 服务器驱动 Ariadne 时的预期工作流。
1. query_chains(hint="createOrder")
→ ranked clusters across services. Start here for cross-service context.
2. expand_node(name="order-created")
→ one-hop neighbours of a known node. Within 10 min of a matching
query_chains, this auto-logs positive feedback — the expand IS the signal.
3. Read the files the returned clusters / neighbours point at.
4. log_feedback(hint, accepted=False, ...)
→ manual thumbs-down only. Positive feedback is captured in step 2.出现 stale_warning 时,调用 rescan() 并重试。详见 FAQ。
快速开始
执行三条命令,然后重启 Claude Code。
pip install mcp onnxruntime tokenizers huggingface_hub
cp ariadne.config.example.json ariadne.config.json # edit repos inside
python3 main.py install ariadne.config.json ~/your-workspaceinstall 是幂等的——在拉取新代码后重新运行它,或者在助手看到 stale_warning 时让其调用 rescan。查看 --help 获取标志位(--no-scan, --force, --snippet, --marker)。
工具
一旦 install 完成且 Claude Code 重启,助手将看到以下工具:
工具 | 参数 | 用途 |
|
| 业务术语 → 跨服务集群 |
|
| 已知节点的单跳邻居 |
| (无) | 当响应包含 |
| (无) | 设置指南 + 运行时配置诊断(缺失数据库、空索引、陈旧扫描) |
|
| 手动点踩(正面反馈是隐式的——详见架构下的“反馈增强”) |
配置
配置格式
{
"repos": [
{
"name": "gateway",
"path": "../gateway",
"scanners": ["graphql"]
},
{
"name": "orders-svc",
"path": "../orders-svc",
"scanners": [
"http",
"kafka",
{
"type": "backend_clients",
"client_target_map": { "billing": "billing-svc", "user": "user-svc" }
}
]
},
{
"name": "web",
"path": "../web",
"scanners": [
"frontend_graphql",
{
"type": "frontend_rest",
"base_class_service": { "OrdersApiService": "orders-svc" }
}
]
}
]
}路径相对于配置文件进行解析。每个仓库列出一个或多个扫描器——可以是名称(字符串)或带有额外选项的对象。
可用扫描器
扫描器 | 查找内容 |
|
|
| Spring |
| Spring |
| Spring |
| TypeScript |
| TS/TSX 文件中的 |
|
|
自定义扫描器
任何上述未涵盖的语言或框架都可以在不触及 Ariadne 源代码的情况下添加。实现 scanner.BaseScanner,将模块放在 Python 可导入的位置,并在 ariadne.config.json 中通过点路径引用该类:
{
"name": "my-go-service",
"path": "../my-go-service",
"scanners": [
{
"type": "my_scanners.go_scanner:GoRouteScanner",
"route_file": "cmd/server/routes.go"
}
]
}"type" 是 "module.path:ClassName"。所有其他键都会传递给 __init__。
# my_scanners/go_scanner.py
from scanner import BaseScanner
class GoRouteScanner(BaseScanner):
def __init__(self, route_file: str = "routes.go"):
self.route_file = route_file
def scan(self, repo_path: str, service: str) -> list[dict]:
# parse repo_path/self.route_file, return node dicts
return [{"id": f"{service}::http::GET::/ping", "type": "http_endpoint",
"raw_name": "ping", "service": service,
"source_file": self.route_file,
"method": "GET", "path": "/ping", "fields": []}]常见问题 (FAQ)
Ariadne 是否需要运行集群、服务器或网络?
不需要。纯静态分析。源码 → 本地 SQLite (ariadne.db, embeddings.db, feedback.db)。无网络调用,无上传。
它如何知道何时重新扫描?
如果最旧的扫描超过 7 天,MCP 响应将包含 stale_warning 字段(CLI 会将相同的警告打印到 stderr)。在 AI 对话中,调用 rescan();在 shell 中,执行 python3 main.py scan --config <path>。
结果起初看起来很通用——它们会改进吗?
会。expand_node 的后续操作会隐式记录正面反馈;增强重排序步骤(confidence + 0.15 * boost)会提升对类似提示有用的集群。第一天的结果是纯词法排序;几周后,它们将反映你团队的导航模式。基于计数,而非学习模型。
我可以不使用 AI 助手,仅作为 CLI 使用吗?
可以。python3 main.py scan / query / expand / stats —— 除了 Python 3.10 外零依赖。MCP 仍然是推荐路径。
架构
ariadne/
├── scanner/ # per-framework extractors → node dicts
├── normalizer/ # camelCase/snake/kebab → tokens
├── scoring/ # IDF-Jaccard engine + bge-small embedder
├── store/ # SQLite: ariadne.db / embeddings.db / feedback.db
├── query/ # query / expand entry points
├── mcp_server.py # MCP stdio server
├── main.py # CLI
└── tests/ # pytest suite评分
数学原理是信息检索,而非图论。节点名称被分词(createOrder → ["create", "order"])并与 IDF 加权的 Jaccard 系数进行比较:
idf_jaccard(A, B) = Σ idf(t) (t ∈ A ∩ B) / Σ idf(t) (t ∈ A ∪ B)
idf(t) = log(N / df(t))罕见 token 占主导地位;高频领域词(task, id, service)会自动衰减,无需停用词列表。
base = idf_jaccard(name) * 0.55 + idf_jaccard(fields) * 0.45
score = min(base * role_mult * service_mult, 1.0)
role_mult = 1.3 for complementary pairs
(GraphQL Mutation ↔ Kafka topic ↔ HTTP POST,
GraphQL Query ↔ Cube Query ↔ HTTP GET)
service_mult = 1.25 cross-service / 0.8 same-service聚类
两阶段,O(anchors × neighbours),与仓库数量无关。
对提示进行分词,与所有节点评分,保留
score ≥ 0.15的前 30 个锚点。对于每个锚点,从数据库中拉取其边(单个
IN查询),并保留edge_score ≥ 0.25的前 12 个邻居。合并重叠度 ≥ 25% 的锚点邻域。
每个集群中,按
(service, type)取前 2 个节点,上限为 12。置信度 = 平均边得分 · 0.6 + 类型多样性 · 0.2 + 服务多样性 · 0.2。
嵌入 (Embeddings)
TF-IDF 是主要的召回渠道。bge-small-en-v1.5(ONNX int8 量化)用于两个狭窄的任务:
召回回退:当 token 重叠较弱时,查找同义词(例如
assignHomework↔assignStudentsToTask)并将它们添加到锚点集。重排序:先构建
top_n × 2个集群,然后按0.6 · confidence + 0.4 · max_cos(hint, cluster_nodes)重新排序并截断至top_n。
ONNX 模型约为 34 MB(int8 量化),通过 onnxruntime 在 CPU 上运行。冷启动约 0.3 秒。向量缓存在 embeddings.db 中;仅查询提示在查询时进行嵌入。
反馈增强
最后的重排序步骤会根据你团队的词汇表调整排名——无需模型训练,无需上传。feedback.db 对每个开发者是本地的。
每次 query_chains 调用都会缓存返回的集群 10 分钟。后续的 expand_node(name) 如果子字符串匹配待处理集群中的节点,会自动写入 accepted=True 行——展开操作本身就是信号。log_feedback(hint, accepted, ...) 是手动点踩的出口。
在针对相同提示的下一次 query() 中:
final_score = confidence + 0.15 * sum(prior_accepted_count per node in cluster)权重(0.15)和衰减窗口(90 天)是有意保守的——词法置信度仍然占主导地位。可以通过 export ARIADNE_FEEDBACK_BOOST=0 禁用。
测试
python3 tests/test_semantic_hint.py
python3 tests/test_feedback_boost.py
python3 tests/test_implicit_feedback.py
python3 tests/test_onnx_embedder.pyhooks/pre-commit 中的预提交钩子会运行 test_semantic_hint.py —— 每个克隆执行一次启用:
ln -sf ../../hooks/pre-commit .git/hooks/pre-commit路线图
除了
application.yaml+@KafkaListener+KafkaTemplate.send之外,支持更多 Kafka 源针对极高频领域 token 的 TF-IDF 权重调整
更强的反馈信号:衰减调整、按服务加权、跨提示泛化(当前的增强是同一提示内的计数)
监视模式:挂钩 git post-commit / 文件事件以自动触发
rescan,而不是等待stale_warningexpand_node产品打磨:更清晰的触发条件、更小的输入面、指向下一步的输出所有工具的参数传递:任务导向名称优于实现名称;统一动词前缀以保持命名一致性
非目标
将 LLM 作为主要判断者(缓慢、昂贵、不可复现)
可视化 / 图数据库后端
完整的 AST 调用图提取
许可证
MIT — 详见 LICENSE。
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/whyy9527/ariadne'
If you have feedback or need assistance with the MCP directory API, please join our Discord server