Skip to content

总体架构 ​

本章从部署视角与代码视角两个维度介绍 Yuheng 的整体架构:系统由哪些进程/容器组成、各组件之间如何通信、使用了哪些技术栈、主要子系统如何分工,以及代码仓库的顶层目录布局。

Yuheng 是面向 AI 智能体的知识层:负责把文档接入进来(解析、数据源同步、在线文档)、组织成知识库(分块、FAQ、Wiki、可选知识图谱)、回答问题(混合检索、重排、带引用的流式问答)、维护知识质量(知识健康),并通过 REST API、MCP Server、Go SDK、CLI 暴露给调用方。它本身不是智能体框架:不内置 Agent 编排、工具调用循环或记忆系统。

1. 系统组成 ​

Yuheng 的核心是"主服务 + 前端 + 文档解析微服务"三个进程,外加 PostgreSQL、Redis 与 RustFS(S3 兼容对象存储)三个基础设施依赖;其余组件(在线文档协同、知识图谱、联网搜索、可观测栈等)均为可选,通过 Docker Compose profile 按需启用。

1.1 核心服务(默认启动) ​

服务构建端口职责
appdocker/Dockerfile.app(Go)8080(宿主机默认只绑 127.0.0.1,APP_BIND 可改)主后端:REST API、RAG 检索问答、异步任务 worker、在线文档后端、知识健康检测。存活探针 GET /health,就绪探针 GET /ready(compose 的 healthcheck 用后者)
frontendfrontend/(NGINX + Vue 3 静态产物,需先 scripts/build_frontend_dist.sh)80(FRONTEND_PORT)Web UI;NGINX 同时是反向代理,把 /api、/files、/r 与 /collab 转发到后端(APP_HOST/APP_BACKEND_PORT/APP_SCHEME 可指向远端后端)
docreaderdocker/Dockerfile.docreader(Python)50051(仅 compose 网络内)文档解析微服务:gRPC 服务端,PDF/DOCX/Excel/EPUB/网页/音视频等格式解析与页面渲染
postgresparadedb/paradedb:v0.22.2-pg175432(网络内)唯一的数据库。ParadeDB 发行版自带 pgvector 与 pg_search(BM25),同时承担业务数据与检索索引;服务启动时检查 vector 与 pg_search 两个扩展,缺失即拒绝启动
redisvalkey/valkey:8.1.10-alpine(Valkey,协议兼容 Redis)6379(网络内)Asynq 任务队列、system_settings 变更发布订阅、分布式限流与模型并发闸门、在线文档的事件总线与权限缓存;配置 STREAM_MANAGER_TYPE=redis 时还承载 SSE 事件流
rustfsrustfs/rustfs(按 digest 固定)9000 / 控制台 9001(仅 127.0.0.1)默认的 S3 兼容对象存储(compose 默认 STORAGE_TYPE=s3、S3_ENDPOINT=http://rustfs:9000);改用本地目录或外部对象存储时它仍会启动

仓库目前不发布预构建镜像:compose 中的 image: 名只是本地构建产物的标签,docker compose up -d --build 会从源码构建。app 与 docreader 之间通过共享卷 docreader-tmp(挂载于 /tmp/docreader)传递解析产物图片;app 的本地文件存储卷为 data-files(/data/files),大视频在本地存储时也经共享路径交给 docreader,而不走 gRPC 消息体。

1.2 可选组件(Compose profile) ​

服务profile用途
collab、drawiodocs在线文档的协同编辑服务(Node + Yjs/Hocuspocus,collab/)与嵌入编辑器的 draw.io。在线文档模块本身由 YUHENG_DOCS_ENABLED 开关控制(默认关闭);不启动 collab 时编辑器退化为独占编辑(进入即取 5 分钟租约)
searxng(+ 一次性 searxng-init)searxng / full自托管元搜索引擎,为问答提供联网搜索(默认绑定 127.0.0.1:8888)
neo4jneo4j / full知识图谱存储,开关为 NEO4J_ENABLE,Bolt 协议 7687
odl-hybridodl-hybridOpenDataLoader PDF 混合解析后端(docreader 通过 HTTP :5002 调用),仅本地构建
dexdex / fullOIDC 测试用 IdP(配合 OIDC_AUTH_ENABLE),不用于生产
langfuse-*(web/worker/clickhouse/minio/db-init)langfuse / full自建 LLM 可观测栈,复用 Yuheng 的 postgres(新建 langfuse 库)与 redis
mcpfull以 HTTP/SSE 方式运行的 mcp-server/(Yuheng MCP Server)

检索引擎只有 PostgreSQL 一种(RETRIEVE_DRIVER=postgres),没有独立的向量库服务;对象存储只有 local 与 s3 两种,s3 可对接 compose 内的 RustFS,也可对接 MinIO、AWS S3 或各云的 S3 兼容端点。

1.3 部署形态 ​

除 Docker Compose 外,仓库还提供 Kubernetes Helm Chart(helm/,含 app、frontend、docreader、collab、postgres、neo4j 等模板)。

2. 技术栈清单 ​

层技术版本/说明
后端语言Gogo.mod 声明 go 1.26.0
Web 框架github.com/gin-gonic/ginv1.12.0
ORMgorm.io/gorm + postgres driverv1.31.1;PostgreSQL 是唯一数据库,没有其它方言分支
依赖注入go.uber.org/digv1.19.0(构造函数注入,见后端设计篇)
异步任务github.com/hibiken/asynqv0.26.0(基于 Redis,6 个 worker 池;无 Redis 时换成进程内同步执行器)
缓存/队列github.com/redis/go-redis/v9v9.14.1
认证github.com/golang-jwt/jwt/v5 + OIDCJWT Bearer / X-API-Key / OIDC
数据库迁移github.com/golang-migrate/migrate/v4v4.19.1;migrations/versioned/*.sql 以 embed.FS 编进二进制,启动时自动执行(AUTO_MIGRATE)
日志github.com/sirupsen/logrus + lumberjack 轮转自研 formatter,request_id 贯穿
配置config/config.yaml + 环境变量每个环境变量在 .env.example 中说明
可观测Langfuse(internal/tracing/langfuse)LLM 调用级 trace
gRPCgoogle.golang.org/grpc v1.84.0调用 docreader
LLM 接入sashabaranov/go-openai、ollama/ollama 等25 个模型提供商(internal/models/provider),多数走 OpenAI 兼容协议
向量/检索pgvector + ParadeDB pg_search引擎目录 retriever.Catalog 中只有 postgres;缺扩展则启动失败
知识图谱neo4j-go-driver/v6可选
表格摘要DuckDB(duckdb-go/v2)、pg_query_go SQL 校验入库时对 CSV/Excel 表格生成摘要与列描述(internal/dataanalysis)
协程池panjf2000/ants/v2文档处理并发池(CONCURRENCY_POOL_SIZE)
API 文档swaggo/gin-swagger非 release 模式暴露 /swagger
前端Vue 3.5 + TypeScript + Vite 7 + Pinia + vue-router + vue-i18n新代码用 Tailwind v4 + shadcn-vue,旧页面仍是 TDesign,逐屏迁移
文档解析服务Python + grpciodocreader/;解析器位于 docreader/parser/
协同编辑服务Node + Yjs(Hocuspocus)collab/;共享文档 schema 在 packages/docs-schema/

3. 进程间通信方式 ​

链路协议说明
浏览器 → frontend(NGINX) → appHTTP(REST + SSE)NGINX 反代 /api;问答走 SSE 流式响应
浏览器 → frontend → collabWebSocket(/collab)在线文档的实时协同
collab → appHTTP,HMAC 共享密钥(YUHENG_COLLAB_SHARED_SECRET)协同服务自己不连数据库:鉴权、加载、落盘全部回调 app 的 /internal/collab/*
app → collabHTTP(YUHENG_COLLAB_INTERNAL_URL)服务端整体替换页面内容(如恢复历史版本)或需要协同服务丢弃内存中的文档时调用(internal/docs/collab 的 Replace / Evict)
app → docreadergRPC(默认 docreader:50051,支持 TLS/mTLS 与 GRPC_AUTH_TOKEN)proto 定义在 docreader/proto/;大文件走流式 ReadStream
app → postgresPostgreSQL wire(GORM)业务数据 + BM25 + pgvector
app ↔ redisRESP(支持 TLS)① Asynq 任务队列(21 类任务);② system_settings 变更 Pub/Sub;③ 限流与分布式 per-model 并发信号量;④ 在线文档事件总线与权限缓存;⑤ 可选的 SSE 事件流存储
app → neo4jBolt(bolt://neo4j:7687)图谱实体/关系存取
app → searxng / 联网搜索服务商HTTPSSRF 白名单校验(SSRF_WHITELIST_EXTRA 默认放行 compose 内 searxng,rustfs)
app → 对象存储 / LLM 提供商 / 数据源HTTP(S)检索走 app → postgres,不经过独立向量库

4. 总体架构图 ​

5. 主要子系统 ​

子系统做什么代码位置
接入文件/URL/手工创建知识,docreader 解析;数据源连接器(飞书/Lark 知识库与云盘、Notion、语雀、RSS、GitLab、腾讯 ima)定时同步internal/application/service/knowledge_*.go、internal/datasource/、internal/infrastructure/docparser/
在线文档(可选)空间、页面树、协同编辑、评论、分享、历史版本;页面按空间绑定的知识库镜像为知识条目(channel=docs)internal/docs/(module.go 是对容器和路由唯一可见的入口)、collab/
组织知识库、分块、标签、FAQ、Auto-Wiki、可选知识图谱internal/application/service/、internal/infrastructure/chunker/
问答混合检索(向量 + BM25)、重排、联网搜索、带引用的流式回答internal/application/service/chat_pipeline/、knowledgebase_search*.go、internal/modelcontext/
知识健康索引后检测重复/有出入的文档、到期复核、被反馈「没帮助」的回答所引用的文档;文档负责人与派发internal/application/service/findings/、knowledge_findings.go、knowledge_stewardship.go、message_feedback.go
对外接口REST /api/v1、MCP Server(22 个工具)、Go SDK、yuheng CLI、DeepSeek Harness 插件internal/router/、mcp-server/、client/、cli/、packages/dsh-yuheng/
扩展接缝独立扩展包在不改核心的前提下增加特性、路由、检索引擎、检测器与迁移internal/extension/、internal/database/migration.go

6. 典型请求链路:文档上传与解析入库 ​

下图展示一篇文档从上传到可被检索、再到完成健康检测的链路,覆盖了大部分组件间交互(同步 API、Asynq 异步任务、gRPC 解析、Embedding 与索引写入、富化子任务):

对话链路(POST /api/v1/knowledge-chat/:session_id)为 SSE:Handler → SessionService → chat_pipeline 插件流水线(查询理解 → 并行检索 → 重排 → 合并 → Prompt 组装 → LLM 流式补全)→ 事件经 Stream Manager(内存或 Redis)推回客户端,详见《检索问答流程》。

7. 代码仓库顶层目录导览 ​

目录职责
cmd/可执行入口。cmd/server:主服务(main.go/bootstrap.go/listen.go + 平台信号处理);cmd/download/duckdb:DuckDB 扩展下载工具
internal/Go 后端全部业务代码(分层结构见后端设计篇):handler、application/service、application/repository、container(DI)、router、middleware、types、docs(在线文档模块)、extension、database、datasource、modelcontext、stream、testutil/pgtest 等
frontend/Vue 3 + Vite 的 Web 前端,构建产物由 NGINX 托管
docreader/Python gRPC 文档解析微服务:parser/ 解析器、proto/ 协议定义、tests/
collab/Node 协同编辑服务(Yjs),只在 docs profile 下运行
packages/docs-schema/(前端与 collab 共用的文档 schema)、dsh-yuheng/(DeepSeek Harness 插件)
cli/yuheng 命令行工具(独立 Go module,kb/doc/chunk/chat/session/search/model/mcp 等命令组)
client/Go SDK:以 HTTP 客户端形式封装 Yuheng API
mcp-server/Python 实现的 MCP Server(yuheng_mcp_server.py),把 Yuheng API 暴露为 MCP 工具,支持 stdio / SSE / HTTP
migrations/versioned/(PostgreSQL 版本化迁移,经 migrations/embed.go 编进二进制)、paradedb/(扩展初始化与存量库切换脚本)
config/config.yaml 主配置、builtin_models.yaml.example 声明式内置模型、prompt_templates/ 提示词模板
docker/app/docreader/odl-hybrid 的 Dockerfile 与 searxng 配置
helm/Kubernetes Helm Chart
third_party/内嵌的第三方代码(如 anydoc-go,带 anydoc 构建标签时链接的进程内 Office 解析器)
dataset/评估用 QA 数据集及生成脚本
scripts/构建、开发模式、迁移、冒烟测试等脚本(dev.sh、build_frontend_dist.sh、migrate.sh、smoke.sh)
testdata/测试数据
misc/杂项(如 dex-config.yaml OIDC 测试配置)
docs/Swagger 产物(make docs 生成)与早期专题说明,部分内容已过时;正式文档是 website-docs/
website-docs/本文档站点(VitePress)

Go 模块路径为 github.com/magicyuan876/yuheng;根目录还有 docker-compose.yml(部署编排)、docker-compose.dev.yml(开发模式依赖服务)、Makefile、VERSION(当前 0.1.0)等。

下一篇《Go 后端设计》深入 internal/ 内部:分层架构、dig 依赖注入、启动流程、路由与 RBAC、中间件、在线文档与知识健康两个子系统、领域模型与错误/日志规范。

基于 Yuheng v0.1.0 源码整理 · MIT License