docs(design): 补全中文设计文档体系
This commit is contained in:
259
docs/设计文档/模块设计/6.智能核心模块详细设计.md
Normal file
259
docs/设计文档/模块设计/6.智能核心模块详细设计.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# 智能核心模块详细设计
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
Agent Core 提供独立于 Django View 的智能编排能力。它消费场景配置,执行 RAG、工具、模型调用和结构化解析,最终返回统一 AgentResult。
|
||||
|
||||
## 2. 职责边界
|
||||
|
||||
负责:
|
||||
|
||||
- Agent 编排。
|
||||
- 场景配置对象消费。
|
||||
- RAG 入库和检索。
|
||||
- 工具注册与执行。
|
||||
- LLM Provider 与 Embedding Provider。
|
||||
- 结构化输出解析。
|
||||
- AgentResult 定义。
|
||||
|
||||
不负责:
|
||||
|
||||
- 不渲染页面。
|
||||
- 不处理 Django 表单。
|
||||
- 不保存 Django Model。
|
||||
- 不管理登录权限。
|
||||
|
||||
## 3. 子模块划分
|
||||
|
||||
```text
|
||||
agent_core/
|
||||
orchestrator.py
|
||||
scenario_loader.py
|
||||
llm_provider.py
|
||||
tool_registry.py
|
||||
structured_output.py
|
||||
rag/
|
||||
ingest.py
|
||||
retriever.py
|
||||
tools/
|
||||
builtin_tools.py
|
||||
schemas/
|
||||
outputs.py
|
||||
```
|
||||
|
||||
`scenario_loader.py` 可作为非 Django 环境下加载配置的工具;Django 场景展示仍由 `apps.scenarios` 负责。
|
||||
|
||||
## 4. Orchestrator 设计
|
||||
|
||||
入口:
|
||||
|
||||
```python
|
||||
def run_agent(scenario_config, user_input: str, options: dict | None = None) -> AgentResult:
|
||||
"""执行一次 Agent 编排,options 可包含 document_ids 等运行期约束。"""
|
||||
```
|
||||
|
||||
流程:
|
||||
|
||||
1. 记录开始时间。
|
||||
2. 根据 `rag.enabled`、`scenario_id` 和可选 `document_ids` 检索引用。
|
||||
3. 根据 `tools` 执行或准备工具结果。
|
||||
4. 构造 messages。
|
||||
5. 调用 LLM Provider。
|
||||
6. 解析结构化输出。
|
||||
7. 计算耗时。
|
||||
8. 返回 `AgentResult(status="success")`。
|
||||
9. 捕获可恢复异常并返回 `status="failed"`。
|
||||
|
||||
V1 在缺少 LLM 或 Embedding 配置时必须返回清晰失败结果。测试代码可以使用 mock provider,但 V1 验收链路必须通过真实 OpenAI 兼容 LLM、Embedding 和 Chroma。
|
||||
|
||||
## 5. Scenario Loader 设计
|
||||
|
||||
Agent Core 的 Scenario Loader 用于脚本、测试或后续独立服务场景。它不依赖 Django View,可以复用 Scenarios 模块的字段规范。
|
||||
|
||||
接口:
|
||||
|
||||
```python
|
||||
load_scenario(path: str) -> dict
|
||||
load_scenarios(directory: str) -> list[dict]
|
||||
```
|
||||
|
||||
## 6. RAG 设计
|
||||
|
||||
入库接口:
|
||||
|
||||
```python
|
||||
def ingest_document(
|
||||
document_id: int,
|
||||
scenario_id: str,
|
||||
source_file: str,
|
||||
text: str,
|
||||
collection: str,
|
||||
) -> IngestResult:
|
||||
"""切分文档、生成 embedding,并写入 Chroma。重新入库时覆盖同一 document_id 的旧 chunk。"""
|
||||
```
|
||||
|
||||
检索接口:
|
||||
|
||||
```python
|
||||
def retrieve(
|
||||
scenario_id: str,
|
||||
query: str,
|
||||
collection: str,
|
||||
top_k: int = 5,
|
||||
document_ids: list[int] | None = None,
|
||||
) -> list[ReferenceChunk]:
|
||||
"""按场景和可选文档范围执行向量检索,返回可审计引用片段。"""
|
||||
```
|
||||
|
||||
切分策略:
|
||||
|
||||
- 默认 chunk size 800 到 1000 字。
|
||||
- overlap 100 到 150 字。
|
||||
- metadata 包含 `scenario_id`、`document_id`、`source_file`、`chunk_id`。
|
||||
|
||||
RAG 入库和检索必须使用 Embedding Provider 与 Chroma。单元测试桩或开发阶段临时验证方案不属于 V1 验收设计。
|
||||
|
||||
## 7. Tool Registry 设计
|
||||
|
||||
工具注册:
|
||||
|
||||
```python
|
||||
registry.register("calculate_rate", calculate_rate)
|
||||
registry.get("calculate_rate")
|
||||
registry.run("calculate_rate", **kwargs)
|
||||
```
|
||||
|
||||
工具结果统一:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool_name": "calculate_rate",
|
||||
"success": true,
|
||||
"arguments": {},
|
||||
"result": {},
|
||||
"error": ""
|
||||
}
|
||||
```
|
||||
|
||||
内置工具:
|
||||
|
||||
- `calculate_rate`
|
||||
- `query_demo_records`
|
||||
- `check_required_fields`
|
||||
- `generate_action_items`
|
||||
|
||||
工具函数不得直接读取 API Key 或执行无审计的外部副作用。
|
||||
|
||||
## 8. LLM Provider 设计
|
||||
|
||||
接口:
|
||||
|
||||
```python
|
||||
class LLMProvider:
|
||||
def generate(self, messages: list[dict], response_format: dict | None = None) -> LLMResponse:
|
||||
"""调用 OpenAI 兼容 Chat Completions 接口并返回统一响应对象。"""
|
||||
```
|
||||
|
||||
配置来源:
|
||||
|
||||
- `LLM_API_KEY`
|
||||
- `LLM_BASE_URL`
|
||||
- `LLM_MODEL`
|
||||
|
||||
Provider 对外隐藏供应商差异,Orchestrator 只处理 `LLMResponse.content`、`LLMResponse.model_name` 和错误信息。供应商可自主选择 OpenAI、硅基流动等 OpenAI 兼容服务。
|
||||
|
||||
Embedding Provider 接口:
|
||||
|
||||
```python
|
||||
class EmbeddingProvider:
|
||||
def embed_texts(self, texts: list[str]) -> list[list[float]]:
|
||||
"""调用 OpenAI 兼容 Embeddings 接口,返回与输入文本一一对应的向量。"""
|
||||
```
|
||||
|
||||
配置来源:
|
||||
|
||||
- `EMBEDDING_API_KEY`
|
||||
- `EMBEDDING_BASE_URL`
|
||||
- `EMBEDDING_MODEL`
|
||||
|
||||
当 `EMBEDDING_API_KEY` 或 `EMBEDDING_BASE_URL` 为空时,可以复用 `LLM_API_KEY` 和 `LLM_BASE_URL`。
|
||||
|
||||
## 9. Structured Output 设计
|
||||
|
||||
接口:
|
||||
|
||||
```python
|
||||
def parse_structured_output(raw_output: str, output_type: str) -> ParseResult:
|
||||
"""优先解析 JSON,并根据输出类型返回结构化结果或解析错误。"""
|
||||
```
|
||||
|
||||
策略:
|
||||
|
||||
- 优先解析 JSON。
|
||||
- 根据 `output_type` 做字段补齐或轻校验。
|
||||
- 失败时返回 `success=False`,保留 `raw_output`。
|
||||
- 不因结构化解析失败导致整个 Agent 流程崩溃。
|
||||
|
||||
## 10. AgentResult 设计
|
||||
|
||||
建议 dataclass:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class AgentResult:
|
||||
answer: str
|
||||
structured_output: dict
|
||||
references: list
|
||||
tool_calls: list
|
||||
raw_output: str
|
||||
model_name: str
|
||||
latency_ms: int
|
||||
status: str
|
||||
error: str = ""
|
||||
```
|
||||
|
||||
所有字段必须有默认值或构造时明确传入,保证 Audit 模块写入稳定。
|
||||
|
||||
## 11. Adapter 扩展设计
|
||||
|
||||
统一接口:
|
||||
|
||||
```python
|
||||
class AgentEngine:
|
||||
def run_agent(self, scenario_config, user_input: str, options: dict | None = None) -> AgentResult:
|
||||
"""保持与顶层 run_agent 函数一致的输入输出合约。"""
|
||||
```
|
||||
|
||||
V1 实现:
|
||||
|
||||
- `LightweightOrchestrator`
|
||||
|
||||
后续扩展:
|
||||
|
||||
- `DifyAdapter`
|
||||
- `OpenAIAgentsAdapter`
|
||||
- `LangGraphAdapter`
|
||||
|
||||
Adapter 只能替换编排实现,不能改变 Django 层依赖的 AgentResult 合约。
|
||||
|
||||
## 12. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| RAG 检索失败 | 记录错误,允许继续或返回 failed |
|
||||
| 工具不存在 | 记录失败工具调用 |
|
||||
| 工具执行异常 | 捕获并返回失败工具结果 |
|
||||
| LLM 配置缺失 | 返回 failed AgentResult |
|
||||
| LLM 调用失败 | 返回 failed AgentResult |
|
||||
| JSON 解析失败 | 返回 success 但带解析错误,展示 raw output |
|
||||
|
||||
## 13. 验收标准
|
||||
|
||||
- Chat 可以调用 `run_agent()`。
|
||||
- 返回对象字段稳定完整。
|
||||
- RAG 按 `scenario_id` 隔离。
|
||||
- RAG 支持按 `document_ids` 限定本次对话的文档范围。
|
||||
- 工具调用结果格式统一。
|
||||
- LLM 与 Embedding 配置从环境变量读取。
|
||||
- 结构化解析失败不导致页面崩溃。
|
||||
- Agent Core 不依赖 Django View。
|
||||
Reference in New Issue
Block a user