chore(master): 清理V2合并后的旧版遗留文件

This commit is contained in:
2026-06-11 00:09:54 +08:00
parent 64d09ec30f
commit ccd6e8ef4d
89 changed files with 0 additions and 7318 deletions

View File

@@ -1,343 +0,0 @@
# V1 Django Baseline Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build the smallest runnable Django baseline that satisfies the current Chinese requirements and design documents.
**Architecture:** Use a Django monolith with four apps (`scenarios`, `documents`, `chat`, `audit`) plus an independent `agent_core` package. The first implementation returns deterministic mock Agent results so the UI, audit, documents and module boundaries can be verified before real RAG/LLM integration.
**Tech Stack:** Python 3.13, Django 5.x, PyYAML, pytest, pytest-django, SQLite, Docker Compose.
---
## File Structure
- Create `requirements.txt`: runtime and test dependencies.
- Create `manage.py`, `config/settings.py`, `config/urls.py`, `config/wsgi.py`, `config/asgi.py`: Django project shell.
- Create `apps/scenarios/`: YAML scenario loading, homepage, tests.
- Create `apps/documents/`: upload model, upload/list/index views, text extraction, tests.
- Create `apps/chat/`: message form, chat view, Agent Core call, audit write, tests.
- Create `apps/audit/`: audit model, service, list/detail views, tests.
- Create `agent_core/`: dataclasses, orchestrator, mock RAG ingest/retrieve, tool registry, structured output parser.
- Create `configs/*.yaml`: five required scenarios.
- Create `templates/`: minimal Django Templates for pages.
- Create `Dockerfile`, `docker-compose.yml`, `.env.example`: one-command startup.
## Task 1: Dependencies and Django Project Shell
**Files:**
- Create: `requirements.txt`
- Create: `manage.py`
- Create: `config/__init__.py`
- Create: `config/settings.py`
- Create: `config/urls.py`
- Create: `config/wsgi.py`
- Create: `config/asgi.py`
- Test: `pytest.ini`
- [ ] **Step 1: Write failing configuration test**
Create `tests/test_project_configuration.py`:
```python
from django.conf import settings
from django.urls import reverse
def test_core_settings_expose_documented_paths():
assert settings.SCENARIO_CONFIG_DIR.name == "configs"
assert settings.CHROMA_PATH.name == "chroma"
assert settings.MEDIA_ROOT.name == "uploads"
def test_home_url_is_registered(client):
response = client.get(reverse("scenarios:index"))
assert response.status_code == 200
```
- [ ] **Step 2: Run test to verify it fails**
Run: `pytest tests/test_project_configuration.py -q`
Expected: FAIL because Django project and apps do not exist.
- [ ] **Step 3: Implement minimal project shell**
Add dependencies and project files with settings for installed apps, templates, SQLite, media paths, and URL includes.
- [ ] **Step 4: Run test to verify progress**
Run: `pytest tests/test_project_configuration.py -q`
Expected: either PASS or fail only because `apps.scenarios` is not implemented yet.
## Task 2: Scenarios Module and Five YAML Configs
**Files:**
- Create: `apps/scenarios/services.py`
- Create: `apps/scenarios/views.py`
- Create: `apps/scenarios/urls.py`
- Create: `apps/scenarios/apps.py`
- Create: `configs/knowledge_qa.yaml`
- Create: `configs/document_review.yaml`
- Create: `configs/ticket_assistant.yaml`
- Create: `configs/quality_analysis.yaml`
- Create: `configs/risk_audit.yaml`
- Create: `templates/scenarios/index.html`
- Test: `tests/test_scenarios.py`
- [ ] **Step 1: Write failing scenario tests**
```python
from apps.scenarios.services import get_scenario, list_scenarios
def test_list_scenarios_loads_five_configs():
scenarios = list_scenarios()
assert [scenario["id"] for scenario in scenarios] == [
"knowledge_qa",
"document_review",
"ticket_assistant",
"quality_analysis",
"risk_audit",
]
def test_get_scenario_returns_full_agent_config():
scenario = get_scenario("quality_analysis")
assert scenario["agent"]["role"]
assert scenario["rag"]["enabled"] is True
assert scenario["output"]["type"] == "quality_report"
```
- [ ] **Step 2: Run test to verify it fails**
Run: `pytest tests/test_scenarios.py -q`
Expected: FAIL because services/configs are missing.
- [ ] **Step 3: Implement scenario loader and homepage**
Use `yaml.safe_load()`, validate required fields, and render scenario cards on `/`.
- [ ] **Step 4: Run tests**
Run: `pytest tests/test_scenarios.py tests/test_project_configuration.py -q`
Expected: PASS.
## Task 3: Agent Core Mock Orchestrator
**Files:**
- Create: `agent_core/results.py`
- Create: `agent_core/orchestrator.py`
- Create: `agent_core/structured_output.py`
- Create: `agent_core/tool_registry.py`
- Create: `agent_core/tools/builtin_tools.py`
- Create: `agent_core/rag/ingest.py`
- Create: `agent_core/rag/retriever.py`
- Test: `tests/test_agent_core.py`
- [ ] **Step 1: Write failing Agent Core tests**
```python
from agent_core.orchestrator import run_agent
def test_run_agent_returns_structured_mock_result():
scenario = {
"id": "knowledge_qa",
"name": "知识库问答助手",
"rag": {"enabled": True, "collection": "knowledge_qa", "top_k": 3},
"tools": ["generate_action_items"],
"output": {"type": "general_answer"},
}
result = run_agent(scenario, "如何处理异常?")
assert result.status == "success"
assert result.answer
assert result.structured_output["output_type"] == "general_answer"
assert result.tool_calls[0]["tool_name"] == "generate_action_items"
```
- [ ] **Step 2: Run test to verify it fails**
Run: `pytest tests/test_agent_core.py -q`
Expected: FAIL because `agent_core` is missing.
- [ ] **Step 3: Implement deterministic mock AgentResult**
Return stable answer, references, tool calls, model name `mock-model`, and latency.
- [ ] **Step 4: Run tests**
Run: `pytest tests/test_agent_core.py -q`
Expected: PASS.
## Task 4: Audit Module
**Files:**
- Create: `apps/audit/models.py`
- Create: `apps/audit/services.py`
- Create: `apps/audit/views.py`
- Create: `apps/audit/urls.py`
- Create: `apps/audit/admin.py`
- Create: `templates/audit/log_list.html`
- Create: `templates/audit/log_detail.html`
- Test: `tests/test_audit.py`
- [ ] **Step 1: Write failing audit tests**
```python
from apps.audit.models import AgentAuditLog
from apps.audit.services import create_audit_log
from agent_core.results import AgentResult
def test_create_audit_log_records_success_result(db):
result = AgentResult(answer="回答", structured_output={"x": 1}, status="success")
log = create_audit_log("knowledge_qa", "知识库问答助手", "问题", result)
assert AgentAuditLog.objects.count() == 1
assert log.final_answer == "回答"
assert log.structured_output == {"x": 1}
```
- [ ] **Step 2: Run test to verify it fails**
Run: `pytest tests/test_audit.py -q`
Expected: FAIL because audit app is missing.
- [ ] **Step 3: Implement model, service, admin, views**
Use JSONField defaults and avoid storing sensitive environment values.
- [ ] **Step 4: Run migrations and tests**
Run: `python manage.py makemigrations audit && pytest tests/test_audit.py -q`
Expected: PASS.
## Task 5: Documents Module
**Files:**
- Create: `apps/documents/models.py`
- Create: `apps/documents/services.py`
- Create: `apps/documents/forms.py`
- Create: `apps/documents/views.py`
- Create: `apps/documents/urls.py`
- Create: `apps/documents/admin.py`
- Create: `templates/documents/document_list.html`
- Create: `templates/documents/upload.html`
- Test: `tests/test_documents.py`
- [ ] **Step 1: Write failing document tests**
```python
from django.core.files.uploadedfile import SimpleUploadedFile
from django.urls import reverse
from apps.documents.models import UploadedDocument
def test_upload_txt_document_creates_uploaded_record(client, db):
file = SimpleUploadedFile("rules.txt", "hello".encode("utf-8"), content_type="text/plain")
response = client.post(reverse("documents:upload"), {"scenario_id": "knowledge_qa", "file": file})
assert response.status_code == 302
document = UploadedDocument.objects.get()
assert document.status == "uploaded"
assert document.file_type == "txt"
```
- [ ] **Step 2: Run test to verify it fails**
Run: `pytest tests/test_documents.py -q`
Expected: FAIL because documents app is missing.
- [ ] **Step 3: Implement upload/list/index flow**
Support `.txt` and `.md`; index action calls `agent_core.rag.ingest.ingest_document()` and updates status.
- [ ] **Step 4: Run migrations and tests**
Run: `python manage.py makemigrations documents && pytest tests/test_documents.py -q`
Expected: PASS.
## Task 6: Chat Module
**Files:**
- Create: `apps/chat/forms.py`
- Create: `apps/chat/views.py`
- Create: `apps/chat/urls.py`
- Create: `apps/chat/apps.py`
- Create: `templates/chat/index.html`
- Test: `tests/test_chat.py`
- [ ] **Step 1: Write failing chat tests**
```python
from django.urls import reverse
from apps.audit.models import AgentAuditLog
def test_chat_post_returns_agent_result_and_audit_log(client, db):
response = client.post(reverse("chat:index", args=["knowledge_qa"]), {"message": "如何处理异常?"})
assert response.status_code == 200
assert "mock-model" in response.content.decode("utf-8")
assert AgentAuditLog.objects.count() == 1
```
- [ ] **Step 2: Run test to verify it fails**
Run: `pytest tests/test_chat.py -q`
Expected: FAIL because chat app is missing.
- [ ] **Step 3: Implement chat form and view**
Validate message, call `get_scenario()`, `run_agent()`, then `create_audit_log()`.
- [ ] **Step 4: Run tests**
Run: `pytest tests/test_chat.py tests/test_audit.py tests/test_agent_core.py -q`
Expected: PASS.
## Task 7: Docker and Documentation Alignment
**Files:**
- Create: `.env.example`
- Create: `Dockerfile`
- Create: `docker-compose.yml`
- Modify: `README.md`
- Test: all tests and Django checks.
- [ ] **Step 1: Add deployment files**
Use a single web service, install `requirements.txt`, run migrations, and serve `0.0.0.0:8000`.
- [ ] **Step 2: Verify Django and tests**
Run:
```bash
python manage.py check
pytest -q
```
Expected: all checks pass.
- [ ] **Step 3: Verify docs path references**
Run:
```powershell
$patterns = @('docs/需求分析', 'docs/设计文档', 'V1总需求文档', '智能体总体设计')
Get-ChildItem -Recurse -File |
Where-Object {
$_.FullName -notlike '*\.git\*' -and
$_.FullName -notlike '*\.idea\*' -and
$_.FullName -notlike '*docs\superpowers\plans\2026-05-29-v1-django-baseline.md'
} |
Select-String -Pattern $patterns
```
Expected: no matches.
## Self-Review
- Spec coverage: The plan covers Chinese docs, five scenario configs, Django startup, homepage, chat, audit, documents, Agent Core, and Docker baseline.
- Placeholder scan: No implementation step relies on an undefined placeholder; mock LLM/RAG is intentionally scoped as the first runnable baseline.
- Type consistency: Tests use `AgentResult`, `run_agent`, `list_scenarios`, `get_scenario`, `UploadedDocument`, and `AgentAuditLog` consistently.

View File

