> 系列:VeapAI 自然语言操作实战(全体系架构专题)
> 版本:VeapAI 开源版 3.6.5(后端 `veap-cloud`,前端 `veap-ui`)
> 本文要点:七层分层 · 一条全链路 · 四个语义构件 · 一组跨层硬约束
## 一个没人能一次答上来的问题
有次内部评审,一位架构师问:你们这套 AI 平台到底有多少个模块?
我把附件、解析、标准、主题、向量、问答一个个数过去,数到十几就停了。不是数量多到数不清,而是按"零件"数没意义。同一个模块换个视角就能归到两个分组里,越数越乱。
后来我们把整个体系摊开,画了一张分层图:七层,每层只解决一类问题。这张图现在有三个用途——新人上手先看它,评审边界先对着它,出新需求先问它"属于哪一层"。
本文是这套架构系列的总览。先看清全景与动线,后面九篇再逐层拆开。
![AiConsole 服务入口:一套控制台里挂载了问答、文档加工与模板生成三类服务]
## 先看总图:七层结构,两次关键跳跃
![全体系总体架构:入口与触发、L5 运行时与执行、L4 向量与召回、L3 语义资产、L2 知识生产、L1 素材与识别、L0 业务基座,治理横切全链路]
这张总图上共有七层。自下往上看,真正有意思的是两次"跳跃"。
第一次跳跃,是把"文件"变成"文本"。附件格式五花八门,扫描件还只是一张图片。这一跳由解析引擎完成,产出统一的正文与摘要。
第二次跳跃,是把"文本"变成"向量"。文本再全,也只是静态资料;向量化之后,"哪条知识跟问题相关"才变成一个可计算的问题。
两次跳跃之间,站着一层最容易被忽略的东西:语义资产。它是后面所有环节的坐标系。
| 层 | 名称 | 一句话职责 | 代表对象 / 契约 |
| --- | --- | --- | --- |
| L0 | 业务基座 | 被各层依赖的平台底座 | `veap_dict_table`、生成接口清单 |
| L1 | 素材与识别 | 把附件与系统元数据变成可加工文本 | `AiDocumentParseEngine`、`ai_doc_asset` |
| L2 | 知识生产 | 把素材加工成知识条目与资源 | kbBuild 两阶段、语义模板 |
| L3 | 语义资产 | 语义的唯一事实来源 | `ai_metadata_standard`、`ai_knowledge_topic`、`ai_app_context_resource` |
| L4 | 向量与召回 | 把条目变成可检索资产 | `ai_vector_ingest_job`、检索模板 |
| L5 | 运行时与执行 | 装配服务、跑编排、执行命令与问答 | `service_inst_conf`、49 节点命令流程 |
| L6 | 治理(横切) | 审计、运营、评估、权限 | `ai_agent_instance_log`、`ai_vector_search_audit` |
## 再看动线:一条全链路怎么走
![全链路数据流:素材 → 识别 → 加工 → 资产 → 向量化 → 召回 → 执行,治理横切留痕与反哺]
把七层竖过来看,就是一条从左到右的动线:
1. 素材:附件上传或数据源同步;系统元数据(表、字典、生成接口)是第二类素材。
2. 识别:解析引擎按扩展名分发,OCR、Office、PDF、纯文本四路各自处理,产物落进文档资产。
3. 加工:附件走 kbBuild(元数据提取 → 条目拆分);系统数据走语义模板(取数 → 渲染 → 写成条目)。
4. 资产:条目按知识主题归档,主题绑定元数据标准;应用侧通过绑定关系声明"召回范围"。
5. 向量化:发布态条目分片嵌入,写入 Milvus;本地台账记录每条条目的向量落点。
6. 召回:批量检索加过滤链,交付前还要经过发布态、权限系数、ACL、重排四道关卡。
7. 执行:问答与命令消费召回证据,结果带引用溯源;全过程写审计。
这条动线有个细节值得单独说:治理不在最后。L6 的审计与运营是横切的,每一层在做事的同时就在留痕。等出事再补日志,是补不回来的。
## 静态骨架:分层架构与它的硬约束
![全体系分层架构:L0 至 L6 每层的模块构成、职责与契约要点]
总图讲动线,这张分层图讲约束。约束里最硬的三条,值得逐条说清。
最硬的一条:每个语义类型只有一个"唯一事实来源"。模型不认识"状态=启用",也不认识"角色表"到底指哪张表——这些都得有人告诉它,而且只能有一个地方说了算。
| 语义类型 | 唯一事实来源 | 表 / 接口 |
| --- | --- | --- |
| 表语义 | 数据字典 | `veap_dict_table` / `listFieldMetas` |
| 操作语义 | 生成接口清单 | `veap_block_class` / `listGeneratedApis` |
| 字段结构 | 元数据标准 | `ai_metadata_standard` / `ai_metadata_field` |
| 术语容器 | 知识主题 | `ai_knowledge_topic` |
| 召回范围 | 应用绑定 | `ai_app_topic_knowledge_config` |
跨层通信也有硬性规矩:只走公开接口,不许绕路。加工层不直连数据库;运行期不重建语义资源——资源是离线构建好的,运行期只读。
还有一条常被低估的约束:错误语义分级。用户自己能修的问题(缺配置、选错表),必须给可执行的提示;底层故障保留技术细节,不许用"操作失败"四个字糊弄过去。
这三条不是口号。它们被写进了各个模块的校验里,也被写进了审查清单里。
![编排引擎的流程列表:每条流程都有独立的版本与运行入口]
## 源码走读:全景里的每一块在哪里
全景图上的每个方块,都能在仓库里找到对应文件:
- 后端 AI 域:`veap-cloud/veap-modules/veap-ai`。标准、主题、条目、语义模板、向量化任务的接口都在这里,例如 `/metadataStandard`、`/knowledgeTopic`、`/semanticTemplate`、`/aiVectorIngestJob`。
- 向量库域:`veap-cloud/veap-modules/veap-milvus`。集合与索引管理、检索模板、检索审计,例如 `/aiMilvusCollection`、`/aiVectorSearchTemplate`。
- 附件与解析:`veap-cloud/veap-modules/veap-file`。解析引擎的 SPI 定义在 `AiDocumentParseEngine`,四个内置引擎实现同一套契约。
- 前端运行时:`veap-ui/src/components/AiConsole`。`RegistryHub` 挂 8 个注册表:capability、command、component、contextParamExtension、contextParamHydratePatcher、menu、stageOutput、workflow。
- 编排引擎:`veap-ui/src/components/AiAgentEngine`。19 类节点、状态机、调度与审计都在这里;画布在 `veap-ui/src/views/ai/agentDesign`。
- 表结构全集:`veap-cloud/DB/veap.sql`。本文提到的每张表都可以在这里对照字段与注释。
补一句规模感:L5 上有一条典型流程,内部叫"全局语义命令体系"。它由 49 个节点、58 条连线组成,全部在可视化画布上维护,没有流程代码。
## 较真:一条被我们自己"放开"的接口契约
这套体系里最容易出错的地方,不是模型,而是接口契约的松紧。
有个真实案例。数据字典服务里有个接口,负责返回一张表关联的标题字段,供下游拼装查询规则使用。最早实现时我们加了两道过滤:标题字段为空的行直接跳过。
当时的想法是"脏数据不要流出去"。但下游的提示词契约写着另一句话:标题字段为空时,由字段筛选规则自行判定。
两边各自都合理,撞在一起就是事故:用户选到一张没配标题字段的表,界面报"缺少表关联信息"。排查了半天,结论不是缺数据,是我们自己的过滤把数据挡在了半路。
最后的处理是放开过滤,允许标题字段为空串,把"如何兜底"交还给原本就有规则的消费方。
这个坑给我们的教训写进了规范:共享接口收紧容易、放开难。任何一次"看起来更安全"的过滤,都要先全仓检索消费方,确认没有下游依赖被你滤掉的信息。
架构图上的"契约"两个字,背后就是这类具体到字段的取舍。
## 复现与边界:没有魔法,只有契约
这套体系全部开源。要把全景图在本地跑起来,最少需要三步:
1. 克隆仓库:https://gitee.com/mindock/veap (后端 `veap-cloud` 与前端 `veap-ui` 同仓)。
2. 建库:导入 `veap-cloud/DB/veap.sql`,得到全部表结构与基础数据。
3. 启动:后端以 `veap-package/veap-monolith` 为单体入口(同一套源码也支持微服务模式);前端工程 `veap-ui` 按仓库 README 的快速开始启动。
后面的九篇会按层展开:附件层、语义层、两条知识加工链、向量与召回、前端运行时、执行层、治理层,最后一篇收在架构原则与演进方向上。
最后说说边界,避免期待错位。这条全链路做的是"把已有资料和已有系统变成可被自然语言消费的知识与操作",它不生成业务数据,也不替你定义业务口径。写操作目前只有新增、修改、删除、授权四类;复杂查询限定在受控的结构化查询范围内。
全景图上没有魔法,只有拼接好的零件和一整套写死的契约。