前言
OpenFoundry 是一个开源的数据操作系统(Data Operating System),灵感来源于 Palantir Foundry 的能力模型。它将数据集成、本体论建模、权限治理、工作流自动化等能力整合到一个可审计、可扩展的软件系统中。
本文将带你从源码层面深入理解 OpenFoundry,涵盖:项目目标、模块详解、安装部署、运行测试全流程。
项目地址 :https://github.com/DioCrafts/OpenFoundry
开源协议:AGPL-3.0
一、项目目标
1.1 解决什么问题
在企业数据平台领域,常见痛点包括:
- 数据孤岛:各种数据源(MySQL、Kafka、S3、Cassandra)无法统一访问
- 权限混乱:谁能看什么数据、谁能做什么操作,缺乏统一治理
- SQL 拼接困难:业务人员无法自主查询数据,依赖工程师写 SQL
- 扩展性差:平台能力被封闭 API 限制,无法自定义
1.2 OpenFoundry 的定位
先讲一下 本体论(Ontology) 的概念------将业务实体(用户、订单、商品)和它们之间的关系抽象成统一的模型。用户不需要写 SQL,只需要理解"对象"和"关系"即可完成复杂查询。
本体论示例:
┌─────────────┐ placed_order ┌─────────────┐
│ User │ ───────────────────────▶│ Order │
│ (用户) │ │ (订单) │
└─────────────┘◀───────────────────────│ │
│ └─────────────┘
│ contains_product │
│ ◀──────────────────────────────┘
▼ │
┌─────────────┐ ▼
│ Product │◀─────────────────────────────────┘
│ (商品) │
└─────────────┘
1.3 核心特性
| 特性 | 说明 |
|---|---|
| 本体论为核心 | 对象类型、属性、动作、关系,统一的业务抽象层 |
| 契约驱动 | Protobuf → OpenAPI → 多语言 SDK,客户端与服务端同步 |
| 50 个微服务 | 每个服务独立部署、独立扩展 |
| GitOps 原生 | Helm + ArgoCD + Terraform,声明式基础设施 |
| 全链路可观测 | OpenTelemetry + Prometheus + Grafana |
二、源码模块详解
2.1 顶级目录结构
OpenFoundry/
├── apps/web/ # React 19 前端(Vite + TypeScript)
├── services/ # 50 个 Go 微服务
├── libs/ # 36 个共享 Go 库
├── proto/ # Protobuf 源定义(生成 libs/proto-gen/)
├── sdks/ # 生成的 TypeScript/Python/Java SDK
├── infra/ # Helm、ArgoCD、Terraform
├── docs/ # VitePress 文档
├── tools/ # CLI 工具
├── Makefile # 权威构建入口
└── go.mod # 单一 Go 模块
2.2 服务层(services/)
OpenFoundry 将功能划分为 50 个微服务,按能力域分组:
身份与安全域
| 服务 | 功能 |
|---|---|
identity-federation-service |
用户注册、登录、JWT 签发、MFA、WebAuthn、OIDC、SAML |
authorization-policy-service |
Cedar 引擎,ABAC/RBAC 策略评估 |
edge-gateway-service |
反向代理、JWT 验证、限流、路由 |
数据与本体论域
| 服务 | 功能 |
|---|---|
ontology-definition-service |
定义对象类型、属性、动作 |
ontology-query-service |
图遍历查询(核心查询引擎) |
ontology-actions-service |
本体论动作执行 |
dataset-versioning-service |
数据集版本控制、分支、事务 |
connector-management-service |
数据源连接器管理 |
AI 与机器学习域
| 服务 | 功能 |
|---|---|
model-catalog-service |
ML 模型目录和版本管理 |
model-deployment-service |
模型部署 |
agent-runtime-service |
AI Agent 运行时 |
llm-catalog-service |
LLM 模型管理 |
2.3 共享库层(libs/)
36 个共享库被所有服务依赖,按功能分为:
核心存储抽象
| 库 | 功能 |
|---|---|
storage-abstraction |
统一的 ObjectStore、LinkStore、SchemaStore 接口 |
cassandra-kernel |
Cassandra 后端实现(Ontology 数据实际存储在这里) |
search-abstraction |
搜索抽象层,支持 Vespa、OpenSearch、内存后端 |
安全与认证
| 库 | 功能 |
|---|---|
auth-middleware |
JWT 验证链、Claims 提取 |
authz-cedar-go |
Cedar 策略引擎 Go 实现 |
capabilities |
能力探测、依赖健康检查 |
可观测性
| 库 | 功能 |
|---|---|
observability |
slog 日志 + OpenTelemetry + Prometheus |
2.4 标准服务结构
每个微服务遵循统一的目录布局:
services/<svc>/
├── cmd/<svc>/main.go # 程序入口
└── internal/
├── server/ # chi 路由配置(/healthz、/metrics、/api)
├── handlers/ # HTTP 处理器(业务逻辑入口)
├── domain/ # 纯业务逻辑
├── repo/ # 数据访问层(sqlc 生成)
│ └── migrations/ # goose 风格 SQL 迁移
├── models/ # Wire 类型
└── config/ # koanf 配置读取
这种统一结构让团队只需学习一次,就能理解所有服务。
三、Ontology Query Service 详解
3.1 什么是本体论查询
本体论查询是 OpenFoundry 的核心查询能力 。它不同于传统 SQL,而是基于图遍历的方式工作:
用户问:"所有下单超过 1000 元的用户"
本体论查询流程:
1. 从所有 User 对象开始
2. 沿着 placed_order 边找到 Order
3. 过滤 amount > 1000 的订单
4. 返回符合条件的用户
3.2 核心代码结构
services/ontology-query-service/
├── cmd/ontology-query-service/main.go # 启动入口,配置 Cassandra 连接
└── internal/
├── handlers/handlers.go # GetObject、ListObjectsByType 等
├── handlers/traversal.go # Traverse(图遍历)、Histogram、LinkSummary
├── handlers/search.go # 全文搜索
├── handlers/mask.go # 字段级别脱敏
└── models/models.go # 请求/响应结构体
3.3 图遍历查询核心逻辑
以 Traverse 为例(traversal.go:207-291):
go
// TraverseRequest 定义了遍历请求
type TraverseRequest struct {
Tenant string // 租户 ID
StartingSet []ObjectRef // 起始对象集合
Steps []SearchAroundStep // 遍历步骤
ParameterValues map[string]any // 参数值
}
// 单步遍历的定义
type SearchAroundStep struct {
Ordinal int // 顺序
RelationID string // 关系 ID(如 "placed_order")
Direction string // 方向:outgoing / incoming
Filters []SearchAroundFilter // 属性过滤器
}
遍历执行流程:
go
// 1. 从起始点开始
current := dedupeRefs(body.StartingSet)
// 2. 逐跳遍历
for _, step := range body.Steps {
for _, ref := range current {
// 3. 查询 Links Store( Cassandra 中的边)
res, _ = h.state.Links.ListOutgoing(ctx, tenant, step.RelationID, ref.ObjectID, page, consistency)
for _, link := range res.Items {
// 4. 获取目标对象
obj, _ = h.state.Objects.Get(ctx, tenant, link.To, consistency)
// 5. 应用属性过滤
if !applyFilters(step.Filters, body.ParameterValues, obj) {
continue
}
next = append(next, ObjectRef{...})
}
}
current = next
}
3.4 与 Text-to-SQL 的对比
| 维度 | 本体论图遍历 | 大模型 Text-to-SQL |
|---|---|---|
| 原理 | 预设关系路径,按路径遍历 | 理解自然语言,生成 SQL |
| 确定性 | ✅ 可审计、无幻觉 | ⚠️ 可能生成错误 SQL |
| 灵活性 | 只能走预定义路径 | 可跨表自由 JOIN |
| 性能 | 稳定可预测 | 复杂查询延迟高 |
| 适用场景 | 结构固定的企业平台 | 临时 ad-hoc 查询 |
四、安装部署
4.1 环境要求
- Go 1.25+(用于编译)
- Docker / Docker Compose(本地开发)
- pnpm(前端开发)
- Kubernetes / ArgoCD(生产部署,可选)
4.2 克隆项目
bash
git clone https://github.com/DioCrafts/OpenFoundry.git
cd OpenFoundry
4.3 安装工具链
bash
make tools
这会安装:
buf--- Protobuf 管理golangci-lint--- Go lintsqlc--- 数据库代码生成gofumpt--- 代码格式化
4.4 本地开发(Docker Compose)
一键启动本地基础设施:
bash
docker compose -f infra/compose/docker-compose.yml up -d
这将启动:
- PostgreSQL(事务存储)
- Cassandra(本体论数据存储)
- Kafka(消息队列)
- NATS(轻量消息)
- Prometheus + Grafana(可观测性)
4.5 编译服务
bash
# 编译所有服务
make build-services
# 或编译单个服务
go build -o bin/ontology-query-service ./services/ontology-query-service/cmd/ontology-query-service
4.6 前端运行
bash
pnpm install
pnpm --filter @open-foundry/web dev
访问 http://localhost:5173 即可看到前端界面。
五、测试流程
5.1 单元测试
bash
# 运行所有单元测试
make test
# 或指定包
GOPROXY=https://goproxy.cn,direct go test -v ./services/ontology-query-service/internal/handlers/...
关键 :如果网络无法访问 proxy.golang.org,需要配置国内镜像:
bash
export GOPROXY=https://goproxy.cn,direct
5.2 运行 Ontology Query Service 测试
我们以 ontology-query-service 为例,测试覆盖了以下能力:
✅ GetObject # 单对象读取
✅ ListObjectsByType # 按类型分页查询
✅ ListOutgoingLinks # 出边查询
✅ Traverse # 图遍历
✅ Histogram # 属性聚合
✅ Search # 全文搜索
✅ ApplyPropertyMask # 字段脱敏
实际运行结果:
=== RUN TestTraverseExecutesSingleHopWithFilters
--- PASS: TestTraverseExecutesSingleHopWithFilters (0.00s)
=== RUN TestTraverseFiltersOutMismatch
--- PASS: TestTraverseFiltersOutMismatch (0.00s)
PASS ok github.com/DioCrafts/OpenFoundry/services/ontology-query-service/internal/handlers 0.594s
5.3 集成测试
需要 Docker 环境:
bash
make test-integration
这会启动 testcontainers,运行需要真实数据库的测试用例。
5.4 CI 完整检查
bash
make ci
等价于:
bash
make tidy # go mod tidy 检查
make vet # go vet 检查
make lint # golangci-lint
make contracts-check # OpenAPI + SDK drift 检查
make test # 单元测试
六、完整本地运行指南(实战)
以下步骤在 macOS + OrbStack 环境下验证通过,网络需要访问 goproxy.cn(Go 模块镜像)。
6.1 环境说明
- Docker/OrbStack:提供容器运行时,跑 PostgreSQL、Redis、NATS、Cassandra 等基础设施
- Go 1.25+:编译服务二进制
- 前端 Vite :
pnpm dev,代理 API 请求到 gateway
6.2 启动基础设施(Docker)
bash
cd infra/compose
# 启动核心基础设施服务(不跑完整 compose,避免 gcr.io 访问超时)
docker compose up -d postgres valkey nats minio cassandra cassandra-init
验证服务健康:
bash
docker ps --format "table {{.Names}}\t{{.Status}}"
预期输出:
NAMES STATUS
openfoundry-postgres-1 Up ... (healthy) 0.0.0.0:5432->5432/tcp
openfoundry-valkey-1 Up ... (healthy) 0.0.0.0:6379->6379/tcp
openfoundry-nats-1 Up ... (healthy) 0.0.0.0:4222->4222/tcp
openfoundry-minio-1 Up ... (healthy) 0.0.0.0:9000-9001->9000-9001/tcp
openfoundry-cassandra-1 Up ... (healthy) 0.0.0.0:9042->9042/tcp
6.3 编译 Go 服务
bash
# 配置 Go 国内镜像(访问 proxy.golang.org 超时时必须)
export GOPROXY=https://goproxy.cn,direct
# 编译 identity-federation-service(用户认证服务)
go build -o bin/identity-federation-service \
./services/identity-federation-service/cmd/identity-federation-service
# 编译 edge-gateway-service(API 网关)
go build -o bin/edge-gateway-service \
./services/edge-gateway-service/cmd/edge-gateway-service
编译产物在 bin/ 目录下,约 35MB 一个。
6.4 启动后端服务
终端 1 --- 启动 identity-federation-service:
bash
export DATABASE_URL=postgres://openfoundry:openfoundry@localhost:5432/openfoundry_auth_service
export JWT_SECRET=openfoundry-dev-secret
export REDIS_URL=redis://localhost:6379
export NATS_URL=nats://localhost:4222
export PORT=50112
export PUBLIC_WEB_ORIGIN=http://localhost:5173
export OPENFOUNDRY_ENV=development
./bin/identity-federation-service
日志输出:
level=INFO msg="observability initialized" service=identity-federation-service
level=INFO msg=listening service=identity-federation-service addr=0.0.0.0:50112
终端 2 --- 启动 edge-gateway-service:
bash
# 先清理占用了 50088 端口的进程
lsof -ti :50088 | xargs kill -9 2>/dev/null
# 启动网关(所有外部请求的入口),监听 50088 端口
export OF_JWT__SECRET=openfoundry-dev-secret
export OF_REDIS__URL=redis://localhost:6379
export OF_UPSTREAM__IDENTITY_FEDERATION_SERVICE_URL=http://localhost:50112
export OF_UPSTREAM__OAUTH_INTEGRATION_SERVICE_URL=http://localhost:50112
export OF_UPSTREAM__SESSION_GOVERNANCE_SERVICE_URL=http://localhost:50112
export OF_SERVER__PORT=50088
./bin/edge-gateway-service
日志输出:
level=INFO msg="observability initialized" service=edge-gateway-service
level=INFO msg="rate-limit using in-memory store"
level=INFO msg=listening service=edge-gateway-service addr=0.0.0.0:50088
6.5 启动前端(Vite)
bash
cd apps/web
pnpm install
pnpm --filter @open-foundry/web dev
前端监听 http://localhost:5173,代理 /api 请求到 localhost:50088。
6.6 API 测试
注册账号:
bash
curl -X POST http://localhost:50088/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"Test123456!","name":"Test User"}'
响应:
json
{"id":"019e68b8-d76d-781e-ada1-51ae403c587c","email":"test@example.com","name":"Test User"}
登录获取 Token:
bash
curl -X POST http://localhost:50088/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"Test123456!"}'
响应:
json
{
"status":"authenticated",
"access_token":"eyJhbGci...",
"refresh_token":"bbZkL2XBy0...",
"token_type":"Bearer",
"expires_in":3600
}
验证 Token 获取用户信息:
bash
curl http://localhost:50088/api/v1/users/me \
-H "Authorization: Bearer <access_token>"
响应:
json
{
"id":"019e68b8-d76d-781e-ada1-51ae403c587c",
"email":"test@example.com",
"name":"Test User",
"roles":["admin"],
"is_active":true,
"mfa_enabled":false
}
6.7 访问前端
bash
cd apps/web
pnpm install
pnpm --filter @open-foundry/web dev
访问 http://localhost:5173,使用刚才注册的账号登录即可。
json
{
"email":"test@example.com",
"password":"Test123456!",
"name":"Test User"
}

七、总结
9.1 项目价值
- 代码质量高:统一的服务结构、自动化的代码生成、完善的测试覆盖
- 架构现代:微服务 + 图遍历查询 + 契约驱动开发
- 可扩展性强:新增服务只需复制模板,Helm + ArgoCD 一键部署
- 治理完善:JWT + Cedar 策略 + 审计日志 + 字段级脱敏
9.2 适用场景
- 企业内部数据平台:需要统一治理数据访问权限
- 多租户 SaaS:需要 tenant 级别的数据隔离
- 图数据查询:对象关系复杂,需要本体论抽象
- AI 数据底座:为 LLM/Agent 提供可信的结构化数据