@@ -1,71 +0,0 @@
# 模块详细设计文档索引
## 1. 设计文档说明
本目录存放 Universal Agent Demo Framework V1 的设计文档。需求文档回答“要做什么”,设计文档回答“怎么实现、边界在哪里、如何验证”。
文档命名统一使用中文编号,便于复试讲解和按顺序阅读。
## 2. 模块设计文档列表
| 顺序 | 文档 | 说明 |
|---|---|---|
| 0 | `0.设计文档索引.md` | 当前索引 |
| 1 | `1.智能体总体设计.md` | 智能核心总体链路、配置、输出和 Adapter |
| 2 | `2.功能流程设计.md` | 复试准备、演示、上传、入库、对话和审计流程 |
| 3 | `3.数据库设计.md` | Django 数据模型、字段、索引和初始化策略 |
| 4 | `4.页面与路由设计.md` | 页面结构、URL、跳转和异常状态 |
| 5 | `5.部署设计.md` | 本地、Docker、环境变量和持久化 |
模块详细设计位于 `模块设计/`
| 模块 | 文档 |
|---|---|
| 配置 | `模块设计/1.配置模块详细设计.md` |
| 场景 | `模块设计/2.场景模块详细设计.md` |
| 文档 | `模块设计/3.文档模块详细设计.md` |
| 对话 | `模块设计/4.对话模块详细设计.md` |
| 审计 | `模块设计/5.审计模块详细设计.md` |
| 智能核心 | `模块设计/6.智能核心模块详细设计.md` |
## 3. 模块依赖关系
```text
config
|-- apps.scenarios
|-- apps.documents
|-- apps.chat
|-- apps.audit
apps.scenarios
|-- reads configs/*.yaml
apps.documents
|-- depends on apps.scenarios
|-- calls agent_core.rag.ingest
apps.chat
|-- depends on apps.scenarios
|-- calls agent_core.orchestrator
|-- calls apps.audit.services
apps.audit
|-- stores AgentResult snapshots
agent_core
|-- consumes scenario config
|-- uses RAG, tools, LLM provider and structured output parser
```
## 4. 推荐阅读顺序
1. `docs/需求分析/1.V1总需求文档.md`
2. `docs/需求分析/2.模块需求索引.md`
3. `docs/设计文档/1.智能体总体设计.md`
4. `docs/设计文档/2.功能流程设计.md`
5. `docs/设计文档/3.数据库设计.md`
6. `docs/设计文档/4.页面与路由设计.md`
7. `docs/设计文档/5.部署设计.md`
8. `docs/设计文档/模块设计/*.md`
后续编码时,每个模块应先对照对应需求文档和详细设计,再实现模型、服务、视图和测试。

View File

@@ -1,211 +0,0 @@
# 智能体总体设计文档
## 1. 设计目标
Agent 设计的核心目标是支持未知复试题的快速适配。
系统不针对单一业务写死,而是通过场景配置、知识库、工具和输出模板组合出不同业务 Agent。
```text
业务 Agent = 场景配置 + 知识库 + 工具集 + 输出模板 + 审计日志 + 模型适配器
```
## 2. Agent 类型
V1 预置 5 类 Agent 场景:
| Agent ID | 名称 | 适用场景 |
|---|---|---|
| `knowledge_qa` | 知识库问答助手 | SOP、制度、客服知识库 |
| `document_review` | 文档审核助手 | 合同、制度、SOP、材料审核 |
| `ticket_assistant` | 工单处理助手 | 客服、售后、运维工单 |
| `quality_analysis` | 质量异常分析助手 | 生产、质检、缺陷分析 |
| `risk_audit` | 风险审核助手 | 财务、采购、报销、合同风险 |
## 3. Agent 执行链路
```text
用户输入
加载场景配置
判断是否启用 RAG
检索知识库片段
加载可用工具
构造 Prompt
调用大模型
解析工具调用和结构化输出
生成 AgentResult
写入审计日志
页面展示
```
## 4. 场景配置结构
场景配置使用 YAMLV1 以配置文件作为场景唯一事实来源,后台管理不作为场景配置入口。
```yaml
id: quality_analysis
name: 质量异常分析助手
description: 用于分析生产质量异常、检索 SOP、生成处理建议
agent:
role: 质量管理专家
goal: 根据用户问题、知识库和工具结果,输出可执行的质量分析报告
system_prompt: ""
instructions:
- 回答必须基于知识库或工具结果
- 不确定时必须说明缺失信息
- 涉及质量风险时给出风险等级
rag:
enabled: true
collection: quality_docs
top_k: 5
tools:
- query_demo_records
- calculate_rate
output:
type: quality_report
audit:
enabled: true
log_retrieval: true
log_tool_calls: true
```
## 5. Prompt 组成
Prompt 建议由以下部分组成:
```text
系统角色
任务目标
行为约束
输出格式要求
知识库检索内容
工具调用结果
用户问题
```
V1 不追求复杂 Prompt 框架,优先保证可读、可改、可解释。
## 6. RAG 策略
RAG 在 V1 中负责给 Agent 提供题目材料和业务知识。
入库流程:
```text
上传文件
抽取文本
文本切分
生成 embedding
写入 Chroma
```
检索流程:
```text
用户问题
按 scenario_id 和可选 document_ids 过滤
向量检索 top_k
返回片段内容、来源和分数
```
## 7. 工具调用策略
工具用于补足大模型不能直接可靠完成的业务动作。
V1 内置工具:
| 工具 | 用途 |
|---|---|
| `calculate_rate` | 计算比例、缺陷率、通过率 |
| `query_demo_records` | 查询模拟业务数据 |
| `check_required_fields` | 检查必填项 |
| `generate_action_items` | 生成行动项 |
工具返回格式:
```json
{
"tool_name": "calculate_rate",
"success": true,
"arguments": {},
"result": {},
"error": ""
}
```
## 8. 结构化输出
V1 支持以下输出类型:
- `general_answer`
- `document_review_report`
- `ticket_response`
- `quality_report`
- `risk_audit_report`
结构化输出优先使用 JSON。
解析失败时:
- 保留模型原始输出。
- 返回解析错误。
- 页面展示原始回答。
- 审计日志记录失败原因。
## 9. AgentResult
Agent Core 统一返回:
```json
{
"answer": "",
"structured_output": {},
"references": [],
"tool_calls": [],
"raw_output": "",
"model_name": "",
"latency_ms": 0,
"status": "success",
"error": ""
}
```
## 10. Adapter 策略
V1 默认使用自研轻量 Orchestrator通过 OpenAI 兼容接口接入 LLM 与 Embedding可自主选择 OpenAI、硅基流动等兼容服务。
后续可以扩展:
- OpenAI Agents SDK Adapter。
- Dify API Adapter。
- LangGraph Adapter。
所有 Adapter 应保持统一接口:
```text
run_agent(scenario_config, user_input, options=None) -> AgentResult
```
这样可以保证 Django 业务层不受底层 Agent 编排实现影响。

View File

@@ -1,169 +0,0 @@
# V1 功能设计文档
## 1. 功能设计目标
V1 的功能设计目标是让复试展示者在本地快速完成一个可讲解、可演示、可改题的 Agent Demo。系统不追求复杂平台能力而是优先保证以下闭环稳定
- 场景配置可选择。
- 文档可上传并入库。
- 用户可在场景下发起对话。
- Agent 可返回结构化结果、引用来源和工具调用记录。
- 每次成功或失败的对话都有审计记录。
- 本地和 Docker 均可启动。
## 2. 用户角色
V1 仅设计一个用户角色Demo 操作者。
该角色负责启动系统、选择场景、上传材料、触发入库、发起对话、查看输出和审计日志。系统不在 V1 中区分管理员、审核员、普通用户等权限角色。
## 3. 核心业务流程
```text
启动系统
查看 5 个预置场景
选择场景
上传题目材料
触发知识库入库
发起 Agent 对话
查看结构化输出、引用和工具调用
查看审计日志
```
任一环节失败时,页面应给出明确提示,并尽量保留用户已完成的上下文。
## 4. 场景选择流程
1. 首页调用 `apps.scenarios.services.list_scenarios()`
2. 服务从 `configs/` 读取 YAML 场景配置。
3. 校验必填字段、工具名称和输出类型。
4. 页面展示场景名称、描述、适用题型、启用状态。
5. 用户点击进入 `/chat/<scenario_id>/`
异常处理:
- 配置目录不存在:展示空状态和配置目录提示。
- 单个配置非法:不阻断其他配置,页面展示该配置错误。
- 场景不存在:跳转或渲染错误页,提示检查场景 ID。
## 5. 文件上传流程
1. 用户进入 `/documents/upload/`
2. 页面加载可用场景下拉框。
3. 用户选择场景并上传 `.txt``.md``.pdf``.docx` 文件。
4. Documents 模块校验文件类型和大小。
5. 保存文件到 `UPLOAD_ROOT/<scenario_id>/`
6. 写入 `UploadedDocument` 记录,状态为 `uploaded`
7. 返回文件列表页并展示上传结果。
V1 文件上传默认手动入库,避免上传大文件时页面阻塞过久。
## 6. 文档入库流程
1. 用户在文件列表点击“入库”。
2. Documents 模块读取文件并抽取文本。
3. 调用 `agent_core.rag.ingest.ingest_document()`
4. Agent Core 按固定长度切分文本。
5. 写入本地 Chroma collection。
6. 入库成功:更新状态为 `indexed`
7. 入库失败:更新状态为 `failed`,保存错误信息。
文本为空、文件丢失、向量库不可写都应进入失败状态,不能让页面报 500。
## 7. Agent 对话流程
```text
用户提交问题
Chat 表单校验
Scenarios 加载场景配置
Agent Core 执行 run_agent()
RAG 按场景和可选文档范围检索知识片段
工具系统执行可用工具
LLM Provider 生成结果
结构化输出解析
Audit 写入日志
Chat 页面展示结果
```
Chat 模块只负责请求处理和页面展示,不直接写 RAG、工具和模型调用细节。
## 8. RAG 检索流程
1. Orchestrator 读取场景配置中的 `rag.enabled``collection``top_k`
2. 若启用 RAG则调用 `agent_core.rag.retriever.retrieve()`
3. 检索必须按 `scenario_id` 过滤,避免跨场景污染。
4. 如果用户在对话页选择了文档,则同时按 `document_ids` 过滤;未选择时使用当前场景全部已入库文档。
5. 返回片段内容、来源文件、chunk ID、分数。
6. 片段进入 Prompt同时随 AgentResult 返回给页面和审计日志。
检索失败时AgentResult 应记录错误或警告;若业务允许,可继续使用非 RAG 上下文回答。
## 9. 工具调用流程
1. 场景配置声明可用工具名称。
2. Orchestrator 从 Tool Registry 查询工具。
3. 对不可用工具记录失败,不中断整个流程。
4. 内置工具按统一参数和返回结构执行。
5. 工具结果进入 Prompt 或结构化输出上下文。
6. 所有工具调用写入 AgentResult 和审计日志。
V1 先采用“配置声明 + Orchestrator 决策”的轻量策略,不实现复杂多轮工具调用协议。
## 10. 审计日志流程
1. Chat 模块在 Agent Core 返回后调用 `apps.audit.services.create_audit_log()`
2. 成功结果记录输入、输出、引用、工具调用、模型名和耗时。
3. 失败结果也记录场景、输入、错误信息和已产生的中间结果。
4. 日志中不得保存 `LLM_API_KEY`、环境变量完整内容或上传文件绝对敏感路径。
5. 审计列表展示摘要,详情页展示完整 JSON 片段。
## 11. 复试改题流程
1. 判断题目最接近的模板。
2. 复制 `configs/` 中相近 YAML。
3. 修改场景名称、角色、目标、指令和输出类型。
4. 上传题目文档并入库。
5. 如题目需要计算或查询,新增一个内置工具并在场景中声明。
6. 用 2 到 3 个问题验证输出和审计链路。
7. 演示时重点展示配置、知识库、工具调用、结构化结果和审计日志。
## 12. 异常处理流程
| 异常 | 处理方式 |
|---|---|
| 场景配置缺失 | 页面展示错误,保留返回首页入口 |
| 场景字段非法 | 标记非法配置,不影响其他场景 |
| 上传文件类型不支持 | 表单错误提示 |
| 文件读取失败 | 文档状态改为 `failed` |
| RAG 入库失败 | 记录错误信息并允许重试 |
| LLM 配置缺失 | AgentResult 返回失败,审计日志记录失败 |
| 工具调用失败 | 记录工具失败,流程尽量继续 |
| 结构化解析失败 | 展示原始输出并记录解析错误 |
## 13. V1 功能验收标准
- 首页可以展示 5 个预置场景。
- 场景配置来自 YAML 文件。
- 可以上传 `.txt``.md``.pdf``.docx` 文件。
- 文件可触发入库,并显示 `uploaded``indexed``failed` 状态。
- 可以进入任一场景对话页并提交问题。
- AgentResult 至少包含回答、结构化输出、引用、工具调用、耗时和状态。
- 成功和失败对话都能生成审计日志。
- 审计详情可以解释一次 Agent 输出的输入、依据和过程。
- 本地启动和 Docker 启动路径清晰可执行。

View File

