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

生成时间：2026-07-29 17:54:22 UTC

## 目录

- [项目概览](#page-overview)
- [Api 模块](#page-src-main-java-ai-labs-eddi-engine-api)
- [Runtime 模块](#page-src-main-java-ai-labs-eddi-engine-runtime)
- [Client 模块](#page-src-main-java-ai-labs-eddi-engine-runtime-client)
- [Agents 模块](#page-src-main-java-ai-labs-eddi-configs-agents)
- [Agents 模块](#page-src-main-java-ai-labs-eddi-engine-runtime-client-agents)
- [Providers 模块](#page-src-main-java-ai-labs-eddi-modules-nlp-extensions-dictionaries-providers)
- [Providers 模块](#page-src-main-java-ai-labs-eddi-modules-nlp-extensions-normalizers-providers)

<a id='page-overview'></a>

## 项目概览

### 相关页面

相关主题：[Api 模块](#page-src-main-java-ai-labs-eddi-engine-api)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/labsai/EDDI/blob/main/README.md)
- [pom.xml](https://github.com/labsai/EDDI/blob/main/pom.xml)
- [src/main/docker/Dockerfile](https://github.com/labsai/EDDI/blob/main/src/main/docker/Dockerfile)
- [.clusterfuzzlite/Dockerfile](https://github.com/labsai/EDDI/blob/main/.clusterfuzzlite/Dockerfile)
- [licenses/README.md](https://github.com/labsai/EDDI/blob/main/licenses/README.md)
- [CHANGELOG.md](https://github.com/labsai/EDDI/blob/main/CHANGELOG.md)
- [docs/architecture.md](https://github.com/labsai/EDDI/blob/main/docs/architecture.md)
- [src/main/resources/application.properties](https://github.com/labsai/EDDI/blob/main/src/main/resources/application.properties)
</details>

# 项目概览

## 项目定位与目标

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）与工具框架**：通过 `DeclarativeAgent` 与 `DeclarativeAgentTask` 将代理定义为目标驱动的规划执行体，支持工具自主调用。资料来源：[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]()

## 高层架构

```mermaid
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]()

---

<a id='page-src-main-java-ai-labs-eddi-engine-api'></a>

## Api 模块

### 相关页面

相关主题：[项目概览](#page-overview), [Runtime 模块](#page-src-main-java-ai-labs-eddi-engine-runtime)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/main/java/ai/labs/eddi/engine/api/IConversationService.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/api/IConversationService.java)
- [src/main/java/ai/labs/eddi/engine/api/IGroupConversationService.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/api/IGroupConversationService.java)
- [src/main/java/ai/labs/eddi/engine/api/ILogoutEndpoint.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/api/ILogoutEndpoint.java)
- [src/main/java/ai/labs/eddi/engine/api/IRestAgentAdministration.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/api/IRestAgentAdministration.java)
- [src/main/java/ai/labs/eddi/engine/api/IRestAgentEngine.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/api/IRestAgentEngine.java)
- [src/main/java/ai/labs/eddi/engine/api/IRestAgentEngineStreaming.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/api/IRestAgentEngineStreaming.java)

</details>

# Api 模块

## 概述与定位

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 模块按业务域划分为三类接口集合。

### 对话域接口

- `IConversationService`：声明单轮/多轮对话的创建、推送与查询端点，是 Bot 与用户之间"一问一答"通道的核心入口，常被 Channel Connector 直接复用。资料来源：[src/main/java/ai/labs/eddi/engine/api/IConversationService.java:32-80]()
- `IGroupConversationService`：扩展多智能体群聊场景，承载 Task Force（v6.1.2 引入的动态多代理协作）等编排模式下的子代理创建与协作会话。资料来源：[src/main/java/ai/labs/eddi/engine/api/IGroupConversationService.java:24-78]()

### 智能体域接口

- `IRestAgentAdministration`：负责 DeclarativeAgent 与 Tool 的全生命周期管理，包括导入、版本化与停用等运维操作。资料来源：[src/main/java/ai/labs/eddi/engine/api/IRestAgentAdministration.java:26-98]()
- `IRestAgentEngine`：以请求-响应模式调用智能体，承载目标驱动的计划、记忆读写与工具调用流程。资料来源：[src/main/java/ai/labs/eddi/engine/api/IRestAgentEngine.java:20-72]()
- `IRestAgentEngineStreaming`：在常规 Engine 之外提供基于 SSE 的流式端点，用于向前端实时推送工具调用进度、Human-in-the-Loop 审批请求与多模态附件上传/解析事件。资料来源：[src/main/java/ai/labs/eddi/engine/api/IRestAgentEngineStreaming.java:18-62]()

### 平台基础设施接口

- `ILogoutEndpoint`：声明登出端点，配合 EDDI 6.x 引入的 OpenSSF Scorecard Gold 级安全基线完成会话失效与令牌撤销。资料来源：[src/main/java/ai/labs/eddi/engine/api/ILogoutEndpoint.java:16-42]()

## 架构层级与请求流转

| 接口 | 主要 HTTP 动词 | 典型路径前缀 | 关联引擎/客户端 |
|------|---------------|--------------|---------------|
| `IConversationService` | POST / GET / DELETE | `/conversation` | Conversation Engine、Channel Connector |
| `IGroupConversationService` | POST / PUT | `/groupConversation` | Multi-Agent Orchestrator |
| `IRestAgentAdministration` | POST / GET / PUT / DELETE | `/agents` | Agent Store / Versioner |
| `IRestAgentEngine` | POST | `/agentEngine` | DeclarativeAgent Executor |
| `IRestAgentEngineStreaming` | POST (text/event-stream) | `/agentEngineStreaming` | Streaming Pipeline + HITL |
| `ILogoutEndpoint` | POST | `/logout` | Security 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-82]() 与 [src/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 级双网关分别扩展自 `IRestAgentEngine` 与 `IRestAgentEngineStreaming`，配合 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]()

---

<a id='page-src-main-java-ai-labs-eddi-engine-runtime'></a>

## Runtime 模块

### 相关页面

相关主题：[Api 模块](#page-src-main-java-ai-labs-eddi-engine-api), [Client 模块](#page-src-main-java-ai-labs-eddi-engine-runtime-client)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/main/java/ai/labs/eddi/engine/runtime/BaseRuntime.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/BaseRuntime.java)
- [src/main/java/ai/labs/eddi/engine/runtime/BoundedLogStore.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/BoundedLogStore.java)
- [src/main/java/ai/labs/eddi/engine/runtime/ConversationSetup.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/ConversationSetup.java)
- [src/main/java/ai/labs/eddi/engine/runtime/DatabaseLogs.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/DatabaseLogs.java)
- [src/main/java/ai/labs/eddi/engine/runtime/IAgent.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/IAgent.java)
- [src/main/java/ai/labs/eddi/engine/runtime/IAgentDeploymentManagement.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/IAgentDeploymentManagement.java)
</details>

# Runtime 模块

## 模块概述

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]()。

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

## 核心组件

### BaseRuntime

`BaseRuntime` 是所有 Runtime 实现（如 `BotManagement`、`BotFactory`）的基类，封装了公共依赖注入与生命周期方法。其内部通过 CDI 注入 `IBotFactory`、`IRestMatcher`、`IBot` 等协作对象，并在初始化阶段建立与持久化存储的连接 资料来源：[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-60]()。`IAgentDeploymentManagement` 则提供 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 模块对每一次对话执行都强制产出结构化日志，这套机制由两个组件协作完成：

- `BoundedLogStore`：内存中的有界日志队列，防止高并发下日志对象无限增长；满阈值后按 FIFO 淘汰最旧条目 资料来源：[src/main/java/ai/labs/eddi/engine/runtime/BoundedLogStore.java:20-70]()。
- `DatabaseLogs`：将 `BoundedLogStore` 中的批次日志异步刷写至持久化层（MongoDB），对外提供按 `conversationId` 查询的能力 资料来源：[src/main/java/ai/labs/eddi/engine/runtime/DatabaseLogs.java:30-110]()。

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

## 数据流与调用链路

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

```mermaid
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](https://github.com/labsai/EDDI/releases/tag/6.2.0)。

## 扩展与自定义

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

- **自定义 Step**：实现 `IStep` 接口并以 CDI `@Alternative` 注册，Runtime 的 Step 解析器会自动发现并串联 资料来源：[src/main/java/ai/labs/eddi/engine/runtime/BaseRuntime.java:100-150]()。
- **自定义 Bot 工厂**：继承 `BaseRuntime` 并覆盖 `createBotInstance()`，可注入领域特定的 Bot 装配逻辑 资料来源：[src/main/java/ai/labs/eddi/engine/runtime/BaseRuntime.java:80-110]()。
- **Agent 工具集**：在 Declarative Agent 配置中声明工具定义，由 `IAgentDeploymentManagement` 在部署阶段校验并落入运行包 资料来源：[src/main/java/ai/labs/eddi/engine/runtime/IAgentDeploymentManagement.java:40-80]()。

## 小结

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

---

<a id='page-src-main-java-ai-labs-eddi-engine-runtime-client'></a>

## Client 模块

### 相关页面

相关主题：[Runtime 模块](#page-src-main-java-ai-labs-eddi-engine-runtime), [Agents 模块](#page-src-main-java-ai-labs-eddi-configs-agents)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/main/java/ai/labs/eddi/engine/runtime/client/agents/AgentStoreClientLibrary.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/agents/AgentStoreClientLibrary.java)
- [src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java)
- [src/main/java/ai/labs/eddi/engine/runtime/client/configuration/IResourceClientLibrary.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/configuration/IResourceClientLibrary.java)
- [src/main/java/ai/labs/eddi/engine/runtime/client/configuration/ResourceClientLibrary.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/configuration/ResourceClientLibrary.java)
- [src/main/java/ai/labs/eddi/engine/runtime/client/factory/IRestInterfaceFactory.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/factory/IRestInterfaceFactory.java)
- [src/main/java/ai/labs/eddi/engine/runtime/client/factory/RestInterfaceFactory.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/factory/RestInterfaceFactory.java)
</details>

# Client 模块

## 模块定位与职责

`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` | 工厂实现（`@ApplicationScoped`） | `ConcurrentHashMap` 缓存 | 生成并缓存远端接口实现，避免重复反射 |
| `IResourceClientLibrary` | 资源客户端接口 | `IRestInterfaceFactory` | 抽象资源（规则/模板）加载方法 |
| `ResourceClientLibrary` | 资源客户端实现 | `IRestInterfaceFactory` | 缓存 `IResourceClient`，对外提供资源访问能力 |
| `IAgentStoreClientLibrary` | Agent 客户端接口 | `IRestInterfaceFactory` | 抽象 Agent 存储读取方法 |
| `AgentStoreClientLibrary` | Agent 客户端实现 | `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]()

---

<a id='page-src-main-java-ai-labs-eddi-configs-agents'></a>

## Agents 模块

### 相关页面

相关主题：[Client 模块](#page-src-main-java-ai-labs-eddi-engine-runtime-client), [Agents 模块](#page-src-main-java-ai-labs-eddi-engine-runtime-client-agents)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/main/java/ai/labs/eddi/configs/agents/AgentSigningService.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/configs/agents/AgentSigningService.java)
- [src/main/java/ai/labs/eddi/configs/agents/CapabilityRegistryService.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/configs/agents/CapabilityRegistryService.java)
- [src/main/java/ai/labs/eddi/configs/agents/IAgentStore.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/configs/agents/IAgentStore.java)
- [src/main/java/ai/labs/eddi/configs/agents/IRestAgentStore.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/configs/agents/IRestAgentStore.java)
- [src/main/java/ai/labs/eddi/configs/agents/IRestCapabilityRegistry.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/configs/agents/IRestCapabilityRegistry.java)
- [src/main/java/ai/labs/eddi/configs/agents/crypto/AgentPublicKey.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/configs/agents/crypto/AgentPublicKey.java)
</details>

# Agents 模块

## 模块概览

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（能力注册表）

`CapabilityRegistryService` 与 `IRestCapabilityRegistry` 共同构成能力注册子系统。能力 (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`：负责对代理配置进行签名/验签，确保只有经授权的代理可以被运行时加载与执行。

```mermaid
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]()

---

<a id='page-src-main-java-ai-labs-eddi-engine-runtime-client-agents'></a>

## Agents 模块

### 相关页面

相关主题：[Agents 模块](#page-src-main-java-ai-labs-eddi-configs-agents), [Providers 模块](#page-src-main-java-ai-labs-eddi-modules-nlp-extensions-dictionaries-providers)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/main/java/ai/labs/eddi/engine/runtime/client/agents/AgentStoreClientLibrary.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/agents/AgentStoreClientLibrary.java)
- [src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java)
- [src/main/java/ai/labs/eddi/engine/runtime/internal/agents/IAgent.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/internal/agents/IAgent.java)
- [src/main/java/ai/labs/eddi/engine/runtime/internal/agents/Agent.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/internal/agents/Agent.java)
- [src/main/java/ai/labs/eddi/engine/runtime/internal/agents/DeclarativeAgent.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/internal/agents/DeclarativeAgent.java)
- [src/main/java/ai/labs/eddi/engine/runtime/internal/agents/DeclarativeAgentTask.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/internal/agents/DeclarativeAgentTask.java)
- [src/main/java/ai/labs/eddi/engine/runtime/internal/agents/tools/ToolRegistry.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/engine/runtime/internal/agents/tools/ToolRegistry.java)
</details>

# Agents 模块

## 概述与定位

Agents 模块是 EDDI 平台用于构建目标驱动型自主对话体的核心运行时子系统，位于 `ai.labs.eddi.engine.runtime` 包下。它将传统聊天机器人升级为可规划、可调用工具、可协同的 AI 智能体，并通过 REST、Slack、MCP 等多种通道面与外部系统集成。该模块自 v5.6.0 起引入 DeclarativeAgent 框架，并于 v6.1.2 扩展为 TASK_FORCE 多代理编排，于 v6.2.0 加入 Human-in-the-Loop 审批门控，是 EDDI “AI 能力栈” 的中枢。

## 核心组件与 Agent 类型

| 层级 | 组件 | 角色 |
|------|------|------|
| 客户端 | `AgentStoreClientLibrary` / `IAgentStoreClientLibrary` | 与持久化 Agent Store 交互的客户端门面 |
| 抽象契约 | `IAgent` | 统一 Agent 行为接口 |
| 基础实现 | `Agent` | 封装对话循环、记忆读写与 LLM 调用骨架 |
| 声明式层 | `DeclarativeAgent`、`DeclarativeAgentTask` | 配置驱动的目标驱动智能体及其任务单元 |
| 工具层 | `ToolRegistry`、`ITool` | 工具的可插拔注册与执行 |

`IAgentStoreClientLibrary` 将 Agent 的 CRUD 抽象为接口，`AgentStoreClientLibrary` 通过依赖注入获取远端 Agent Store 资源并映射为运行时对象，便于替换实现与单元测试。`资料来源：[src/main/java/ai/labs/eddi/engine/runtime/client/agents/IAgentStoreClientLibrary.java:1-40]()`、`资料来源：[src/main/java/ai/labs/eddi/engine/runtime/client/agents/AgentStoreClientLibrary.java:1-80]()`

`IAgent` 给出 Agent 的统一行为契约；`Agent` 提供默认实现，承担 LLM 调度、消息总线、记忆读写等通用职责。`DeclarativeAgent` 接收声明式 `goal + tools + policy` 配置即可上线，无需编码即可编排目标驱动智能体；`DeclarativeAgentTask` 把执行拆分为可被规划器动态调度的任务单元，支持子 Agent 在运行时实例化。`资料来源：[src/main/java/ai/labs/eddi/engine/runtime/internal/agents/IAgent.java:1-60]()`、`资料来源：[src/main/java/ai/labs/eddi/engine/runtime/internal/agents/Agent.java:1-80]()`、`资料来源：[src/main/java/ai/labs/eddi/engine/runtime/internal/agents/DeclarativeAgent.java:1-120]()`、`资料来源：[src/main/java/ai/labs/eddi/engine/runtime/internal/agents/DeclarativeAgentTask.java:1-100]()`

## 工具调用与人机协同（HITL）

`ToolRegistry` 集中管理所有可被 Agent 调用的工具。注册时按注解或配置生成 LLM 可理解的 JSON Schema，并由 LLM 在每轮中按需选择。v6.2.0 引入的两级 HITL 审批门覆盖了工具调用路径：

- **turn-level**：每个对话 turn 开始前需人工批准整体执行；
- **per-tool-call**：每次具体工具调用前需独立审批。

审批面覆盖 Slack、REST 与 MCP，并具备崩溃恢复、超时策略与完整审计日志，便于事后追溯与合规审计。`资料来源：[src/main/java/ai/labs/eddi/engine/runtime/internal/agents/tools/ToolRegistry.java:1-140]()`

## 运行时流程与部署注意事项

```mermaid
sequenceDiagram
    participant U as 用户/通道
    participant R as Agent 运行时
    participant L as LLM (langchain4j)
    participant T as ToolRegistry
    participant H as HITL 审批门
    U->>R: 触发 turn
    R->>H: turn-level 审批
    H-->>R: 通过/拒绝
    R->>L: 注入 goal + 记忆 + 工具 schema
    L-->>R: 返回计划或工具调用请求
    R->>H: per-tool-call 审批
    H-->>R: 通过/拒绝
    R->>T: 选择并执行工具
    T-->>R: 返回结果
    R->>L: 汇总并生成最终回复
    R-->>U: 输出
```

在生产部署方面，社区 Issue #390 报告了 EDDI 5.1.1 在 Kubernetes 中出现 CPU 高占用导致 Pod 被驱逐的现象，多与 Agent 长连接下的 LLM 轮询及记忆检索相关。启用 Agents 模块时建议：

- 合理配置 LLM 调用超时与并发上限；
- 启用 HITL 审批以限制失控工具调用；
- 监控 `ToolRegistry` 中高频工具的执行时长；
- 在 v6.0+ 上使用 Java 25 + Quarkus 3.34 LTS 与 MongoDB/PostgreSQL 双存储后端，并结合 OpenSSF Scorecard Gold 安全基线进行巡检。

---

<a id='page-src-main-java-ai-labs-eddi-modules-nlp-extensions-dictionaries-providers'></a>

## Providers 模块

### 相关页面

相关主题：[Agents 模块](#page-src-main-java-ai-labs-eddi-engine-runtime-client-agents), [Providers 模块](#page-src-main-java-ai-labs-eddi-modules-nlp-extensions-normalizers-providers)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- 资料来源： [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/DecimalDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/DecimalDictionaryProvider.java)
- 资料来源： [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/EmailDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/EmailDictionaryProvider.java)
- 资料来源： [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java)
- 资料来源： [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IntegerDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IntegerDictionaryProvider.java)
- 资料来源： [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/OrdinalNumbersDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/OrdinalNumbersDictionaryProvider.java)
- 资料来源： [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/PunctuationDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/PunctuationDictionaryProvider.java)
</details>

文件</summary>

以下源码文件用于生成本页说明：

- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/DecimalDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/DecimalDictionaryProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/EmailDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/EmailDictionaryProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IDictionaryProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IntegerDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IntegerDictionaryProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/OrdinalNumbersDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/OrdinalNumbersDictionaryProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/PunctuationDictionaryProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/PunctuationDictionaryProvider.java)
</details>

# 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` | 邮箱识别 | "user@example.com" 等 |
| `PunctuationDictionaryProvider` | 标点符号识别 | "，。？！；：" 等 |

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

资料来源：
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/IntegerDictionaryProvider.java:1-25]()
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/DecimalDictionaryProvider.java:1-25]()
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/OrdinalNumbersDictionaryProvider.java:1-25]()
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/EmailDictionaryProvider.java:1-25]()
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/dictionaries/providers/PunctuationDictionaryProvider.java:1-25]()

## 调用流程与运行时集成

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

```mermaid
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 多语言对话能力的重要支撑。

---

<a id='page-src-main-java-ai-labs-eddi-modules-nlp-extensions-normalizers-providers'></a>

## Providers 模块

### 相关页面

相关主题：[Providers 模块](#page-src-main-java-ai-labs-eddi-modules-nlp-extensions-dictionaries-providers)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/ContractedWordNormalizerProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/ContractedWordNormalizerProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/ConvertSpecialCharacterNormalizerProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/ConvertSpecialCharacterNormalizerProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/INormalizerProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/INormalizerProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/PunctuationNormalizerProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/PunctuationNormalizerProvider.java)
- [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/RemoveUndefinedCharacterNormalizerProvider.java](https://github.com/labsai/EDDI/blob/main/src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/RemoveUndefinedCharacterNormalizerProvider.java)
</details>

# Providers 模块

## 模块定位与作用

Providers 模块是 EDDI 平台中负责"按需创建、配置并交付运行时组件"的工厂层。它把"创建哪种实现、读取哪些配置、是否缓存单例"这些横切关注点从 NLP、LLM、Channel 等业务管线中剥离，使平台各子系统都能以可插拔方式扩展。在 NLP 子系统中，Providers 集中于 `ai.labs.eddi.modules.nlp.extensions.normalizers.providers` 包，覆盖文本规范化管线所需的若干步骤。资料来源：[src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/INormalizerProvider.java:1-30]()

## 接口契约：`INormalizerProvider`

`INormalizerProvider` 定义了所有 Normalizer Provider 的统一契约。实现类需要提供组件类型标识（`provides()`/`type()`），声明运行时依赖，并通过 `IResource` 接收 Botfather 下发的配置。Provider 实例本身由 Quarkus CDI（Arc）容器管理，生命周期默认为 `@ApplicationScoped`，因此无需 Provider 显式释放底层 Normalizer 资源。资料来源：[src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/INormalizerProvider.java:1-50]()

## 内置 Normalizer Provider

EDDI 内置四个 Normalizer Provider，对应文本预处理中常见的清理动作：

| Provider 类名 | 核心作用 | 典型场景 |
|---|---|---|
| `ContractedWordNormalizerProvider` | 还原英文缩写（如 *I'm* → *I am*） | 英文对话输入预处理 |
| `ConvertSpecialCharacterNormalizerProvider` | 转换全角/特殊符号为标准形式 | Slack、REST 富文本输入 |
| `PunctuationNormalizerProvider` | 统一中英文标点形态 | 跨语种 Bot 链路 |
| `RemoveUndefinedCharacterNormalizerProvider` | 剔除不可识别或不可打印字符 | OCR、ASR 转写后的脏数据 |

资料来源：[src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/ContractedWordNormalizerProvider.java:1-40]() · [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/ConvertSpecialCharacterNormalizerProvider.java:1-40]() · [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/PunctuationNormalizerProvider.java:1-40]() · [src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/RemoveUndefinedCharacterNormalizerProvider.java:1-40]()

## 注册、发现与注入流程

EDDI 借助 CDI 在启动时扫描 `providers` 子包，自动注册所有 `@ApplicationScoped` 的 Provider。运行时由 `ExtensionManager` 根据 Botfather 配置中的 type 字段查找匹配 Provider，按依赖拓扑排序后实例化对应 Normalizer 并注入 NLP Pipeline：

```mermaid
graph LR
  A[Botfather 配置] --> B[ExtensionManager]
  B --> C{查找匹配 type 的 Provider}
  C -->|命中| D[INormalizerProvider]
  D --> E[create 配置化 Normalizer]
  E --> F[注入 NLP Pipeline]
```

由于 Provider 由 CDI 单例化，热路径上只创建一次 Normalizer 实例，因此大量并发请求下不会出现重复构造开销。资料来源：[src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/INormalizerProvider.java:1-50]()

## 自定义 Provider 实践

新增 Normalizer Provider 的最小步骤：

1. 在 `modules/nlp/extensions/normalizers/providers/` 下新建类并实现 `INormalizerProvider`；
2. 通过 `@ApplicationScoped` 或等效 CDI 注解注册到容器；
3. 在 `provides()` 中返回与其他 Normalizer 不同的 type，避免冲突；
4. 通过 `IResource` 读取配置，完成 `Normalizer` 构造。

资料来源：[src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/PunctuationNormalizerProvider.java:1-60]()

## 模式的可推广性

Provider 工厂模式不仅服务于 Normalizer，同样贯穿 LLM Provider（Cascade 多模型选择，6.2.0 引入企业级改造）、Vector Store Provider（ChromaDB、MongoDB、PostgreSQL，6.1.0 引入 ChromaDB 支持）、Channel Provider（Slack、REST、MCP，6.0.1 起逐步原生化）以及 Memory、Database Provider。Normalizer Provider 是该模式在 NLP 层最直观的实例，可作为理解其他子系统 Provider 的参考。

## 社区关联

社区 Issue #390 报告 EDDI 5.1.1 在 Kubernetes 部署下出现 CPU 高占用与 Pod 重启。该版本未启用 v6 系列的 Provider 懒加载与 `@Startup` 精细化控制，热点路径上若一次性装配大量 Provider 容易引发瞬时 CPU 峰值。升级至 v6 后，`INormalizerProvider` 与同级 Provider 的初始化时机更可控，是缓解该类问题的一环。资料来源：[src/main/java/ai/labs/eddi/modules/nlp/extensions/normalizers/providers/INormalizerProvider.java:1-50]()

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：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

<!-- canonical_name: labsai/EDDI; human_manual_source: deepwiki_human_wiki -->
