Files
DEMO-AGENT/docs/设计文档/模块设计/6.智能核心模块详细设计.md

260 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 智能核心模块详细设计
## 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。