@@ -1,144 +0,0 @@
# V1 数据库设计文档
## 1. 数据库设计目标
V1 数据库设计优先服务本地演示、讲解清晰和快速改题。数据模型只覆盖文件、对话、审计和简单示例业务数据,不引入复杂权限、多租户或工作流状态机。
## 2. 数据库选型
默认使用 SQLite数据库文件位于 `data/db.sqlite3`。SQLite 适合复试现场单机运行,便于 Docker 挂载和备份。
后续如需多人协作或更正式部署,可通过 Django settings 切换到 PostgreSQL但 V1 不强制实现。
## 3. 表结构总览
| 表 | Django Model | 模块 | 说明 |
|---|---|---|---|
| uploaded_document | `UploadedDocument` | Documents | 上传文件元数据和入库状态 |
| agent_audit_log | `AgentAuditLog` | Audit | Agent 执行审计快照 |
| demo_business_record | `DemoBusinessRecord` | Agent Core / Tools | 内置工具可查询的模拟业务数据 |
| chat_session | `ChatSession` | Chat | 可选,对话会话 |
| chat_message | `ChatMessage` | Chat | 可选,对话消息 |
## 4. UploadedDocument 表设计
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BigAutoField | PK | 主键 |
| scenario_id | CharField(100) | indexed | 关联场景 ID |
| original_name | CharField(255) | required | 原始文件名 |
| file | FileField | required | 文件相对路径 |
| file_type | CharField(20) | required | `txt``md``pdf``docx` 等 |
| size | PositiveIntegerField | default 0 | 字节数 |
| status | CharField(20) | indexed | `uploaded``indexed``failed` |
| error_message | TextField | blank | 入库失败原因 |
| created_at | DateTimeField | auto_now_add | 上传时间 |
| updated_at | DateTimeField | auto_now | 更新时间 |
状态流转:
```text
uploaded -> indexed
uploaded -> failed
failed -> indexed
failed -> failed
```
重新入库时应按文档维度覆盖或清理旧 chunk避免同一文件重复出现在向量检索结果中。文档选择范围由 Chat 表单本次提交的 `document_ids` 传入 Agent CoreV1 不需要为该选择单独建表。
## 5. AgentAuditLog 表设计
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BigAutoField | PK | 主键 |
| scenario_id | CharField(100) | indexed | 场景 ID |
| scenario_name | CharField(200) | blank | 场景名称快照 |
| user_input | TextField | required | 用户输入 |
| retrieved_chunks | JSONField | default list | RAG 引用片段 |
| tool_calls | JSONField | default list | 工具调用记录 |
| structured_output | JSONField | default dict | 结构化输出 |
| final_answer | TextField | blank | 最终回答 |
| raw_output | TextField | blank | 模型原始输出 |
| model_name | CharField(100) | blank | 模型名称 |
| latency_ms | PositiveIntegerField | default 0 | 执行耗时 |
| status | CharField(20) | indexed | `success``failed` |
| error_message | TextField | blank | 错误信息 |
| created_at | DateTimeField | auto_now_add, indexed | 创建时间 |
审计日志保存的是执行快照,不依赖场景配置后续是否被修改。
## 6. DemoBusinessRecord 表设计
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BigAutoField | PK | 主键 |
| scenario_id | CharField(100) | indexed | 适用场景 |
| record_type | CharField(100) | indexed | 记录类型,如 defect、ticket、invoice |
| title | CharField(255) | required | 标题 |
| payload | JSONField | default dict | 模拟业务数据 |
| created_at | DateTimeField | auto_now_add | 创建时间 |
该表为 V1 必需表,用于 `query_demo_records` 工具避免工具只能返回硬编码数据。Django Admin 可以管理该表的数据,场景 YAML 仍不在 Admin 中编辑。
## 7. ChatSession 表设计
V1 可先不实现会话持久化。如果实现,字段建议如下:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BigAutoField | 主键 |
| scenario_id | CharField(100) | 场景 ID |
| title | CharField(255) | 会话标题 |
| created_at | DateTimeField | 创建时间 |
| updated_at | DateTimeField | 更新时间 |
## 8. ChatMessage 表设计
V1 可通过审计日志满足演示追踪,不强制实现消息表。如果实现,字段建议如下:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BigAutoField | 主键 |
| session | ForeignKey(ChatSession) | 所属会话 |
| role | CharField(20) | `user``assistant``system` |
| content | TextField | 消息内容 |
| audit_log | ForeignKey(AgentAuditLog, null=True) | 关联审计 |
| created_at | DateTimeField | 创建时间 |
## 9. 表关系设计
```text
Scenario YAML
|-- scenario_id
|-- UploadedDocument.scenario_id
|-- AgentAuditLog.scenario_id
|-- DemoBusinessRecord.scenario_id
|-- ChatSession.scenario_id
ChatSession 1 -- N ChatMessage
ChatMessage 0/1 -- 1 AgentAuditLog
```
场景配置 V1 存在 YAML 中,不建 `Scenario` 数据表。这样更方便复试现场复制和修改配置文件。
## 10. 索引设计
- `UploadedDocument(scenario_id, status)`:用于按场景查看文件和入库状态。
- `AgentAuditLog(scenario_id, created_at)`:用于按场景查看最近日志。
- `AgentAuditLog(status, created_at)`:用于排查失败日志。
- `DemoBusinessRecord(scenario_id, record_type)`:用于工具查询模拟数据。
## 11. 数据初始化策略
- 场景初始化:读取 `configs/*.yaml`,不写数据库。
- 示例业务数据:可提供 Django management command 初始化 `DemoBusinessRecord`
- 超级用户本地演示可手动创建Docker 可通过说明引导创建。
- 上传文件和 Chroma 数据:存放在 `data/` 下,通过 Docker volume 持久化。
## 12. 后续扩展方向
- 增加 `Scenario` 表,实现后台编辑场景。
- 增加 `ToolCallLog` 独立表,用于复杂工具审计。
- 使用 PostgreSQL JSONB 优化 JSON 查询。
- 增加用户和权限模型。
- 增加文档 chunk 元数据表,便于从数据库追踪向量库内容。

View File

@@ -1,179 +0,0 @@
# V1 页面与路由设计文档
## 1. 页面设计目标
V1 页面使用 Django Templates优先保证清晰、稳定、可讲解。页面应围绕复试演示的主路径组织选择场景、上传文档、入库、对话、查看审计。
## 2. 页面列表
| 页面 | 路径 | 模块 | 说明 |
|---|---|---|---|
| 首页/场景列表 | `/` | Scenarios | 展示 5 个预置场景 |
| Agent 对话页 | `/chat/<scenario_id>/` | Chat | 提交问题并展示结果 |
| 文件列表页 | `/documents/` | Documents | 查看上传文件和入库状态 |
| 文件上传页 | `/documents/upload/` | Documents | 上传题目材料 |
| 文档入库动作 | `/documents/<id>/index/` | Documents | POST 触发入库 |
| 审计日志列表 | `/audit/` | Audit | 查看对话记录 |
| 审计日志详情 | `/audit/<log_id>/` | Audit | 查看单次执行详情 |
| Django Admin | `/admin/` | Config | 后台管理 |
## 3. 路由总览
```text
config.urls
|-- "" -> apps.scenarios.urls
|-- "chat/" -> apps.chat.urls
|-- "documents/" -> apps.documents.urls
|-- "audit/" -> apps.audit.urls
|-- "admin/" -> django.contrib.admin
```
各模块只暴露自己的 URL避免把业务路由集中写在 `config.urls` 中。
## 4. 首页与场景列表页
路径:`/`
展示内容:
- 系统名称和简短定位。
- 5 个场景卡片或列表。
- 场景名称、描述、适用题型、启用状态。
- “进入对话”按钮。
- 文件管理和审计日志入口。
错误状态:
- 没有可用场景:展示配置目录提示。
- 配置读取失败:展示失败原因和文件名。
## 5. Agent 对话页
路径:`/chat/<scenario_id>/`
页面区域:
- 场景摘要名称、角色、目标、RAG 状态、工具列表。
- 文档范围:当前场景下状态为 `indexed` 的文档多选框;未选择时默认使用全部已入库文档。
- 输入区:一个 textarea 和提交按钮。
- 结果区:自然语言回答和结构化输出。
- 引用区source、chunk_id、score、content。
- 工具区tool_name、success、arguments、result、error。
- 审计入口:当前对话生成日志后展示详情链接。
POST 成功后仍渲染同一页面,保留用户问题和 AgentResult。
## 6. 文件上传页
路径:`/documents/upload/`
页面元素:
- 场景选择下拉框。
- 文件选择控件。
- 支持类型提示。
- 上传按钮。
- 错误或成功提示。
表单接受 `.txt``.md``.pdf``.docx`。PDF 仅要求纯文本抽取DOCX 仅要求段落和普通文本抽取。
## 7. 文件列表页
路径:`/documents/`
展示字段:
- 原始文件名。
- 所属场景。
- 文件类型。
- 文件大小。
- 入库状态。
- 上传时间。
- 入库按钮。
- 失败原因。
状态为 `indexed` 时可以显示“重新入库”,重新入库需要覆盖或清理该文档旧 chunk。
## 8. 审计日志列表页
路径:`/audit/`
展示字段:
- 日志 ID。
- 场景名称。
- 用户输入摘要。
- 状态。
- 模型名称。
- 执行耗时。
- 创建时间。
- 详情入口。
默认按 `created_at desc` 排序。
## 9. 审计日志详情页
路径:`/audit/<log_id>/`
展示内容:
- 场景信息。
- 用户输入。
- 最终回答。
- 结构化输出 JSON。
- RAG 引用列表。
- 工具调用列表。
- 模型名称和耗时。
- 错误信息。
JSON 内容可以先用 `<pre>` 展示,优先保证可读。
## 10. Django Admin 页面
Admin 注册:
- `UploadedDocument`
- `AgentAuditLog`
- `DemoBusinessRecord`
V1 不要求在 Admin 中编辑 YAML 场景,场景仍以配置文件为准。
## 11. 页面跳转关系
```text
首页
|-- 进入对话页
|-- 文件列表页
|-- 审计日志列表页
文件列表页
|-- 文件上传页
|-- 触发入库后回到文件列表页
对话页
|-- 提交后留在当前对话页
|-- 查看当前审计详情
审计列表页
|-- 审计详情页
```
## 12. 页面异常状态
| 页面 | 异常 | 展示方式 |
|---|---|---|
| 首页 | 场景配置为空 | 空状态和配置目录说明 |
| 对话页 | 场景不存在 | 明确提示并提供返回首页 |
| 对话页 | Agent 执行失败 | 展示错误、保留输入、写入失败审计 |
| 上传页 | 文件类型错误 | 表单错误 |
| 文件列表 | 入库失败 | 状态为 failed 并显示原因 |
| 审计详情 | 日志不存在 | 404 或友好错误页 |
## 13. V1 页面验收标准
- 主要页面可通过浏览器访问。
- 页面之间跳转路径完整。
- POST 表单使用 CSRF 保护。
- 所有用户可见错误都有中文提示。
- Agent 对话结果可以同时看到回答、引用、工具和审计入口。
- 页面不依赖 React/Vue。

View File

