Doramagic 项目包 · 项目说明书

EDDI 项目

EDDI 是一款基于配置驱动的引擎,可将 JSON 转化为生产级 AI 智能体,支持多智能体编排、12+ LLM 提供商、MCP/A2A 协议、RAG、持久化记忆,并遵循 EU AI Act、GDPR、HIPAA 等企业合规要求,基于 Quarkus 构建。

项目概览

EDDI 是一个面向企业级生产环境的多代理(Multi-Agent)对话式 AI 平台,基于 LangChain4j 1.13.0 与 Quarkus 3.34.5 LTS 构建,运行于 Java 25 之上。项目提供从对话机器人编排、工具调用、向量检索、多模态附件处理到人机协同审批(Human-in-the-Loop)的完整能力栈,旨在让组织能够在 Slack、REST、...

章节 相关页面

继续阅读本节完整说明和来源证据。

项目定位与目标

EDDI 是一个面向企业级生产环境的多代理(Multi-Agent)对话式 AI 平台,基于 LangChain4j 1.13.0 与 Quarkus 3.34.5 LTS 构建,运行于 Java 25 之上。项目提供从对话机器人编排、工具调用、向量检索、多模态附件处理到人机协同审批(Human-in-the-Loop)的完整能力栈,旨在让组织能够在 Slack、REST、MCP 等多种渠道上部署具备自主规划与协作能力的 AI 代理。资料来源:README.md:1-40

平台自 v6.0.0 起进入通用可用(GA)阶段,并在 6.1.x、6.2.x 系列中持续强化安全、可观测性与多代理编排能力。资料来源:CHANGELOG.md:1-30

技术栈与基础设施

层级选型
运行时Java 25
应用框架Quarkus 3.34.5 LTS
LLM 集成LangChain4j 1.13.0
数据存储MongoDB / PostgreSQL
向量存储ChromaDB
前端React 19 + Vite
容器化Docker / Kubernetes

资料来源:pom.xml:1-120、资料来源:src/main/docker/Dockerfile:1-40。项目同时提供 ClusterFuzzLite 集成用于持续模糊测试,以保障输入处理的健壮性。资料来源:.clusterfuzzlite/Dockerfile:1-25

核心能力模块

EDDI 围绕"对话即编排"的设计理念组织能力:

  • 多代理编排:支持 TASK_FORCE 风格的动态子代理创建与任务委派,代理可在运行时招募并协调子代理完成复杂任务。资料来源:CHANGELOG.md:50-90
  • 声明式代理(Declarative Agent)与工具框架:通过 DeclarativeAgentDeclarativeAgentTask 将代理定义为目标驱动的规划执行体,支持工具自主调用。资料来源:CHANGELOG.md:200-260
  • 人机协同审批(HITL):v6.2.0 引入两级独立审批门——轮次级与单次工具调用级,覆盖 Slack、REST、MCP 三类审批入口,并具备崩溃恢复、超时策略与完整审计轨迹。资料来源:CHANGELOG.md:10-45
  • 多模态附件管道:完整支持图像、文档等附件的摄取、解析与上下文注入。资料来源:CHANGELOG.md:55-80
  • 全局变量存储与记忆摘要:通过 LLM 驱动的记忆摘要实现跨会话上下文持久化,并提供集群级 Global Variable Store 共享状态。资料来源:CHANGELOG.md:90-130
  • 渠道连接器:原生嵌入 Slack 连接器,并提供 REST 与 MCP 接口。资料来源:CHANGELOG.md:140-180

安全与可观测性

平台在 v6.0.2、v6.1.1 等硬化版本中完成关键 IDOR 漏洞修复,测试覆盖率超过 90% 指令 / 80% 分支,并达成 OpenSSF Scorecard Gold 评级。资料来源:CHANGELOG.md:180-230、资料来源:licenses/README.md:1-30。Admin UI 已在 v6.0.2 中完全重写,提供品牌化暗色模式与重写后的 Swagger UI,便于运维人员对代理、工具与渠道进行集中管理。资料来源:CHANGELOG.md:230-280

高层架构

flowchart LR
    U[用户渠道<br/>Slack / REST / MCP] --> G[API 网关]
    G --> O[多代理编排器]
    O --> A[声明式代理]
    A --> T[工具调用]
    A --> V[向量存储<br/>ChromaDB]
    A --> M[记忆与<br/>全局变量存储]
    T --> H[HITL 审批门]
    H --> O
    O --> U

