# JRXML 生成代理 — 架构文档 ## 概览 一个三层架构的桌面应用,通过自然语言多轮对话帮助非技术用户创建 JasperReports 模板(JRXML)。核心流程:用户输入 → 意图识别 → 模板检索 → LLM 生成/修改 → 自动验证修正 → 输出可编译的 JRXML。 ``` ┌──────────────────────────────────────────────────────────────┐ │ Vue 3 + Vite 前端 (:5173) │ │ frontend/ (聊天界面 + SSE 流式) │ │ 聊天界面 / 会话管理 / JRXML 预览 / 下载 / 快捷操作 │ └─────────────────────┬────────────────────────────────────────┘ │ HTTP + SSE (/api/*) ▼ ┌──────────────────────────────────────────────────────────────┐ │ FastAPI SSE 后端 (:8000) │ │ api_server.py │ │ REST: /api/sessions, /api/upload, /api/.../download/latest │ │ SSE: /api/sessions/{id}/chat (流式推送) │ │ 事件: node_start | node_complete | stream_token │ │ agent_complete | agent_error │ └─────────────────────┬────────────────────────────────────────┘ │ run_agent(user_input) ▼ ┌──────────────────────────────────────────────────────────────┐ │ LangGraph 状态机 (agent/) │ │ │ │ load_session → process_input → manage_context │ │ → save_state_snapshot → classify_intent │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ │ │ retrieve modify_jrxml preview consult undo/reset │ │ │ │ /export │ │ ▼ ▼ │ │ generate save_session │ │ │ │ │ │ └────┬─────┘ │ │ ▼ │ │ (jrxml_reorder 自动规范化元素顺序) │ │ ▼ │ │ validate ──(fail)──► explain_error ──► correct_jrxml │ │ │ ▲ │ │ │ (pass) └──(retry` 声明) - `` 是否含有效 SQL SELECT - `` 必需属性(pageWidth, pageHeight, name) 2. **XSD Schema 校验**(可选): - 需要 `validation_service/schemas/jasperreport_7_0_6.xsd` 文件 - 使用 `lxml.etree.XMLSchema` 进行完整 schema 校验 ### 会话持久化(backend/session.py) ``` sessions/{session_id}.json { "session_id": "abc123def456", "session_name": "员工名册报表", "created_at": "2026-05-19T09:00:00+00:00", "updated_at": "2026-05-19T09:30:00+00:00", "agent_state": { ... } // 完整的 AgentState 字段 } ``` ## 关键 Prompt 设计 | Prompt | 用途 | 输出约束 | |--------|------|---------| | `INTENT_CLASSIFY_PROMPT` | 8 分类意图识别 | 只输出意图名称 | | `INITIAL_GENERATION_PROMPT` | 首次生成 JRXML | 只输出 JRXML,无 markdown | | `MODIFICATION_PROMPT` | 修改现有 JRXML | 只输出完整 JRXML | | `CORRECTION_PROMPT` | 自动修正错误 | 只输出修复后 JRXML | | `EXPLAIN_PROMPT` | 错误转人话 | 2-3 句话 | | `COMPRESSION_PROMPT` | 对话压缩 | ≤200 字摘要 | | `CONSULT_PROMPT` | 咨询解答 | 简洁中文 | ## 配置参数(.env) | 参数 | 默认值 | 说明 | |------|--------|------| | `LLM_BACKEND` | cloud | cloud / local | | `LLM_PROVIDER` | openai | openai / anthropic | | `OPENAI_API_KEY` | — | API 密钥 | | `OPENAI_BASE_URL` | https://api.openai.com/v1 | API 端点 | | `LLM_MODEL` | gpt-4o | 模型名称 | | `LOCAL_LLM_MODEL` | qwen2.5-coder:7b | Ollama 模型 | | `EMBED_BACKEND` | local | local / cloud | | `LOCAL_EMBED_MODEL` | Qwen/Qwen3-Embedding-0.6B | 本地嵌入模型 | | `VALIDATION_SERVICE_URL` | http://localhost:8001/validate | 验证端点 | | `CHROMA_PERSIST_DIR` | ./db/chroma | ChromaDB 路径 | | `MAX_RETRY` | 5 | 自动修正最大尝试次数 | | `CONTEXT_MAX_TOKENS` | 6000 | 触发压缩的 token 阈值 | | `CONTEXT_KEEP_RECENT` | 4 | 保留最近 N 轮完整对话 | | `SESSIONS_DIR` | ./sessions | 会话 JSON 存储目录 | | `HISTORY_MAX_SNAPSHOTS` | 10 | 撤销快照保留数量 | ## 启动流程 ```bash # 1. 安装依赖 pip install -r requirements.txt # 2. 配置环境 cp .env.example .env # 编辑 .env 填入 API 密钥 # 3. 初始化知识库(预下载嵌入模型) python scripts/init_kb.py --download-model # 4. 启动验证服务(终端 1) python -m uvicorn validation_service.main:app --port 8001 --host 0.0.0.0 # 5. 启动 Streamlit 界面(终端 2) STREAMLIT_SERVER_HEADLESS=true streamlit run app.py --server.port 8501 # 6. 访问 http://localhost:8501 ``` ## 测试 ```bash pytest tests/test_validation.py -v # 验证服务单元测试 pytest tests/test_agent.py -v # 代理集成测试 pytest tests/ -v # 全部测试 ``` ## 技术栈 | 层 | 技术 | |----|------| | UI | Streamlit 1.57 | | 工作流引擎 | LangGraph 1.2 | | LLM 接入 | Anthropic SDK / LangChain-OpenAI / LangChain-Ollama | | 向量数据库 | ChromaDB 1.5 | | 嵌入模型 | Sentence-Transformers (HuggingFace) | | 验证服务 | FastAPI + lxml XMLSchema | | HTTP 客户端 | httpx | | Token 计算 | tiktoken | | 持久化 | JSON 文件 + ChromaDB PersistentClient |