@@ -1,111 +0,0 @@
# V1 部署设计文档
## 1. 部署设计目标
V1 部署目标是降低复试现场环境风险。系统应支持本地 Python 方式启动,也支持 Docker Compose 一键启动。默认不依赖外部数据库、Redis 或任务队列。
## 2. 本地运行方式
建议命令:
```bash
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver
```
本地运行使用 SQLite、`data/uploads``data/chroma`
当前本地方式会在启动时自动读取根目录 `.env`,因此 `runserver``pytest` 和日常脚本可以共享同一套配置。
## 3. Docker 运行方式
建议命令:
```bash
docker compose up --build
```
V1 Docker Compose 只需要一个 Django Web 服务。Chroma 使用本地持久化目录,不额外启动独立服务。
## 4. 环境变量设计
| 变量 | 默认值 | 说明 |
|---|---|---|
| `DJANGO_SECRET_KEY` | `dev-secret-key` | 开发密钥 |
| `DJANGO_DEBUG` | `true` | 是否开启调试 |
| `DJANGO_ALLOWED_HOSTS` | `*` | 允许主机 |
| `LLM_API_KEY` | 空 | 大模型 API Key |
| `LLM_BASE_URL` | `https://api.openai.com/v1` | OpenAI 兼容接口地址,可接入 OpenAI、硅基流动等兼容服务 |
| `LLM_MODEL` | `gpt-4.1-mini` | 默认模型 |
| `EMBEDDING_API_KEY` | 空 | Embedding API Key为空时可复用 `LLM_API_KEY` |
| `EMBEDDING_BASE_URL` | 空 | Embedding OpenAI 兼容接口地址;为空时可复用 `LLM_BASE_URL` |
| `EMBEDDING_MODEL` | `text-embedding-3-small` | 默认 Embedding 模型 |
| `SCENARIO_CONFIG_DIR` | `configs` | 场景配置目录 |
| `UPLOAD_ROOT` | `data/uploads` | 上传目录 |
| `CHROMA_PATH` | `data/chroma` | 向量库目录 |
`.env.example` 应提供这些变量的样例,不写真实密钥。
当前实现说明:
- 本地 Python 方式启动时,会先加载根目录 `.env`,再读取进程环境中的覆盖值。
- Docker Compose 方式可通过 `env_file` 向容器注入环境变量;当前仓库默认读取 `.env`
- 因此本地运行和容器运行可以默认共用一份 `.env`,但演示前仍应确认密钥和模型参数是否正确。
## 5. 目录挂载设计
Docker 需要持久化以下目录:
```text
./data/db.sqlite3
./data/uploads
./data/chroma
./configs
```
`configs` 挂载后可以在不重建镜像的情况下修改场景配置。
## 6. SQLite 数据持久化
SQLite 文件放在 `data/db.sqlite3`。Docker 中应将 `data/` 作为 volume 挂载,避免容器重建后数据丢失。
## 7. Chroma 数据持久化
Chroma 数据放在 `data/chroma`。RAG 入库后,重启容器不应丢失向量数据。
## 8. 上传文件持久化
上传文件放在 `data/uploads/<scenario_id>/`。数据库只保存相对路径或 Django FileField 路径。
## 9. 启动命令设计
Docker 容器启动时建议执行:
```bash
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
```
V1 可以先用开发服务器满足演示。后续正式部署可切换到 Gunicorn。
## 10. 常见部署问题
| 问题 | 处理 |
|---|---|
| 端口 8000 被占用 | 修改 compose 端口映射 |
| API Key 缺失 | 页面提示 LLM 或 Embedding 配置缺失 |
| Chroma 目录无权限 | 检查 `data/chroma` 挂载权限 |
| 上传目录不存在 | settings 或启动脚本创建目录 |
| 场景配置读取失败 | 检查 `configs/*.yaml` 格式 |
| Docker 构建慢 | 提前构建镜像或使用本地 Python 方式演示 |
## 11. 后续部署扩展
- 使用 Gunicorn + WhiteNoise。
- 增加 PostgreSQL 服务。
- 增加 Redis 和 Celery 做异步入库。
- 增加 Nginx 反向代理。
- 增加健康检查接口。

View File

@@ -1,112 +0,0 @@
# 配置模块详细设计
## 1. 模块目标
Config 模块负责 Django 项目的启动配置和总装配。它不承载业务逻辑,只为其他模块提供稳定运行环境。
目标:
- 项目本地和 Docker 均可启动。
- 环境变量可覆盖关键配置。
- App、模板、静态资源、上传文件和数据库路径统一配置。
- URL 总入口清晰,模块路由各自维护。
## 2. 职责边界
负责:
- `settings.py``urls.py``wsgi.py``asgi.py`
- 环境变量读取和默认值。
- SQLite、静态文件、媒体文件、Chroma、场景配置目录。
- Django Admin 和模块 URL 装配。
不负责:
- 不读取场景 YAML 业务内容。
- 不调用 Agent Core。
- 不处理上传文件文本抽取。
- 不写审计日志。
## 3. 配置项设计
| 配置 | Django setting | 默认值 |
|---|---|---|
| `DJANGO_SECRET_KEY` | `SECRET_KEY` | `dev-secret-key` |
| `DJANGO_DEBUG` | `DEBUG` | `true` |
| `DJANGO_ALLOWED_HOSTS` | `ALLOWED_HOSTS` | `["*"]` |
| `UPLOAD_ROOT` | `MEDIA_ROOT` | `BASE_DIR / "data" / "uploads"` |
| `SCENARIO_CONFIG_DIR` | `SCENARIO_CONFIG_DIR` | `BASE_DIR / "configs"` |
| `CHROMA_PATH` | `CHROMA_PATH` | `BASE_DIR / "data" / "chroma"` |
| `LLM_API_KEY` | `LLM_API_KEY` | 空 |
| `LLM_BASE_URL` | `LLM_BASE_URL` | `https://api.openai.com/v1` |
| `LLM_MODEL` | `LLM_MODEL` | `gpt-4.1-mini` |
| `EMBEDDING_API_KEY` | `EMBEDDING_API_KEY` | 空,默认可复用 `LLM_API_KEY` |
| `EMBEDDING_BASE_URL` | `EMBEDDING_BASE_URL` | 空,默认可复用 `LLM_BASE_URL` |
| `EMBEDDING_MODEL` | `EMBEDDING_MODEL` | `text-embedding-3-small` |
## 4. 目录路径设计
启动前或初始化时应确保:
```text
data/
uploads/
chroma/
configs/
static/
templates/
```
V1 可以在 `settings.py` 中定义路径,在 management command 或启动脚本中创建目录。生产代码不应在每次请求中反复创建目录。
## 5. URL 总路由设计
`config.urls`
```python
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("apps.scenarios.urls")),
path("chat/", include("apps.chat.urls")),
path("documents/", include("apps.documents.urls")),
path("audit/", include("apps.audit.urls")),
]
```
开发模式下追加 `static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)`,用于访问上传文件。
## 6. 静态资源与上传文件设计
- `STATIC_URL = "static/"`
- `STATICFILES_DIRS = [BASE_DIR / "static"]`
- `MEDIA_URL = "media/"`
- `MEDIA_ROOT = UPLOAD_ROOT`
上传文件路径由 Documents 模块按场景组织Config 只提供根目录。
## 7. 环境变量读取设计
V1 可使用标准库 `os.environ.get()`,不强制引入复杂配置库。
布尔值规则:
```text
"1", "true", "yes", "on" -> True
其他 -> False
```
`DJANGO_ALLOWED_HOSTS` 使用逗号分隔,空值时默认 `["*"]`
当前实现约束:
- 本地直接运行 Django 命令时,会先尝试解析根目录 `.env` 文件,再读取进程环境中的覆盖值。
- Docker Compose 方式可以通过 `env_file` 传入同一批变量;当前仓库默认读取 `.env`
- `.env.example` 只保留占位符示例,不保存真实 API Key。
## 8. 验收标准
- `python manage.py check` 通过。
- `python manage.py migrate` 可执行。
- `/``/admin/` 路由可访问。
- `MEDIA_ROOT``CHROMA_PATH``SCENARIO_CONFIG_DIR` 在 settings 中可被其他模块引用。
- LLM 与 Embedding 配置只从 settings 或环境变量读取,不散落在业务代码中。

View File

@@ -1,134 +0,0 @@
# 场景模块详细设计
## 1. 模块目标
Scenarios 模块是业务 Agent 的入口,负责读取和展示场景配置,并向 Chat、Documents、Agent Core 提供场景上下文。
## 2. 职责边界
负责:
-`configs/*.yaml` 读取场景。
- 校验场景必填字段。
- 展示场景列表和场景摘要。
- 提供 `list_scenarios()``get_scenario()` 等服务。
不负责:
- 不执行 Agent。
- 不做 RAG 检索。
- 不调用工具和大模型。
- 不保存审计日志。
## 3. 场景配置结构
必填结构:
```yaml
id: knowledge_qa
name: 知识库问答助手
description: 用于 SOP、制度和内部知识库问答
applicable_questions:
- SOP 问答
- 制度问答
agent:
role: 知识库问答专家
goal: 基于知识库回答用户问题
system_prompt: ""
instructions:
- 回答必须基于检索内容
rag:
enabled: true
collection: knowledge_qa
top_k: 5
tools:
- generate_action_items
output:
type: general_answer
audit:
enabled: true
```
`agent.system_prompt` 为可选字段。配置了非空值时Agent Core 优先使用该字段作为系统提示词;为空或缺失时,由 `role``goal``instructions` 组合生成系统提示词。
`applicable_questions` 作为页面展示字段,若缺失可显示为空列表。
## 4. 场景加载流程
1. 读取 `settings.SCENARIO_CONFIG_DIR`
2. 遍历 `.yaml``.yml` 文件。
3. 使用 YAML parser 转为 dict。
4. 调用 `validate_scenario()`
5. 转换为 `ScenarioConfig` dataclass 或普通 dict。
6. 按文件名或配置顺序返回。
为了便于复试修改V1 不需要强缓存;若加缓存,应提供清理方式或在 DEBUG 下禁用缓存。
## 5. 场景校验规则
必填字段:
- `id`
- `name`
- `description`
- `agent.role`
- `agent.goal`
- `agent.instructions`
- `rag.enabled`
- `tools`
- `output.type`
- `audit.enabled`
校验失败时返回包含文件名、字段路径、错误原因的结果。列表页可以跳过非法场景并展示错误摘要。
## 6. 页面设计
首页路径:`/`
展示:
- 场景名称。
- 场景描述。
- 适用题型。
- RAG 是否启用。
- 工具数量。
- 进入对话按钮。
可选详情页:`/scenarios/<scenario_id>/`。V1 可以把详情合并到 Chat 页面。
## 7. 服务函数设计
```python
def list_scenarios() -> list[ScenarioConfig]:
"""读取配置目录中的合法场景,非法场景以错误摘要返回给页面。"""
def get_scenario(scenario_id: str) -> ScenarioConfig:
"""按场景 ID 返回完整配置,找不到时抛出 ScenarioNotFound。"""
def validate_scenario(config: dict) -> ValidationResult:
"""校验必填字段、字段类型、工具名称和输出类型。"""
```
`get_scenario()` 找不到时抛出业务异常,例如 `ScenarioNotFound`,由 View 转成中文错误提示。
## 8. 异常处理
| 异常 | 处理 |
|---|---|
| 配置目录不存在 | 返回空列表和错误提示 |
| YAML 语法错误 | 标记该文件无效 |
| ID 重复 | 保留第一个,报告重复错误 |
| 必填字段缺失 | 标记该场景无效 |
| 工具不存在 | 场景仍可展示,但 Chat 执行时记录工具错误 |
## 9. 验收标准
- 首页至少展示 5 个场景。
- 场景配置来自 `configs/` 文件。
- 非法配置有明确错误,不导致首页 500。
- Chat 可通过 `scenario_id` 获取完整配置。

View File

@@ -1,127 +0,0 @@
# 文档模块详细设计
## 1. 模块目标
Documents 模块让用户把复试题材料快速变成 Agent 可检索的知识库。V1 必须支持 `.txt``.md``.pdf``.docx`,保证常见复试材料可以进入 RAG。
## 2. 职责边界
负责:
- 文件上传表单和页面。
- 文件保存与元数据记录。
- 读取文本内容。
- 调用 Agent Core RAG 入库。
- 更新入库状态。
不负责:
- 不实现向量检索算法。
- 不生成模型回答。
- 不直接写审计日志。
## 3. 数据模型设计
模型:`UploadedDocument`
字段见 `docs/设计文档/3.数据库设计.md`
常量:
```python
STATUS_UPLOADED = "uploaded"
STATUS_INDEXED = "indexed"
STATUS_FAILED = "failed"
SUPPORTED_EXTENSIONS = {".txt", ".md", ".pdf", ".docx"}
```
文件保存路径建议:
```text
uploads/<scenario_id>/<YYYYMMDD>/<uuid>_<original_name>
```
## 4. 文件上传流程
1. GET `/documents/upload/` 渲染上传表单。
2. POST 校验 `scenario_id` 和文件。
3. 调用 Scenarios 服务确认场景存在。
4. 校验扩展名和文件大小。
5. 保存文件。
6. 创建 `UploadedDocument(status="uploaded")`
7. 跳转文件列表页并展示成功提示。
## 5. 文本抽取流程
抽取函数:
```python
def extract_text(document: UploadedDocument) -> str:
"""按文件类型抽取可入库纯文本,失败时抛出可展示的业务异常。"""
```
规则:
- `.txt`:优先 UTF-8失败时尝试系统默认编码。
- `.md`UTF-8 读取,保留标题、列表和正文。
- `.pdf`:抽取纯文本,不要求 OCR、表格还原和复杂版式理解。
- `.docx`:抽取段落、标题和普通表格文本,不要求完整保留 Word 样式。
- 空文本视为失败。
- 文件不存在视为失败。
XLSX 暂不作为 V1 必须项,可作为后续结构化业务数据导入能力。
## 6. RAG 入库触发流程
POST `/documents/<id>/index/`
1. 获取 `UploadedDocument`
2. 调用 `extract_text()`
3. 调用 `agent_core.rag.ingest.ingest_document()`,传入 `document_id``scenario_id`、文件名和抽取文本。
4. 成功后更新 `status="indexed"`,清空 `error_message`
5. 失败后更新 `status="failed"`,写入 `error_message`
6. 重定向回文件列表页。
入库动作必须使用 POST避免 GET 触发写操作。
已入库或失败文档允许重新入库。重新入库前需要按 `document_id` 清理或覆盖旧 chunk避免重复检索。
## 7. 页面设计
文件列表页展示:
- 文件名。
- 场景 ID。
- 文件类型。
- 文件大小。
- 状态。
- 上传时间。
- 入库按钮。
- 错误信息。
上传页展示:
- 场景下拉框。
- 文件控件。
- 支持类型提示。
- 表单错误。
## 8. 异常处理
| 异常 | 处理 |
|---|---|
| 场景不存在 | 表单错误 |
| 文件为空 | 表单错误 |
| 扩展名不支持 | 表单错误 |
| 文件保存失败 | 页面提示失败 |
| 文本为空 | 状态 failed |
| RAG 入库失败 | 状态 failed 并保存原因 |
## 9. 验收标准
- 可以上传 `.txt``.md``.pdf``.docx`
- 文件列表可看到记录。
- 文件可按场景关联。
- 入库成功状态变为 `indexed`
- 入库失败状态变为 `failed` 且可查看原因。
- 入库失败或已入库文档可重新入库。