资料来源:docs/architecture.md:1-60、资料来源:src/main/resources/application.properties:1-80

社区关注点

社区中反馈较多的运行期问题主要与 Kubernetes 部署下的 CPU 突增相关(见 Issue #390),常见诱因包括 LLM 调用阻塞、向量检索线程配置不当以及定时任务堆积。在 v6.x 系列中,平台引入了多模型级联(multi-model cascade)与超时策略以缓解此类资源压力。资料来源:CHANGELOG.md:40-70

资料来源:pom.xml:1-120、资料来源:src/main/docker/Dockerfile:1-40。项目同时提供 ClusterFuzzLite 集成用于持续模糊测试,以保障输入处理的健壮性。资料来源:.clusterfuzzlite/Dockerfile:1-25

Api 模块

Api 模块是 EDDI 平台对外暴露 REST 接口的契约层,统一集中于 src/main/java/ai/labs/eddi/engine/api 目录下。该模块以纯 Java 接口形式声明 HTTP 路由、参数、返回值与异常,由 Quarkus 的实现类完成具体服务暴露,构成 EDDI 6.x 重构后端架构中的"门面"层。通过将这些接口集中维护,Admin UI、Sw...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 对话域接口

继续阅读本节完整说明和来源证据。

章节 智能体域接口

继续阅读本节完整说明和来源证据。

章节 平台基础设施接口

继续阅读本节完整说明和来源证据。

概述与定位

Api 模块是 EDDI 平台对外暴露 REST 接口的契约层,统一集中于 src/main/java/ai/labs/eddi/engine/api 目录下。该模块以纯 Java 接口形式声明 HTTP 路由、参数、返回值与异常,由 Quarkus 的实现类完成具体服务暴露,构成 EDDI 6.x 重构后端架构中的"门面"层。通过将这些接口集中维护,Admin UI、Swagger UI、Channel Connector、MCP 客户端以及第三方调用方可基于同一份契约调用对话、智能体与平台管理能力。资料来源:src/main/java/ai/labs/eddi/engine/api/IConversationService.java:1-30

核心接口分组

Api 模块按业务域划分为三类接口集合。

对话域接口

智能体域接口

平台基础设施接口

架构层级与请求流转

接口主要 HTTP 动词典型路径前缀关联引擎/客户端
IConversationServicePOST / GET / DELETE/conversationConversation Engine、Channel Connector
IGroupConversationServicePOST / PUT/groupConversationMulti-Agent Orchestrator
IRestAgentAdministrationPOST / GET / PUT / DELETE/agentsAgent Store / Versioner
IRestAgentEnginePOST/agentEngineDeclarativeAgent Executor
IRestAgentEngineStreamingPOST (text/event-stream)/agentEngineStreamingStreaming Pipeline + HITL
ILogoutEndpointPOST/logoutSecurity Filter

调用方通过 Admin UI、Swagger UI、Channel Connector 或 MCP 客户端访问上述路径,由 Quarkus 路由把请求映射到 Api 接口对应的实现类,再下钻到 Engine 层执行业务逻辑。资料来源:src/main/java/ai/labs/eddi/engine/api/IRestAgentEngine.java:35-68

安全加固与社区关注

EDDI 6.1.1 在 Api 模块大规模修复了 IDOR(不安全直接对象引用)漏洞,要求所有用户面接口强制校验所属租户与权限,关闭横向越权访问。资料来源:src/main/java/ai/labs/eddi/engine/api/IConversationService.java:56-82src/main/java/ai/labs/eddi/engine/api/IRestAgentAdministration.java:62-95

社区提交的 Issue #390 报告:在 Kubernetes 中部署 EDDI 5.1.1 时出现 CPU 高占用导致 Pod 被杀的问题。Api 模块本身不直接消耗计算资源,但所有进入 Engine 层的请求都会经由该契约层转发。建议在排查时结合 Micrometer / Prometheus 按端点暴露的延迟与吞吐指标,定位高负载接口后再针对实现层做并发或缓存优化。资料来源:src/main/java/ai/labs/eddi/engine/api/IRestAgentEngineStreaming.java:27-60

EDDI 6.2.0 引入的 Human-in-the-Loop 框架在 Api 层落地为新增的"批准"端点:turn 级与 tool-call 级双网关分别扩展自 IRestAgentEngineIRestAgentEngineStreaming,配合 Slack、REST 与 MCP 三类审批面共同执行,并附带超时策略、崩溃恢复与完整审计链路。资料来源:src/main/java/ai/labs/eddi/engine/api/IRestAgentEngine.java:44-72

Swagger UI 在 v6.1.1 中被完全重写为带品牌的暗色模式,所有上述接口的 OpenAPI 描述均由 Api 模块的 JAX-RS 注解自动生成,开发者可以直接在 /swagger-ui 浏览并试用。资料来源:src/main/java/ai/labs/eddi/engine/api/IRestAgentAdministration.java:30-58

来源:https://github.com/labsai/EDDI / 项目说明书

Runtime 模块

Runtime 模块是 EDDI 平台对话引擎(Conversation Engine)的核心运行时,负责加载已部署的 Bot、调度 Agent 任务执行、管理对话生命周期并对每一次交互产出完整的审计日志。该模块位于 ai.labs.eddi.engine.runtime 包下,向上对 REST/Channel Connector 暴露统一的对话执行入口,向下对接持久化层(...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 BaseRuntime

继续阅读本节完整说明和来源证据。

章节 IAgent 与 IAgentDeploymentManagement

继续阅读本节完整说明和来源证据。

章节 ConversationSetup

继续阅读本节完整说明和来源证据。

模块概述

Runtime 模块是 EDDI 平台对话引擎(Conversation Engine)的核心运行时,负责加载已部署的 Bot、调度 Agent 任务执行、管理对话生命周期并对每一次交互产出完整的审计日志。该模块位于 ai.labs.eddi.engine.runtime 包下,向上对 REST/Channel Connector 暴露统一的对话执行入口,向下对接持久化层(MongoDB/PostgreSQL)与 LLM Cascade,是连接"配置态 Bot"与"运行态对话"的桥梁 资料来源:src/main/java/ai/labs/eddi/engine/runtime/BaseRuntime.java:1-40

模块的核心抽象是 IBotIBotFactory,运行时通过这两个接口在内存中装配一个可执行的 Bot 实例,并将每一次用户输入委派给 Bot 内部的 Step 链或 Declarative Agent 处理 资料来源:src/main/java/ai/labs/eddi/engine/runtime/BaseRuntime.java:41-120

核心组件

BaseRuntime

BaseRuntime 是所有 Runtime 实现(如 BotManagementBotFactory)的基类,封装了公共依赖注入与生命周期方法。其内部通过 CDI 注入 IBotFactoryIRestMatcherIBot 等协作对象,并在初始化阶段建立与持久化存储的连接 资料来源:src/main/java/ai/labs/eddi/engine/runtime/BaseRuntime.java:60-95

IAgent 与 IAgentDeploymentManagement

IAgent 是 Declarative Agent 框架的运行时入口,定义了 Agent 在一次任务循环中所需的状态查询、计划执行、工具调用与终止回调 资料来源:src/main/java/ai/labs/eddi/engine/runtime/IAgent.java:1-60IAgentDeploymentManagement 则提供 Agent 部署包的版本管理、热加载与回滚能力,是 6.0.0 引入 Declarative Agent 后扩展出来的部署面接口 资料来源:src/main/java/ai/labs/eddi/engine/runtime/IAgentDeploymentManagement.java:1-50

ConversationSetup

ConversationSetup 负责在新建一次对话时合并"Bot 配置 + 用户上下文 + 渠道会话标识",构造出 ConversationContext。它同时承担 memory pack(含短期记忆、长期记忆、变量存储)的初始化职责,使得后续 Step 在执行时能透明地读写 Memory 资料来源:src/main/java/ai/labs/eddi/engine/runtime/ConversationSetup.java:30-90

日志与审计子系统

Runtime 模块对每一次对话执行都强制产出结构化日志,这套机制由两个组件协作完成:

这种"内存缓冲 + 异步落库"的双层结构兼顾了实时可观测性与 I/O 吞吐,也是社区在 issue #390 中反馈的"高 CPU 占用"场景下的关键路径——Bot 每次 step() 调用都会向日志总线写一条记录,需注意日志采样率与 Step 链长度的乘积 资料来源:issue #390

数据流与调用链路

下图展示了 Runtime 模块在一次典型"用户发送文本"事件中的调用顺序:

sequenceDiagram
    participant U as 用户/Channel
    participant R as REST Resource
    participant RT as BaseRuntime
    participant CS as ConversationSetup
    participant B as Bot (IBot)
    participant L as BoundedLogStore
    participant DB as DatabaseLogs

    U->>R: sendMessage(conversationId, text)
    R->>RT: execute(conversationId, text)
    RT->>CS: createContext(botId, userInfo)
    CS-->>RT: ConversationContext + Memory
    RT->>B: invoke(context, text)
    B-->>RT: List<BotResponse>
    RT->>L: append(LogEntry)
    L-->>DB: flush(batch)
    RT-->>R: ExecutionResult
    R-->>U: BotResponse

在 v6.1.0 之后,链路末端的 invoke() 可以委派给 IAgent,由 Agent 自主规划工具调用与多轮循环;v6.2.0 进一步在 Agent 与 Tool Call 之间插入 Human-in-the-Loop 审核关卡,Runtime 模块会缓存待审动作并在审批通过后继续执行 资料来源:release 6.2.0

扩展与自定义

开发者可通过以下方式扩展 Runtime:

小结

Runtime 模块通过 BaseRuntime + ConversationSetup + 日志子系统 + Agent 接口族的协同,构成了 EDDI 对话能力的执行核心。它向上提供统一的对话 API,向下托管 Bot 装配、Agent 执行、Memory 初始化与审计落库全流程,是理解 EDDI v6 系列(特别是 HITL、TASK_FORCE、Multimodal 流水线)所有上层特性行为落点的关键模块。

来源:https://github.com/labsai/EDDI / 项目说明书

Client 模块

engine/runtime/client 包是 EDDI 引擎运行时(Engine Runtime)调用远端 EDDI 服务(Bot 管理、控制台、资源配置)时所使用的轻量级 HTTP/REST 客户端层。它并不直接承载业务对话逻辑,而是为运行时内的各个子系统(如 Bot Loader、Resource Loader、Agent 装载)提供统一的、带版本控制的远端访问能力...

章节 相关页面

继续阅读本节完整说明和来源证据。

模块定位与职责

engine/runtime/client 包是 EDDI 引擎运行时(Engine Runtime)调用远端 EDDI 服务(Bot 管理、控制台、资源配置)时所使用的轻量级 HTTP/REST 客户端层。它并不直接承载业务对话逻辑,而是为运行时内的各个子系统(如 Bot Loader、Resource Loader、Agent 装载)提供统一的、带版本控制的远端访问能力。运行时整体借助 IRestInterfaceFactory 抽象出来的“接口代理工厂”机制,将标注为 JAX-RS 风格的远端 API 客户端接口在本地动态实例化,从而既保持类型安全的调用方式,又避免在运行时耦合具体的 HTTP 栈。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/factory/IRestInterfaceFactory.java:1-1

模块按职责被划分为三个子包:用于动态构建 REST 客户端接口的 factory、用于代理资源(Resource)配置 REST 服务的 configuration、以及用于代理 Agent 存储 REST 服务的 agents。三个子包均遵循“接口 + 实现 + CDI 注入”的标准模式,便于在 Quarkus 容器中被替换或扩展。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java:1-1、资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/configuration/IResourceClientLibrary.java:1-1

客户端工厂层:RestInterfaceFactory

IRestInterfaceFactory 定义了一个统一的工厂接口,核心方法是根据传入的 Class 对象构造出对应的远端 REST 客户端实例。该接口的设计目标是让上层调用方不再关心 HTTP 细节,只面向接口编程。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/factory/IRestInterfaceFactory.java:1-1

实现类 RestInterfaceFactory 通过 @ApplicationScoped 暴露为 CDI 单例 bean,其内部维护一个 ClassToInterfaceHashMap 类型的映射表 interfaceImplementations,并通过 ConcurrentHashMap 提供线程安全的并发访问能力。构造过程会先基于目标接口生成具体的实现逻辑,再把每次新生成的实现注册进该映射表,从而对相同接口的二次请求进行缓存,避免重复构造。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/factory/RestInterfaceFactory.java:1-1

getRestInterface(Class restInterface) 方法是该工厂的主要入口:当传入的接口类尚未在映射表中时,会生成新的实现并存入;当已存在时则直接复用,从而以懒加载 + 缓存的方式控制运行时实例数量,对 Kubernetes 中常见的横向扩容场景(例如 Issue #390 中提到的 “High CPU consumption” 投诉)较为友好,避免因每次调用都反射生成代理对象而耗尽 CPU。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/factory/RestInterfaceFactory.java:1-1

资源配置客户端:ResourceClientLibrary

IResourceClientLibrary 接口抽象了运行时加载远端资源(规则集、对话流程模板、字典等)所需的操作集合,是运行时资源装配的关键入口。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/configuration/IResourceClientLibrary.java:1-1

实现类 ResourceClientLibrary 通过构造器注入 IRestInterfaceFactory,并在初始化阶段调用工厂方法得到 IResourceClient 实例,把它保存在私有字段中,供后续业务调用。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/configuration/ResourceClientLibrary.java:1-1

这种“在客户端库中只保存一个由工厂构造出的代理对象”的写法,使得 ResourceClientLibrary 自身的职责非常薄——它仅仅是把运行时需要的远端资源接口适配进引擎内部,避免在业务调用栈中直接出现工厂调用,从而降低了上层调用方的耦合度。

Agent 存储客户端:AgentStoreClientLibrary

IAgentStoreClientLibrary 在结构上与 IResourceClientLibrary 类似,但其抽象的是 Agent 维度的远端存储接口,主要供运行时在装配 Bot 时查询和拉取 Agent 相关的元数据及配置。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java:1-1

AgentStoreClientLibrary 同样通过 @Inject 接收 IRestInterfaceFactory,在初始化时一次性构造出实际的 REST 接口实现实例,并将其缓存在本地。这种“一次性构造 + 长期复用”的模式,使得 Agent 装载流程在面对大量 Bot 并发初始化时也保持线性、可预测的内存占用。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/agents/AgentStoreClientLibrary.java:1-1

借助 v6.1.2 引入的 Task Force Discussion Style 以及 v6.x 全新的多 Agent 编排能力,运行时需要频繁地按需拉取和解析 Agent 描述信息;IAgentStoreClientLibrary 的存在使得这种动态 Agent 招募可以通过标准 HTTP/REST 通道完成,与底层采用何种 LLM 服务解耦。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java:1-1

模块架构概览

下表给出 Client 模块中各组件的角色与协作关系,便于快速理解整体结构。

组件角色关键依赖主要职责
IRestInterfaceFactory工厂接口定义按 Class 动态生成 REST 客户端实例的契约
RestInterfaceFactory工厂实现(@ApplicationScopedConcurrentHashMap 缓存生成并缓存远端接口实现,避免重复反射
IResourceClientLibrary资源客户端接口IRestInterfaceFactory抽象资源(规则/模板)加载方法
ResourceClientLibrary资源客户端实现IRestInterfaceFactory缓存 IResourceClient,对外提供资源访问能力
IAgentStoreClientLibraryAgent 客户端接口IRestInterfaceFactory抽象 Agent 存储读取方法
AgentStoreClientLibraryAgent 客户端实现IRestInterfaceFactory缓存 Agent 远端接口,对外提供 Agent 数据访问

总体而言,Client 模块借助“接口 + 工厂 + 实现缓存”的三层结构,把运行时与 EDDI 后端服务的耦合面收敛到 IRestInterfaceFactory 这一个扩展点上,使得后续要替换底层通信框架或增加拦截器(例如 v6.2.0 的 HITL 审批、AUDIT 链路、熔断/超时策略)时,只需要在工厂层做改造,而不必改动所有上层 Client 库。资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/factory/IRestInterfaceFactory.java:1-1、资料来源:src/main/java/ai/labs/eddi/engine/runtime/client/factory/RestInterfaceFactory.java:1-1

来源:https://github.com/labsai/EDDI / 项目说明书

Agents 模块

Agents 模块是 EDDI 平台中负责管理"声明式代理 (Declarative Agent)"配置、能力注册与签名验证的核心子模块。它使机器人可被声明为以目标为导向、可调用工具并具备多轮推理能力的智能体,是 v6.x 中多代理编排、TASKFORCE 协作讨论风格以及 Human-in-the-Loop (HITL) 框架的基础设施支撑。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 Agent Store(代理存储)

继续阅读本节完整说明和来源证据。

章节 Capability Registry(能力注册表)

继续阅读本节完整说明和来源证据。

模块概览

Agents 模块是 EDDI 平台中负责管理"声明式代理 (Declarative Agent)"配置、能力注册与签名验证的核心子模块。它使机器人可被声明为以目标为导向、可调用工具并具备多轮推理能力的智能体,是 v6.x 中多代理编排、TASK_FORCE 协作讨论风格以及 Human-in-the-Loop (HITL) 框架的基础设施支撑。

模块主要职责:

  • 持久化代理配置 (Agent Store)
  • 维护代理可调用的能力/工具清单 (Capability Registry)
  • 为代理配置提供完整性签名 (Agent Signing Service)
  • 通过 REST 接口对外暴露代理与能力注册的管理能力

资料来源:src/main/java/ai/labs/eddi/configs/agents/IAgentStore.java:1-30 资料来源:src/main/java/ai/labs/eddi/configs/agents/IRestAgentStore.java:1-30

核心组件

Agent Store(代理存储)

IAgentStore 定义了代理配置的基本 CRUD 接口,用于在底层 MongoDB 中存取代理的声明式定义;IRestAgentStore 在该接口之上构建了 REST 资源端点,供 Admin UI 与外部系统调用。典型操作包括按 ID/名称检索代理、列出可用代理、创建/更新与删除代理定义。

资料来源:src/main/java/ai/labs/eddi/configs/agents/IRestAgentStore.java:1-50 资料来源:src/main/java/ai/labs/eddi/configs/agents/IAgentStore.java:1-40

Capability Registry(能力注册表)

CapabilityRegistryServiceIRestCapabilityRegistry 共同构成能力注册子系统。能力 (Capability) 代表代理可调用的工具或函数,例如 HTTP 请求、数据库查询、RAG 检索、Slack 消息等。该注册表允许运维人员集中登记可用能力,并在代理配置中按需引用。

资料来源:src/main/java/ai/labs/eddi/configs/agents/CapabilityRegistryService.java:1-40 资料来源:src/main/java/ai/labs/eddi/configs/agents/IRestCapabilityRegistry.java:1-40

安全签名机制

为保证代理配置在传输与持久化过程中不被篡改,模块引入了非对称签名机制:

  • AgentPublicKey:封装代理公钥信息,用于在运行时验证代理配置的签名合法性。
  • AgentSigningService:负责对代理配置进行签名/验签,确保只有经授权的代理可以被运行时加载与执行。
flowchart LR
    A[Admin UI / API] --> B[IRestAgentStore]
    B --> C[IAgentStore]
    B --> D[AgentSigningService]
    D --> E[AgentPublicKey]
    C --> F[(MongoDB)]
    G[Runtime Engine] --> H[AgentSigningService.verify]
    H --> E

资料来源:src/main/java/ai/labs/eddi/configs/agents/AgentSigningService.java:1-50 资料来源:src/main/java/ai/labs/eddi/configs/agents/crypto/AgentPublicKey.java:1-40

与其他模块的协同

Agents 模块并非孤立存在,与之紧密协作的子系统包括:

  • Runtime 引擎:会话启动时通过 AgentSigningService 校验签名并加载代理。
  • Tooling 系统(自 v5.6.0 引入):代理通过 Capability Registry 选择并调用工具。
  • TASK_FORCE 讨论风格(v6.1.2):允许代理在运行时创建子代理并委派任务。
  • HITL 框架(v6.2.0):在 turn-level 与 per-tool-call 两个粒度对代理行为进行人工审批。

社区反馈显示,EDDI 5.1.x 在 Kubernetes 中存在 CPU 高占用问题(Issue #390),常与多个长生命周期代理同时加载以及频繁的能力查询相关。建议通过提升代理缓存粒度、减少 Capability Registry 全表扫描来缓解负载。

资料来源:src/main/java/ai/labs/eddi/configs/agents/IRestAgentStore.java:1-80 资料来源:src/main/java/ai/labs/eddi/configs/agents/CapabilityRegistryService.java:1-60

资料来源:src/main/java/ai/labs/eddi/configs/agents/IAgentStore.java:1-30

Providers 模块

Providers 模块位于 EDDI NLP 扩展层 (modules/nlp/extensions/dictionaries/providers/) ,其核心职责是为不同的实体识别场景提供可插拔的词典数据源。在 EDDI 的对话式 AI 管线中,原始用户输入需要经过规范化、分词、词性标注、命名实体识别等步骤;Providers 模块为这些步骤提供"原子级"词条(即"小颗...

章节 相关页面

继续阅读本节完整说明和来源证据。

概述与职责

Providers 模块位于 EDDI NLP 扩展层 (modules/nlp/extensions/dictionaries/providers/) ,其核心职责是为不同的实体识别场景提供可插拔的词典数据源。在 EDDI 的对话式 AI 管线中,原始用户输入需要经过规范化、分词、词性标注、命名实体识别等步骤;Providers 模块为这些步骤提供"原子级"词条(即"小颗粒词"),使得正则/规则引擎或基于词典的 NER 阶段能够正确地识别数字、邮箱、序数、标点等结构化文本片段。

模块通过统一的 IDictionaryProvider 契约屏蔽了不同词典来源的差异,使上层调用方可以以一致的方式获取字典数据,降低了扩展成本。

资料来源:src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java:1-30

核心接口设计

IDictionaryProvider 是整个 Providers 模块的抽象根。其典型形态为 Java 接口,暴露供消费者获取字典条目、查询字典标识以及判定条目存在性的方法。常见方法签名包括:

  • String getId() —— 返回当前 provider 的唯一标识,便于在多 provider 场景下进行路由与日志追踪。
  • boolean contains(String value) —— 用于快速判断某字符串是否已被该 provider 收录。
  • Iterable<String> getWords() —— 惰性返回字典中的全部词条,避免一次性加载导致内存压力。

该接口的存在让六类具体 provider 实现可以互换使用,符合"开闭原则"。

资料来源:src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java:10-40

内置 Provider 实现

模块下默认提供多种与正则/数字/结构化文本识别直接相关的字典生产者,每一类都对应实际对话中最常见的实体类型:

Provider 类用途典型识别内容
IntegerDictionaryProvider整数识别"一"、"十二"、"123" 等
DecimalDictionaryProvider小数识别"3.14"、"零点五" 等
OrdinalNumbersDictionaryProvider序数词识别"第一"、"第二十" 等
EmailDictionaryProvider邮箱识别"[email protected]" 等
PunctuationDictionaryProvider标点符号识别",。?!;:" 等

这些 Provider 通常在启动时由 CDI / Quarkus 容器装配,并通过配置或反射注册到 NLP 字典消费组件中。它们既可以作为面向字面量的词典(如标点),也可以作为面向正则锚点的前缀/后缀词典(如邮箱)。在 v6.0+ 重构后,模块进一步与现代化的 langchain4j 1.13.0 栈协同,保持低耦合。

资料来源:

调用流程与运行时集成

Providers 模块在 NLP 流水线中通常由 正则词典正则化阶段触发,整体数据流如下:

flowchart LR
    A[用户输入原文] --> B[Unicode / 简繁体规范化]
    B --> C[Regex Normalizer]
    C --> D{IDictionaryProvider 集合}
    D --> E[Integer Dictionary]
    D --> F[Decimal Dictionary]
    D --> G[Ordinal Dictionary]
    D --> H[Email Dictionary]
    D --> I[Punctuation Dictionary]
    E & F & G & H & I --> J[字典化后的 Token 序列]
    J --> K[下游 NER / 规则引擎]

字典消费组件在初始化时遍历已注册的 IDictionaryProvider 列表,调用 getWords() 构造内存索引;当文本经过正则归一化时,会通过 contains() 检查命中并将相应片段替换为占位符或打上标签。这种设计使得新增一种实体类型(如电话号码、URL)只需新增一个 Provider 类,无需修改既有流水线。

资料来源:src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java:20-50

扩展指南与社区关注点

新增自定义 Provider 仅需实现 IDictionaryProvider 接口,并在 Quarkus 的 bean 发现机制下提供对应的 @ApplicationScoped 标注。常见注意事项包括:

  1. 保持 getId() 稳定:该 ID 可能被用于缓存键,需要保证全局唯一。
  2. 控制 getWords() 的惰性策略:词典规模较大时(例如全量人名),建议返回 Iterable 以流式加载,避免在启动阶段占用过多堆内存。
  3. 避免与上游 LangChain 配置冲突:参考 v5.5.1 恢复的 * 匹配运算符及更新的 LangChain 配置,自定义 provider 的 key 不要与系统保留 token 冲突。

在与 v6 之后版本(6.0.0 GA 与 6.2.0 HITL)集成时,Providers 模块自身不承担人类审批 (Human-in-the-Loop) 责任——它只负责为识别阶段提供底层数据;HITL 的两道审批门(turn-level 与 per-tool-call)位于更高的 Agent 编排层。

资料来源:src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java:5-15

小结

Providers 模块通过统一的 IDictionaryProvider 契约,将数字、序数、邮箱、标点等结构化文本的字典化逻辑封装为可独立装配、可独立扩展的组件。它在 EDDI NLP 流水线中扮演"数据源"角色,是规则型 NER 与正则归一化的基础。结合 v6.x 的安全加固与测试覆盖率提升(OpenSSF Scorecard Gold),该模块的接口稳定性与可扩展性已成为 EDDI 多语言对话能力的重要支撑。

资料来源:src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java:1-30

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

high 能力证据存在缺口

缺口未补前,Doramagic 不能把该能力当作可靠推荐卖点。

medium 依赖 Docker 环境

非工程用户可能没有 Docker,启动成本明显增加。

medium 安装命令尚未沙箱验证

命令可能缺步骤、过期或依赖本地环境,不能直接作为用户承诺。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

Pitfall Log / 踩坑日志

项目:labsai/EDDI

摘要:发现 11 个潜在踩坑项,其中 1 个为 high/blocking;最高优先级:能力坑 - 能力证据存在缺口。

1. 能力坑 · 能力证据存在缺口

  • 严重度:high
  • 证据强度:source_linked
  • 发现:Sandbox install result is missing.
  • 对用户的影响:缺口未补前,Doramagic 不能把该能力当作可靠推荐卖点。
  • 证据:evidence.evidence_gaps | https://github.com/labsai/EDDI | Sandbox install result is missing.

2. 安装坑 · 依赖 Docker 环境

  • 严重度:medium
  • 证据强度:runtime_trace
  • 发现:安装/运行入口包含 Docker 命令:docker compose up
  • 对用户的影响:非工程用户可能没有 Docker,启动成本明显增加。
  • 复现命令:docker compose up
  • 证据:identity.distribution | https://github.com/labsai/EDDI | docker compose up

3. 安装坑 · 安装命令尚未沙箱验证

  • 严重度:medium
  • 证据强度:runtime_trace
  • 发现:当前 install_status=documented,还只是文档/元数据线索。
  • 对用户的影响:命令可能缺步骤、过期或依赖本地环境,不能直接作为用户承诺。
  • 复现命令:docker compose up
  • 证据:downstream_validation.install_status | https://github.com/labsai/EDDI | install_status=documented; command=docker compose up

4. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 证据:capability.assumptions | https://github.com/labsai/EDDI | README/documentation is current enough for a first validation pass.

5. 运行坑 · Quick Start 尚未实际跑通

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:quickstart_status=not_attempted。
  • 对用户的影响:用户只能看到安装线索,不能确信 10 分钟内能形成最小可试路径。
  • 证据:downstream_validation.quickstart_status | https://github.com/labsai/EDDI | quickstart_status=not_attempted; sandbox_quickstart_status=missing

6. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 证据:evidence.maintainer_signals | https://github.com/labsai/EDDI | last_activity_observed missing
  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 证据:downstream_validation.risk_items | https://github.com/labsai/EDDI | no_demo; severity=medium

8. 安全/权限坑 · 存在安全注意事项

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:No sandbox install has been executed yet; downstream must verify before user use.
  • 对用户的影响:用户安装前需要知道权限边界和敏感操作。
  • 证据:risks.safety_notes | https://github.com/labsai/EDDI | No sandbox install has been executed yet; downstream must verify before user use.

9. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 证据:risks.scoring_risks | https://github.com/labsai/EDDI | no_demo; severity=medium

10. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 证据:evidence.maintainer_signals | https://github.com/labsai/EDDI | issue_or_pr_quality=unknown

11. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 证据:evidence.maintainer_signals | https://github.com/labsai/EDDI | release_recency=unknown

来源:Doramagic 发现、验证与编译记录