# 智能核心模块详细设计 ## 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。