View File

@@ -1,118 +0,0 @@
# 对话模块详细设计
## 1. 模块目标
Chat 模块负责复试演示中的主交互:用户选择场景后提交问题,系统展示 Agent 输出、引用、工具调用和审计入口。
## 2. 职责边界
负责:
- 对话页 GET/POST。
- 用户输入表单校验。
- 获取场景配置。
- 调用 Agent Core。
- 调用 Audit 服务写日志。
- 渲染 AgentResult。
不负责:
- 不直接读取 YAML。
- 不直接调用 LLM。
- 不直接执行 RAG 和工具。
- 不实现复杂多轮会话状态。
## 3. 页面设计
路径:`/chat/<scenario_id>/`
GET
- 加载场景配置。
- 展示场景摘要。
- 加载当前场景下状态为 `indexed` 的文档列表。
- 展示空表单。
POST
- 校验输入。
- 执行 Agent。
- 写审计。
- 展示结果和审计链接。
## 4. 表单设计
字段:
| 字段 | 类型 | 规则 |
|---|---|---|
| `message` | textarea | 必填,最大 4000 字 |
| `document_ids` | 多选 | 可选,只能选择当前场景下已入库文档 |
错误提示:
- 空输入:`请输入要咨询的问题。`
- 超长输入:`问题过长,请控制在 4000 字以内。`
- 文档不属于当前场景或未入库:`请选择当前场景下已入库的文档。`
## 5. Agent Core 调用流程
```python
scenario = get_scenario(scenario_id)
result = run_agent(
scenario_config=scenario,
user_input=form.cleaned_data["message"],
options={"document_ids": form.cleaned_data.get("document_ids", [])}
)
```
Chat 只依赖 Agent Core 的统一返回对象,不关心内部是否使用 RAG、工具或真实模型。
未选择文档时,`document_ids` 传空列表或不传,由 Agent Core 默认使用当前场景全部已入库文档。
## 6. 结果展示设计
优先级:
1. 如果 `structured_output` 不为空,展示结构化 JSON 或字段化结果。
2. 展示 `answer`
3. 展示 `references`
4. 展示 `tool_calls`
5. 展示 `latency_ms``model_name``status`
6. 如果有 `error`,展示中文错误提示。
结构化解析失败时,页面仍展示 `raw_output``answer`
## 7. 审计日志写入流程
Agent Core 返回后调用:
```python
audit_log = create_audit_log(
scenario_id=scenario.id,
scenario_name=scenario.name,
user_input=message,
agent_result=result,
)
```
如果 Agent Core 抛异常Chat 应构造失败结果并继续写失败审计。
## 8. 异常处理
| 异常 | 处理 |
|---|---|
| 场景不存在 | 显示错误并返回首页入口 |
| 表单无效 | 留在页面并显示表单错误 |
| Agent Core 抛异常 | 构造 failed AgentResult写审计 |
| 审计写入失败 | 页面提示审计失败,但展示 Agent 输出 |
| LLM 配置缺失 | 展示模型配置缺失 |
## 9. 验收标准
- 从首页可进入对话页。
- 可提交问题并渲染 AgentResult。
- 可选择本次对话使用的文档范围;未选择时默认使用当前场景全部已入库文档。
- 失败时有中文提示。
- 成功和失败都尽量写入审计。
- View 中没有 RAG、工具、LLM 的细节实现。

View File

@@ -1,121 +0,0 @@
# 审计模块详细设计
## 1. 模块目标
Audit 模块记录 Agent 执行过程,使演示者能够解释一次输出的来源、工具调用和模型结果。它是系统从“普通问答页面”变成“可追踪业务 Agent”的关键。
## 2. 职责边界
负责:
- `AgentAuditLog` 模型。
- 审计写入服务。
- 审计列表页。
- 审计详情页。
- 敏感信息过滤。
不负责:
- 不执行 Agent。
- 不执行 RAG。
- 不执行工具。
- 不调用模型。
## 3. 数据模型设计
模型:`AgentAuditLog`
字段见 `docs/设计文档/3.数据库设计.md`
JSON 字段默认值必须使用函数,例如 `default=list``default=dict`,避免多实例共享同一对象。
## 4. 日志写入流程
服务函数:
```python
def create_audit_log(
scenario_id: str,
scenario_name: str,
user_input: str,
agent_result: AgentResult,
) -> AgentAuditLog:
"""将 AgentResult 映射为 AgentAuditLog并在保存前做敏感信息脱敏。"""
```
写入映射:
- `agent_result.references` -> `retrieved_chunks`
- `agent_result.tool_calls` -> `tool_calls`
- `agent_result.structured_output` -> `structured_output`
- `agent_result.answer` -> `final_answer`
- `agent_result.raw_output` -> `raw_output`
- `agent_result.model_name` -> `model_name`
- `agent_result.latency_ms` -> `latency_ms`
- `agent_result.status` -> `status`
- `agent_result.error` -> `error_message`
## 5. 日志列表页设计
路径:`/audit/`
查询:
- 默认按创建时间倒序。
- V1 可不做分页,若日志较多再加 Django Paginator。
展示:
- ID。
- 场景名称。
- 用户输入前 80 字。
- 状态。
- 模型名。
- 耗时。
- 创建时间。
- 详情链接。
## 6. 日志详情页设计
路径:`/audit/<log_id>/`
展示:
- 基础信息。
- 用户输入。
- 最终回答。
- 结构化输出。
- RAG 检索片段。
- 工具调用。
- 原始输出。
- 错误信息。
JSON 可用格式化后的 `<pre>` 展示。
## 7. 敏感信息处理
不得保存:
- `LLM_API_KEY`
- 完整环境变量 dump
- 用户机器上的敏感绝对路径
- Docker secret 或 token
如错误信息来自异常对象,应在保存前做简单脱敏,至少替换 API Key 值。
## 8. 异常处理
| 异常 | 处理 |
|---|---|
| AgentResult 字段缺失 | 使用默认空值 |
| JSON 不可序列化 | 转为字符串或空对象 |
| 日志不存在 | 返回 404 |
| 写入失败 | 抛给 Chat由 Chat 展示审计失败提示 |
## 9. 验收标准
- 每次对话成功后有审计日志。
- Agent 失败也有失败日志。
- 列表页可查看日志摘要。
- 详情页可查看输入、输出、引用和工具调用。
- 日志不包含 API Key。

View File

@@ -1,259 +0,0 @@
# 智能核心模块详细设计
## 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。

View File

@@ -1,583 +0,0 @@
# Universal Agent Demo Framework V1 需求文档
## 1. 项目背景
本项目用于复试展示。复试题目暂时未知但大概率围绕企业生产、质量、客服、财务、SOP、文档审核、工单处理等场景。
项目目标不是提前猜中某一个具体业务题,而是先搭建一个通用 AI Agent Demo 底座。拿到复试题目后,可以通过修改场景配置、上传知识库、补充少量业务工具,快速生成一个可演示的业务 Agent 系统。
核心理念:
```text
业务 Agent = 场景配置 + 知识库 + 工具集 + 输出模板 + 审计日志 + 模型适配器
```
## 2. 项目目标
V1 版本目标是实现一个可运行、可演示、可快速改题的基础平台。
系统需要支持:
- 通过配置快速创建不同业务 Agent。
- 支持上传文档并构建 RAG 知识库。
- 支持根据场景调用内置业务工具。
- 支持结构化输出,方便展示报告、风险点、建议动作等结果。
- 支持审计日志,记录用户输入、检索内容、工具调用和模型输出。
- 支持 Docker 一键启动,降低复试现场环境风险。
- 支持快速替换大模型 API。
## 3. 非目标
V1 不追求完整企业级平台能力,以下内容暂不作为第一版重点:
- 复杂权限系统。
- 多租户管理。
- 完整工作流引擎。
- 复杂多 Agent 协作。
- 前后端分离架构。
- 深度集成 Dify。
- 生产级高并发优化。
- 完整在线文档协同编辑。
## 4. 技术方案
### 4.1 总体架构
V1 使用 Django 单体应用承载企业系统外壳Agent Core 作为独立 Python 模块承载智能编排能力。
```text
Django Monolith
|
|-- Web UI
| |-- 场景选择
| |-- Agent 对话
| |-- 文件上传
| |-- 结构化结果展示
| |-- 审计日志查看
|
|-- Django Admin
| |-- 上传文件管理
| |-- 审计日志管理
| |-- 示例业务数据管理
|
|-- Agent Core
| |-- 场景配置加载
| |-- RAG 检索
| |-- 工具注册与调用
| |-- 大模型适配
| |-- 结构化输出解析
|
|-- Storage
|-- SQLite
|-- Chroma
|-- Uploaded Files
```
### 4.2 技术栈
| 模块 | 技术 | 说明 |
|---|---|---|
| Web 框架 | Django | 负责页面、模型、后台、文件上传和业务管理 |
| 页面渲染 | Django Templates + Bootstrap | 降低前端复杂度,快速完成 Demo |
| 数据库 | SQLite | V1 默认数据库,适合本地演示 |
| 向量库 | Chroma | 本地 RAG 知识库 |
| Agent Core | 自研轻量 Orchestrator | 保证可控、易讲解、易改题 |
| LLM 接入 | OpenAI API 兼容接口 | 方便切换 OpenAI、硅基流动等兼容服务、国产模型或本地代理 |
| Embedding 接入 | OpenAI API 兼容接口 | 用于文档向量化,供应商可自主选择 |
| 部署 | Docker + Docker Compose | 支持一键启动 |
## 5. 用户角色
V1 只设计一个主要用户角色:
### Demo 操作者
通常是复试时的展示者,负责选择场景、上传材料、输入问题、查看 Agent 输出和审计记录。
暂不区分管理员、业务人员、审核人员等复杂角色。
## 6. 核心使用流程
### 6.1 复试前准备流程
1. 启动系统。
2. 选择或复制一个已有场景模板。
3. 根据题目修改场景配置。
4. 上传题目相关文档。
5. 如有必要,补充一个业务工具函数。
6. 运行一次测试对话。
7. 使用审计日志确认 RAG、工具调用和输出链路正常。
### 6.2 复试演示流程
1. 打开系统首页。
2. 展示系统支持多个业务场景。
3. 选择当前题目对应的 Agent。
4. 上传或选择知识库文档。
5. 输入业务问题。
6. 展示 Agent 的结构化输出。
7. 展示引用来源、工具调用和审计日志。
8. 说明同一平台可通过配置切换到其他业务场景。
## 7. 场景模板
V1 预置 5 类通用场景模板,用于覆盖大多数复试题型。
| 模板 ID | 模板名称 | 适用题型 |
|---|---|---|
| knowledge_qa | 知识库问答助手 | SOP、制度、客服知识库、内部文档问答 |
| document_review | 文档审核助手 | 合同审核、制度审核、SOP 审核、材料合规检查 |
| ticket_assistant | 工单处理助手 | 客服工单、售后工单、运维工单 |
| quality_analysis | 质量异常分析助手 | 生产质量、缺陷分析、原因定位 |
| risk_audit | 风险审核助手 | 财务审核、采购审核、报销审核、合同风险 |
## 8. 场景配置需求
场景应通过 YAML 或 JSON 文件定义,避免把业务逻辑写死在代码中。
配置内容包括:
- 场景 ID。
- 场景名称。
- 场景描述。
- Agent 角色。
- Agent 任务目标。
- 系统提示词 可选。
- 是否启用 RAG。
- RAG 检索参数。
- 可用工具列表。
- 输出模板类型。
- 审计策略。
示例:
```yaml
id: quality_analysis
name: 质量异常分析助手
description: 用于分析生产质量异常、检索 SOP、生成处理建议
agent:
role: 质量管理专家
goal: 根据用户问题、知识库和工具结果,输出可执行的质量分析报告
system_prompt: 你是质量管理专家,需要基于知识库和工具结果输出结构化质量分析报告
instructions:
- 回答必须基于知识库或工具结果
- 不确定时必须说明缺失信息
- 涉及质量风险时给出风险等级
rag:
enabled: true
collection: quality_docs
top_k: 5
tools:
- query_demo_records
- calculate_rate
output:
type: quality_report
audit:
enabled: true
log_retrieval: true
log_tool_calls: true
```
## 9. 功能需求
### 9.1 首页
首页需要展示系统定位和可用场景列表。
页面能力:
- 查看所有 Agent 场景。
- 进入某个场景的对话页。
- 查看最近审计日志入口。
- 查看文件上传入口。
### 9.2 场景选择
系统需要支持从预置模板中选择业务场景。
V1 从 YAML 配置文件读取场景。后台管理只负责上传文件、审计日志和示例业务数据管理,不作为场景配置入口。
最低要求:
- 展示场景名称。
- 展示场景描述。
- 展示场景适用题型。
- 点击后进入对应 Agent 对话页。
### 9.3 Agent 对话
Agent 对话页是核心演示页面。
页面需要包含:
- 当前场景名称。
- 用户输入框。
- 文件上下文选择,可多选当前场景已入库文档;不选时默认使用当前场景全部已入库文档。
- Agent 输出区域。
- 结构化结果展示区域。
- 引用片段展示区域。
- 工具调用展示区域。
Agent 执行流程:
1. 接收用户问题。
2. 加载当前场景配置。
3. 如果启用 RAG则检索相关知识片段。
4. 根据场景判断是否调用工具。
5. 调用大模型生成结果。
6. 解析为结构化输出。
7. 写入审计日志。
8. 返回页面展示。
### 9.4 文件上传
系统需要支持上传题目材料和知识库文档。
V1 支持的文件类型:
- TXT
- Markdown
- PDF
- DOCX
- XLSX 可作为后续增强
文件上传后需要保存:
- 原始文件名。
- 文件路径。
- 文件类型。
- 上传时间。
- 关联场景。
- 是否已入库。
### 9.5 RAG 知识库
系统需要支持将上传文档写入向量库,并在 Agent 对话时检索。
V1 RAG 流程:
1. 读取上传文件文本。
2. 按固定长度切分文本。
3. 生成 embedding。
4. 写入 Chroma collection。
5. 对话时根据用户问题检索 top_k 片段。
6. 将片段作为上下文传给 Agent。
7. 在结果中展示引用来源。
### 9.6 工具调用
系统需要提供一个工具注册机制。
V1 内置工具建议包括:
| 工具名 | 用途 |
|---|---|
| calculate_rate | 计算比例、缺陷率、通过率等指标 |
| query_demo_records | 查询模拟业务数据 |
| check_required_fields | 检查文档或表单必填项 |
| generate_action_items | 根据问题生成行动项 |
工具调用需要记录到审计日志中。
### 9.7 结构化输出
不同场景需要不同输出模板。
V1 至少支持以下输出类型:
#### 通用问答输出
- answer
- references
- confidence
#### 文档审核输出
- summary
- issues
- risk_level
- suggestions
- missing_items
- references
#### 工单处理输出
- reply
- category
- priority
- suggested_action
- need_human_review
#### 质量分析输出
- summary
- possible_causes
- evidence
- risk_level
- suggested_actions
- references
### 9.8 审计日志
系统需要记录每次 Agent 执行过程。
审计字段:
- 日志 ID。
- 场景 ID。
- 用户输入。
- 检索片段。
- 工具调用记录。
- 模型名称。
- 结构化输出。
- 原始输出。
- 执行耗时。
- 创建时间。
审计日志页面需要支持:
- 查看日志列表。
- 查看单条日志详情。
- 展示检索内容。
- 展示工具调用。
- 展示最终输出。
### 9.9 模型适配
系统需要通过统一接口调用大模型,避免模型 API 写死。
V1 模型适配器需要支持:
- 从环境变量读取 API Key。
- 从环境变量读取 Base URL。
- 从环境变量读取 Model Name。
- 支持 OpenAI API 兼容格式,可接入 OpenAI、硅基流动等兼容供应商。
- 支持独立配置 Embedding 模型,用于 RAG 入库和检索。
环境变量示例:
```env
DJANGO_SECRET_KEY=replace-with-a-local-secret-key
DJANGO_DEBUG=true
DJANGO_ALLOWED_HOSTS=*
LLM_API_KEY=your_api_key
LLM_BASE_URL=https://api.openai.com/v1
LLM_MODEL=gpt-4.1-mini
EMBEDDING_API_KEY=
EMBEDDING_BASE_URL=
EMBEDDING_MODEL=text-embedding-3-small
SCENARIO_CONFIG_DIR=configs
UPLOAD_ROOT=data/uploads
CHROMA_PATH=data/chroma
```
补充说明:
- `EMBEDDING_API_KEY` 为空时可复用 `LLM_API_KEY`
- `EMBEDDING_BASE_URL` 为空时可复用 `LLM_BASE_URL`
- `.env.example` 仅作为模板,不允许放真实密钥。
- 当前 V1 代码会在 settings 初始化时自动读取根目录 `.env`,本地运行与 `pytest` 可复用同一套配置;当前 Docker Compose 配置也通过 `env_file` 读取 `.env`
## 10. Dify 集成策略
V1 不把 Dify 作为核心依赖。
原因:
- 复试现场需要最大程度保证可控。
- 自研 Agent Core 更方便解释架构设计。
- 题目未知时,直接依赖外部平台会增加部署和调试风险。
- Django + Agent Core 已能覆盖第一版演示需求。
系统预留 Agent Engine Adapter 概念,后续可接入 Dify、OpenAI Agents SDK 或其他企业 AI 平台。
V1 默认引擎:
```text
Lightweight Orchestrator
```
后续可扩展:
```text
Dify API Adapter
OpenAI Agents SDK Adapter
LangGraph Adapter
```
## 11. Docker 部署需求
系统需要支持 Docker Compose 一键启动。
基础命令:
```bash
docker compose up --build
```
V1 容器内容:
- Django Web 服务。
- SQLite 数据文件挂载。
- Chroma 数据目录挂载。
- 上传文件目录挂载。
V1 暂不强制引入 PostgreSQL。如果后续需要更正式的部署效果可以在 Docker Compose 中增加 PostgreSQL 服务。
## 12. 推荐项目结构
```text
universal-agent-demo/
manage.py
requirements.txt
Dockerfile
docker-compose.yml
.env.example
README.md
config/
settings.py
urls.py
wsgi.py
asgi.py
apps/
scenarios/
models.py
admin.py
services.py
chat/
views.py
urls.py
forms.py
documents/
models.py
views.py
services.py
audit/
models.py
admin.py
services.py
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
configs/
knowledge_qa.yaml
document_review.yaml
ticket_assistant.yaml
quality_analysis.yaml
risk_audit.yaml
data/
uploads/
chroma/
db.sqlite3
templates/
base.html
home.html
chat/index.html
documents/upload.html
audit/logs.html
static/
css/
js/
```
## 13. 模块需求文档
V1 按 6 个核心模块拆分,具体模块需求见:
| 模块 | 文档 |
|---|---|
| 配置 | `docs/需求分析/3.配置模块需求.md` |
| 场景 | `docs/需求分析/4.场景模块需求.md` |
| 文档 | `docs/需求分析/5.文档模块需求.md` |
| 对话 | `docs/需求分析/6.对话模块需求.md` |
| 审计 | `docs/需求分析/7.审计模块需求.md` |
| 智能核心 | `docs/需求分析/8.智能核心模块需求.md` |
模块总览见:
```text
docs/需求分析/2.模块需求索引.md
```
## 14. V1 验收标准
V1 完成后,需要满足以下验收标准:
- 可以通过 Docker Compose 启动系统。
- 首页可以看到至少 5 个预置场景。
- 可以进入某个场景进行 Agent 对话。
- 可以上传 TXT、Markdown、PDF 或 DOCX 文件。
- 可以将上传文件写入本地知识库。
- Agent 回答时可以使用知识库检索结果。
- 至少支持 2 个内置工具调用。
- Agent 输出可以以结构化方式展示。
- 每次对话都会生成审计日志。
- 审计日志中可以查看用户问题、检索内容、工具调用和最终输出。
- 可以通过环境变量切换大模型 API 地址和模型名。
## 15. 复试改题策略
拿到题目后,优先按以下步骤适配:
1. 判断题目属于哪类模板。
2. 复制最接近的 YAML 场景配置。
3. 修改 Agent 角色、任务目标和输出模板。
4. 上传题目给出的文档或样例数据。
5. 如果题目需要业务计算,则新增一个工具函数。
6. 用 2 到 3 个测试问题验证效果。
7. 演示时重点展示配置、知识库、工具调用、结构化输出和审计日志。
题型映射:
| 题目类型 | 优先模板 |
|---|---|
| SOP 问答 | knowledge_qa |
| 制度问答 | knowledge_qa |
| 文档审核 | document_review |
| 客服处理 | ticket_assistant |
| 质量异常分析 | quality_analysis |
| 财务审核 | risk_audit |
| 采购审核 | risk_audit |
| 合同风险分析 | document_review 或 risk_audit |
## 16. 后续迭代方向
V1 完成后,可以根据时间增加以下能力:
- 支持 Excel 数据分析工具。
- 支持后台页面编辑场景配置,并同步生成或更新 YAML。
- 支持流式输出。
- 支持 OpenAI Agents SDK Adapter。
- 支持 Dify API Adapter。
- 支持 PostgreSQL 部署模式。
- 支持简单登录认证。
- 支持演示数据一键初始化。

View File

@@ -1,85 +0,0 @@
# 模块需求文档索引
本文档用于汇总 Universal Agent Demo Framework V1 的模块拆分和需求文档位置。
## 1. 模块拆分原则
V1 按 6 个核心模块拆分:
```text
config
apps.scenarios
apps.documents
apps.chat
apps.audit
agent_core
```
拆分原则:
- Django Apps 负责业务外壳。
- Agent Core 负责 AI 能力。
- RAG、工具调用、模型适配不直接写进 View。
- 第一版不做复杂权限、多租户和完整工作流。
- 模块数量保持克制,方便复试前快速改题。
## 2. 模块文档列表
| 模块 | 文档 | 说明 |
|---|---|---|
| 配置 | `3.配置模块需求.md` | Django 项目配置、环境变量、部署配置 |
| 场景 | `4.场景模块需求.md` | 场景模板、场景配置、场景列表 |
| 文档 | `5.文档模块需求.md` | 文件上传、文件管理、RAG 入库入口 |
| 对话 | `6.对话模块需求.md` | 对话页面、Agent 调用、结果展示 |
| 审计 | `7.审计模块需求.md` | 审计日志、检索记录、工具调用记录 |
| 智能核心 | `8.智能核心模块需求.md` | RAG、工具、模型调用、结构化输出、编排 |
## 3. 模块依赖关系
```text
apps.chat
|-- depends on apps.scenarios
|-- depends on apps.audit
|-- calls agent_core
apps.documents
|-- depends on apps.scenarios
|-- calls agent_core.rag.ingest
apps.audit
|-- stores result from apps.chat / agent_core
agent_core
|-- reads scenario config object
|-- uses Chroma
|-- uses LLM Provider
|-- uses Tool Registry
```
## 4. 推荐开发顺序
建议按以下顺序开发:
1. Config 模块:保证项目可启动。
2. Scenarios 模块:展示 5 个预置场景。
3. 智能核心最小闭环:输入问题,通过 OpenAI 兼容模型接口返回结构化结果。
4. Chat 模块:页面调用 Agent Core。
5. Audit 模块:记录每次对话。
6. Documents 模块:上传文档。
7. Agent Core RAG文档入库和检索。
8. Agent Core 工具系统:增加内置工具。
9. Docker一键启动。
## 5. V1 完成标准
模块文档全部完成后V1 的实现应满足:
- 系统可以启动。
- 首页可以看到 5 个场景。
- 可以进入场景对话。
- 可以上传文档。
- 可以触发 RAG 入库。
- Agent 可以返回结构化输出。
- 工具调用和引用来源可以展示。
- 每次对话都有审计日志。
- Docker Compose 可以一键启动。

View File

@@ -1,115 +0,0 @@
# 配置模块需求文档
## 1. 模块定位
Config 模块是 Django 项目的基础配置模块,负责系统启动、路由装配、环境变量读取、静态资源、文件存储、数据库、日志和第三方组件配置。
该模块不承载业务逻辑,只负责让系统稳定启动,并为其他模块提供统一运行环境。
## 2. 模块目标
- 支持本地开发和 Docker 部署两种运行方式。
- 支持通过环境变量切换模型 API、Embedding API、调试模式和文件路径。
- 统一注册 Django Apps、模板目录、静态资源目录和上传目录。
- 提供系统级 URL 路由入口。
- 为后续扩展 PostgreSQL、Redis、Celery 等组件预留配置空间。
## 3. 职责边界
### 3.1 负责
- Django `settings.py` 配置。
- Django `urls.py` 总路由配置。
- WSGI / ASGI 启动配置。
- 环境变量读取。
- SQLite 默认数据库配置。
- 静态文件和上传文件配置。
- Chroma 本地持久化目录配置。
- LLM 与 Embedding 相关环境变量配置。
### 3.2 不负责
- 不处理具体 Agent 业务逻辑。
- 不解析场景 YAML。
- 不处理文件入库。
- 不直接调用大模型。
- 不保存审计日志。
## 4. 配置项需求
系统至少需要支持以下环境变量:
| 配置项 | 默认值 | 说明 |
|---|---|---|
| `DJANGO_SECRET_KEY` | `dev-secret-key` | Django 密钥 |
| `DJANGO_DEBUG` | `true` | 是否开启调试模式 |
| `DJANGO_ALLOWED_HOSTS` | `*` | 允许访问的主机 |
| `DATABASE_URL` | 空 | 预留配置V1 默认 SQLite不要求解析该配置 |
| `LLM_API_KEY` | 空 | 大模型 API Key |
| `LLM_BASE_URL` | `https://api.openai.com/v1` | OpenAI 兼容接口地址,可接入 OpenAI、硅基流动等兼容服务 |
| `LLM_MODEL` | `gpt-4.1-mini` | 默认模型名称 |
| `EMBEDDING_API_KEY` | 空 | Embedding API Key为空时可复用 `LLM_API_KEY` |
| `EMBEDDING_BASE_URL` | 空 | Embedding OpenAI 兼容接口地址;为空时可复用 `LLM_BASE_URL` |
| `EMBEDDING_MODEL` | `text-embedding-3-small` | 默认 Embedding 模型名称 |
| `CHROMA_PATH` | `data/chroma` | Chroma 持久化目录 |
| `UPLOAD_ROOT` | `data/uploads` | 上传文件目录 |
| `SCENARIO_CONFIG_DIR` | `configs` | 场景配置目录 |
补充要求:
- `.env.example` 仅作为模板文件,不得写入真实密钥。
- 本地直接执行 `python manage.py runserver` 时,应自动读取根目录 `.env`
- Docker 运行时可通过 `env_file` 或容器环境变量注入同一组配置;当前仓库默认由 Compose 读取 `.env`
## 5. 目录需求
系统启动时需要保证以下目录存在:
```text
data/
uploads/
chroma/
db.sqlite3
configs/
```
如果目录不存在V1 可以在初始化脚本或启动流程中创建。
## 6. 路由需求
总路由需要聚合以下模块路由:
| 路径 | 模块 | 用途 |
|---|---|---|
| `/` | `apps.scenarios` | 首页和场景列表 |
| `/chat/` | `apps.chat` | Agent 对话 |
| `/documents/` | `apps.documents` | 文件上传和文档管理 |
| `/audit/` | `apps.audit` | 审计日志查看 |
| `/admin/` | Django Admin | 后台管理 |
## 7. 启动需求
本地启动:
```bash
python manage.py migrate
python manage.py runserver
```
说明:上述命令执行前,应先准备好根目录 `.env`;当前 V1 代码会在启动时自动加载该文件。
Docker 启动:
```bash
docker compose up --build
```
## 8. 验收标准
- 项目可以通过 `python manage.py runserver` 启动。
- 项目可以通过 `docker compose up --build` 启动。
- `/admin/` 可以访问。
- 首页 `/` 可以访问。
- 环境变量可以覆盖默认 LLM 与 Embedding 配置。
- 上传目录和 Chroma 目录有明确配置。

View File

@@ -1,143 +0,0 @@
# 场景模块需求文档
## 1. 模块定位
Scenarios 模块负责管理业务 Agent 场景,是整个平台快速适配未知复试题的核心入口。
场景定义需要尽量配置化,避免把具体业务逻辑写死在 Django View 或 Agent Core 中。
## 2. 模块目标
- 读取预置场景配置。
- 展示可用业务 Agent 列表。
- 提供场景详情。
- 为 Chat 模块提供当前场景的完整配置。
- 以 YAML 配置文件作为 V1 场景唯一事实来源。
## 3. 职责边界
### 3.1 负责
- 场景模板定义。
- 场景配置文件读取。
- 场景元信息展示。
- 场景启用/禁用状态。
- 场景与文档、审计日志的关联关系。
### 3.2 不负责
- 不执行 Agent 对话。
- 不直接处理 RAG 检索。
- 不直接调用工具。
- 不直接调用大模型。
- 不解析结构化输出。
## 4. 场景模板需求
V1 预置 5 类场景模板:
| 模板 ID | 模板名称 | 适用题型 |
|---|---|---|
| `knowledge_qa` | 知识库问答助手 | SOP、制度、客服知识库、内部文档问答 |
| `document_review` | 文档审核助手 | 合同审核、制度审核、材料合规检查 |
| `ticket_assistant` | 工单处理助手 | 客服工单、售后工单、运维工单 |
| `quality_analysis` | 质量异常分析助手 | 生产质量、缺陷分析、原因定位 |
| `risk_audit` | 风险审核助手 | 财务审核、采购审核、报销审核、合同风险 |
## 5. 场景配置字段
场景配置文件使用 YAML。V1 的后台管理只管理上传文件、审计日志和示例业务数据等外围数据,不作为场景配置入口。
必填字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | string | 场景唯一标识 |
| `name` | string | 场景名称 |
| `description` | string | 场景说明 |
| `agent.role` | string | Agent 角色 |
| `agent.goal` | string | Agent 目标 |
| `agent.instructions` | list[string] | Agent 指令 |
| `agent.system_prompt` | string | 可选字段;配置后优先作为系统提示词 |
| `rag.enabled` | boolean | 是否启用 RAG |
| `tools` | list[string] | 可用工具列表 |
| `output.type` | string | 输出模板类型 |
| `audit.enabled` | boolean | 是否记录审计 |
示例:
```yaml
id: document_review
name: 文档审核助手
description: 检查合同、制度或 SOP 中的风险点和缺失项
agent:
role: 文档审核专家
goal: 根据审核规则和知识库内容输出结构化审核意见
system_prompt: ""
instructions:
- 只基于用户提供文档和知识库进行判断
- 不确定的问题必须标记为需人工复核
- 输出必须包含风险等级和修改建议
rag:
enabled: true
collection: document_review
top_k: 5
tools:
- check_required_fields
output:
type: document_review_report
audit:
enabled: true
```
## 6. 页面需求
### 6.1 场景列表页
路径:`/`
展示内容:
- 场景名称。
- 场景描述。
- 适用题型。
- 是否启用。
- 进入对话按钮。
### 6.2 场景详情页 可选
路径:`/scenarios/<scenario_id>/`
展示内容:
- Agent 角色。
- Agent 目标。
- RAG 是否启用。
- 可用工具列表。
- 输出模板类型。
V1 可以不做独立详情页,在对话页展示当前场景摘要即可。
## 7. 服务接口需求
Scenarios 模块至少需要提供以下服务函数:
```text
list_scenarios() -> list[ScenarioConfig]
get_scenario(scenario_id: str) -> ScenarioConfig
validate_scenario(config: dict) -> ValidationResult
```
## 8. 验收标准
- 首页可以展示 5 个预置场景。
- 点击场景可以进入对应对话页。
- 场景配置来自配置文件,而不是硬编码在 View 中。
- 后台管理不作为 V1 场景配置编辑入口。
- 缺失必填字段时能给出明确错误。
- Chat 模块可以根据 `scenario_id` 获取完整场景配置。

View File

@@ -1,132 +0,0 @@
# 文档模块需求文档
## 1. 模块定位
Documents 模块负责文件上传、文件管理、文本抽取和知识库入库入口。
该模块是复试题快速适配的关键模块。拿到题目材料后,用户需要能快速上传文档,并让 Agent 在对话中使用这些文档。
## 2. 模块目标
- 支持上传题目材料和知识库文件。
- 保存文件元数据。
- 支持按场景关联文件。
- 提供文档入库入口。
- 为 Agent Core 的 RAG 模块提供文件内容。
## 3. 职责边界
### 3.1 负责
- 文件上传页面。
- 文件保存。
- 文件元数据记录。
- 文件与场景关联。
- 文本抽取入口。
- 触发 RAG 入库。
### 3.2 不负责
- 不负责具体向量检索算法。
- 不负责 embedding 生成细节。
- 不负责 Agent 对话编排。
- 不负责模型回答。
## 4. 支持文件类型
V1 必须支持:
| 类型 | 扩展名 | 说明 |
|---|---|---|
| 文本文档 | `.txt` | 第一优先级,最稳定 |
| Markdown | `.md` | 适合准备知识库和规则 |
| PDF | `.pdf` | 复试常见材料格式V1 抽取纯文本 |
| Word | `.docx` | 复试常见材料格式V1 抽取段落文本 |
后续增强:
| 类型 | 扩展名 | 说明 |
|---|---|---|
| Excel | `.xlsx` | 后续可作为业务数据源或结构化表格导入 |
## 5. 数据模型需求
建议模型:`UploadedDocument`
字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | int | 主键 |
| `scenario_id` | string | 关联场景 ID |
| `original_name` | string | 原始文件名 |
| `file` | FileField | Django FileField 相对路径,不保存用户本机绝对路径 |
| `file_type` | string | 文件类型 |
| `size` | int | 文件大小 |
| `status` | string | `uploaded` / `indexed` / `failed` |
| `error_message` | text | 入库失败原因 |
| `created_at` | datetime | 上传时间 |
| `updated_at` | datetime | 更新时间 |
## 6. 页面需求
### 6.1 文件上传页
路径:`/documents/upload/`
页面元素:
- 场景选择下拉框。
- 文件选择按钮。
- 上传按钮。
- 支持类型提示。
- 上传结果提示。
### 6.2 文件列表页
路径:`/documents/`
展示内容:
- 文件名。
- 所属场景。
- 文件类型。
- 文件大小。
- 入库状态。
- 上传时间。
- 入库按钮。
## 7. RAG 入库流程
用户上传文件后,可以手动触发入库。
流程:
1. 用户上传文件。
2. 系统保存文件和元数据。
3. 用户点击入库按钮。
4. Documents 模块读取文件文本。
5. 调用 `agent_core.rag.ingest`
6. 入库成功后更新状态为 `indexed`
7. 入库失败后更新状态为 `failed` 并保存错误信息。
## 8. 文本抽取需求
V1 文本抽取策略:
- `.txt`:按 UTF-8 读取,失败时尝试系统默认编码。
- `.md`:按 UTF-8 读取,保留标题和正文。
- `.pdf`:抽取纯文本,不要求 OCR、表格还原和复杂版式理解。
- `.docx`:抽取段落、标题和普通表格文本,不要求完整保留 Word 样式。
入库失败后的文档允许重新触发入库。重新入库前需要清理或覆盖同一 `document_id` 对应的旧 chunk避免重复检索。
## 9. 验收标准
- 可以上传 `.txt``.md``.pdf``.docx` 文件。
- 上传后可以在文件列表看到记录。
- 文件可以关联到指定场景。
- 可以触发文件入库。
- 入库成功后状态变为 `indexed`
- 入库失败时页面能显示失败原因。
- 入库失败的文档可以重新入库。

View File

@@ -1,129 +0,0 @@
# 对话模块需求文档
## 1. 模块定位
Chat 模块负责 Agent 对话页面和用户交互,是复试演示时最核心的入口。
该模块接收用户问题,加载场景配置,调用 Agent Core 执行智能编排,并将结构化结果、引用来源、工具调用和审计信息展示给用户。
## 2. 模块目标
- 提供按场景进入的 Agent 对话页。
- 支持用户输入业务问题。
- 调用 Agent Core 执行完整 Agent 流程。
- 展示结构化输出。
- 展示 RAG 引用片段。
- 展示工具调用记录。
- 触发审计日志写入。
## 3. 职责边界
### 3.1 负责
- 对话页面渲染。
- 表单接收和校验。
- 当前场景上下文传递。
- 调用 Agent Core。
- 展示 Agent 返回结果。
### 3.2 不负责
- 不直接读取 YAML 场景文件。
- 不直接执行 RAG 检索。
- 不直接执行工具函数。
- 不直接调用大模型 API。
- 不直接写复杂审计细节。
## 4. 页面需求
### 4.1 Agent 对话页
路径:`/chat/<scenario_id>/`
页面区域:
- 当前场景摘要。
- 当前场景下已入库文档多选框。
- 用户问题输入框。
- 提交按钮。
- Agent 结构化输出区域。
- 引用来源区域。
- 工具调用区域。
- 执行耗时区域。
- 审计日志详情入口。
## 5. 表单需求
用户输入表单字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `message` | textarea | 是 | 用户业务问题 |
| `document_ids` | list[int] | 否 | 本次对话指定使用的已入库文档 |
校验规则:
- 输入不能为空。
- 输入长度建议不超过 4000 字。
- 如果场景不存在,需要返回明确错误。
- `document_ids` 只能包含当前场景下状态为 `indexed` 的文档。
- 未选择文档时,默认使用当前场景下全部已入库文档作为 RAG 范围。
## 6. Agent 执行流程
Chat 模块调用 Agent Core 的流程:
```text
用户提交问题
校验 scenario_id 和 message
获取场景配置
调用 `run_agent(scenario_config, user_input, options=None)`
获取 AgentResult
调用 Audit 模块记录日志
渲染结果页面
```
## 7. AgentResult 展示需求
Agent Core 返回结果建议包含:
| 字段 | 说明 |
|---|---|
| `answer` | 自然语言回答 |
| `structured_output` | 结构化结果 |
| `references` | RAG 引用来源 |
| `tool_calls` | 工具调用记录 |
| `raw_output` | 模型原始输出 |
| `latency_ms` | 执行耗时 |
| `error` | 错误信息 |
页面需要优先展示结构化结果。如果结构化解析失败,则展示自然语言回答和错误提示。
## 8. 错误处理需求
需要处理以下错误:
| 错误 | 页面行为 |
|---|---|
| 场景不存在 | 显示场景不存在 |
| 用户输入为空 | 显示表单错误 |
| LLM API Key 缺失 | 显示模型配置缺失 |
| RAG 检索失败 | 显示检索失败,但允许模型基于已有信息回答 |
| 工具调用失败 | 显示工具失败信息,并继续生成结果 |
| 结构化解析失败 | 展示原始回答,并提示结构化解析失败 |
## 9. 验收标准
- 可以从场景列表进入对话页。
- 可以提交问题并获得 Agent 输出。
- 页面能展示结构化结果。
- 页面能展示引用来源。
- 页面能展示工具调用记录。
- 执行失败时有可理解的错误提示。
- 每次对话都会产生审计日志。

View File

@@ -1,143 +0,0 @@
# Audit 模块需求文档
## 1. 模块定位
Audit 模块负责记录和展示 Agent 执行过程,是项目体现企业级能力的重要模块。
复试演示时,审计日志用于证明系统不是黑盒问答,而是可以追踪输入、检索、工具调用、模型输出和执行耗时。
## 2. 模块目标
- 记录每次 Agent 对话。
- 记录 RAG 检索片段。
- 记录工具调用详情。
- 记录模型输出和结构化结果。
- 提供审计日志列表和详情页。
- 支持按场景查看日志。
## 3. 职责边界
### 3.1 负责
- 审计日志数据模型。
- 日志写入服务。
- 日志列表页面。
- 日志详情页面。
- 工具调用记录展示。
- RAG 引用记录展示。
### 3.2 不负责
- 不执行 Agent。
- 不执行工具调用。
- 不执行 RAG 检索。
- 不参与模型生成。
- 不做复杂权限控制。
## 4. 数据模型需求
建议模型:`AgentAuditLog`
字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | int | 主键 |
| `scenario_id` | string | 场景 ID |
| `scenario_name` | string | 场景名称 |
| `user_input` | text | 用户输入 |
| `retrieved_chunks` | JSON | 检索片段 |
| `tool_calls` | JSON | 工具调用记录 |
| `structured_output` | JSON | 结构化输出 |
| `final_answer` | text | 最终回答 |
| `raw_output` | text | 模型原始输出 |
| `model_name` | string | 模型名称 |
| `latency_ms` | int | 执行耗时 |
| `status` | string | `success` / `failed` |
| `error_message` | text | 错误信息 |
| `created_at` | datetime | 创建时间 |
## 5. 日志写入需求
Audit 模块需要提供服务函数:
```text
create_audit_log(
scenario_id,
scenario_name,
user_input,
agent_result
) -> AgentAuditLog
```
写入规则:
- Agent 成功时,记录完整结果。
- Agent 失败时,也要记录用户输入、场景和错误信息。
- RAG 片段和工具调用使用 JSON 保存。
- 不记录 API Key 等敏感配置。
## 6. 页面需求
### 6.1 审计日志列表页
路径:`/audit/`
展示字段:
- 日志 ID。
- 场景名称。
- 用户输入摘要。
- 状态。
- 模型名称。
- 执行耗时。
- 创建时间。
- 详情入口。
### 6.2 审计日志详情页
路径:`/audit/<log_id>/`
展示内容:
- 用户输入。
- 最终回答。
- 结构化输出。
- RAG 检索片段。
- 工具调用记录。
- 模型名称。
- 执行耗时。
- 错误信息。
## 7. 检索片段展示需求
每个引用片段建议包含:
| 字段 | 说明 |
|---|---|
| `source` | 来源文件名 |
| `chunk_id` | 片段 ID |
| `content` | 片段内容 |
| `score` | 相似度分数 |
## 8. 工具调用展示需求
每次工具调用建议包含:
| 字段 | 说明 |
|---|---|
| `tool_name` | 工具名称 |
| `arguments` | 调用参数 |
| `result` | 工具结果 |
| `success` | 是否成功 |
| `error` | 错误信息 |
## 9. 验收标准
- 每次对话成功后都会生成审计日志。
- Agent 执行失败时也会生成失败日志。
- 审计列表可以查看所有日志。
- 审计详情可以查看用户输入、检索片段、工具调用和最终输出。
- 日志中不保存 API Key。
- 可以根据日志解释一次 Agent 输出的依据。

View File

@@ -1,225 +0,0 @@
# 智能核心模块需求文档
## 1. 模块定位
Agent Core 是系统的智能能力核心,负责根据场景配置完成 RAG 检索、工具调用、大模型调用和结构化输出。
该模块应保持独立于 Django View方便后续迁移为独立服务或接入 OpenAI Agents SDK、Dify 等外部编排引擎。
## 2. 模块目标
- 提供统一 Agent 执行入口。
- 根据场景配置组织 Prompt。
- 支持 RAG 检索。
- 支持工具注册与调用。
- 支持 OpenAI API 兼容的 LLM 与 Embedding 调用,可自主接入 OpenAI、硅基流动等兼容服务。
- 支持结构化输出解析。
- 返回可审计的 AgentResult。
## 3. 职责边界
### 3.1 负责
- Agent 编排。
- 场景配置对象消费。
- RAG 入库和检索核心逻辑。
- 工具注册和工具执行。
- LLM Provider 适配。
- 输出结构化解析。
- 生成 AgentResult。
### 3.2 不负责
- 不渲染页面。
- 不直接处理 Django 表单。
- 不直接保存 Django Model。
- 不管理用户登录。
- 不负责 Docker 部署。
## 4. 子模块划分
```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
```
## 5. Orchestrator 需求
`orchestrator.py` 提供统一入口:
```text
run_agent(
scenario_config,
user_input,
options=None
) -> AgentResult
```
执行流程:
1. 读取场景配置。
2. 根据配置判断是否启用 RAG。
3.`scenario_id` 和可选 `document_ids` 检索相关知识片段。
4. 根据配置加载可用工具。
5. 构造系统提示词。
6. 调用大模型。
7. 执行必要的工具调用。
8. 解析结构化输出。
9. 返回 AgentResult。
V1 可以使用轻量 Orchestrator不强制引入完整 Agent SDK。
## 6. RAG 需求
### 6.1 入库
`rag/ingest.py` 负责:
- 接收文档文本。
- 文本切分。
- 通过 OpenAI 兼容 Embedding Provider 生成 embedding。
- 写入 Chroma。
- 保存 metadata。
metadata 至少包含:
- `scenario_id`
- `document_id`
- `source_file`
- `chunk_id`
- `created_at`
### 6.2 检索
`rag/retriever.py` 负责:
- 根据用户问题检索相关片段。
- 支持按 `scenario_id` 过滤。
- 支持按本次对话选择的 `document_ids` 过滤;未选择时使用当前场景全部已入库文档。
- 返回 top_k 结果。
- 返回内容、来源和分数。
## 7. 工具系统需求
`tool_registry.py` 负责工具注册、查找和执行。
V1 内置工具:
| 工具名 | 说明 |
|---|---|
| `calculate_rate` | 计算通过率、缺陷率、占比等 |
| `query_demo_records` | 查询模拟业务数据 |
| `check_required_fields` | 检查必填项是否缺失 |
| `generate_action_items` | 生成行动项清单 |
工具执行结果需要统一格式:
```json
{
"tool_name": "calculate_rate",
"success": true,
"arguments": {},
"result": {},
"error": ""
}
```
## 8. LLM Provider 需求
`llm_provider.py` 负责模型调用。
V1 需要支持 OpenAI API 兼容 LLM 接口:
- `LLM_API_KEY`
- `LLM_BASE_URL`
- `LLM_MODEL`
接口需要隐藏不同模型供应商差异,对 Orchestrator 暴露统一方法:
```text
generate(messages, response_format=None) -> LLMResponse
```
Embedding 也通过 OpenAI 兼容接口接入:
- `EMBEDDING_API_KEY`
- `EMBEDDING_BASE_URL`
- `EMBEDDING_MODEL`
当 Embedding 专用 Key 或 Base URL 为空时,可以复用 LLM 的 Key 和 Base URL。RAG 入库和检索必须通过真实 embedding 与 Chroma 完成,模拟 embedding 或简单文本匹配只能作为开发阶段临时桩,不计入 V1 验收。
## 9. 结构化输出需求
`structured_output.py` 负责将模型输出转换为业务结构。
V1 输出类型:
- `general_answer`
- `document_review_report`
- `ticket_response`
- `quality_report`
- `risk_audit_report`
解析策略:
- 优先要求模型直接返回 JSON。
- JSON 解析成功则展示结构化结果。
- JSON 解析失败则保留原始输出,并返回解析错误。
## 10. AgentResult 需求
Agent Core 最终返回统一结果对象。
字段:
| 字段 | 说明 |
|---|---|
| `answer` | 最终自然语言回答 |
| `structured_output` | 结构化输出 |
| `references` | RAG 引用片段 |
| `tool_calls` | 工具调用记录 |
| `raw_output` | 模型原始输出 |
| `model_name` | 模型名称 |
| `latency_ms` | 执行耗时 |
| `status` | `success` / `failed` |
| `error` | 错误信息 |
## 11. Adapter 扩展需求
V1 默认使用 `LightweightOrchestrator`
后续可扩展:
- OpenAI Agents SDK Adapter。
- Dify API Adapter。
- LangGraph Adapter。
Adapter 需要保持同样输入输出:
```text
run_agent(scenario_config, user_input, options=None) -> AgentResult
```
## 12. 验收标准
- Chat 模块可以调用 Agent Core 获得统一 AgentResult。
- RAG 可以按场景检索知识片段。
- RAG 可以按本次对话选择的文档范围检索知识片段。
- 工具调用结果可以记录并返回。
- LLM 与 Embedding 配置可以通过环境变量切换。
- 结构化输出解析失败时不会导致整个流程崩溃。
- Agent Core 不依赖 Django View。