# ai-ticket-agent
**Repository Path**: wmx2671/ai-ticket-agent
## Basic Information
- **Project Name**: ai-ticket-agent
- **Description**: 基于 FastAPI、Groq Tool Calling、TF-IDF RAG 与 SQLite 构建的智能工单 Agent,支持自然语言 CRUD、会话隔离、删除二次确认,并提供 Pytest API 测试及 Selenium 端到端测试。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2026-08-11
- **Last Updated**: 2026-10-08
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# AI Ticket Agent
一个基于 FastAPI、SQLAlchemy、SQLite 与 LLM Tool Calling 构建的智能工单 Agent。
项目既提供 REST API,也支持通过自然语言创建、查询、搜索、更新和删除工单。模型负责理解意图和选择工具;Python 工具负责执行真实数据库操作。删除操作使用后端二次确认,避免模型或模糊回复直接删除数据。
> 当前为可本地运行的工程化 MVP,已提供 Web 操作界面、Swagger UI、REST API、命令行入口和基于 TF-IDF 的本地 RAG 知识库。
## 功能
- 创建、查询、列表查询、关键词搜索和 PATCH 部分更新工单
- LLM Tool Calling 与最多 5 轮的 Agent 工具调用循环
- 按 `session_id` 隔离对话记录和待确认删除状态
- 会话历史裁剪,降低 Token 与内存持续增长风险
- 删除工单的 Human-in-the-loop 确认与取消流程
- `priority`、`status` 的 API 枚举校验
- Groq 限流、超时、连接和工具参数异常处理
- 本地 RAG 知识库检索(IT SOP / FAQ)
- Web 工单创建、列表展示、关键词过滤、Agent 对话与删除确认交互
- pytest 单元/API测试与 Selenium Chrome 端到端测试
## 技术栈
- Python 3.12
- FastAPI、Pydantic、Uvicorn
- SQLAlchemy + SQLite
- Groq API(`openai/gpt-oss-20b`)
- pytest、Selenium、Chrome Headless
## 架构
```text
Web UI / Swagger / API Client
│
▼
FastAPI
│
▼
Agent Service ───── Session Memory
│
▼
Groq LLM
│
▼
Tool Calling Loop(最多 5 轮)
│ │
▼ ▼
Ticket Tools RAG Search Tool
│ │
▼ ▼
SQLAlchemy/SQLite TF-IDF/Knowledge Base
```
LLM 不直接操作数据库。它只产生 Tool Call;`tools.py` 中的 Python 函数执行实际业务逻辑并将真实结果返回给模型。
## 删除确认流程
```text
用户:删除 5 号工单
│
▼
LLM:request_delete_ticket(ticket_id=5)
│
▼
后端:保存 pending_action,并询问确认
│
┌────┴────┐
▼ ▼
确认 取消
│ │
▼ ▼
真实删除 清除 pending_action
```
示例:
```text
用户:删除 5 号工单
助手:确认删除 5 号工单吗?回复“确认”或“取消”。
用户:确认
助手:已成功删除 5 号工单。
```
## 快速开始
### 1. 创建虚拟环境并安装依赖
Windows PowerShell:
```powershell
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --no-cache-dir -r requirements.txt
```
### 2. 配置环境变量
复制 `.env.example` 为 `.env`,并填写 Groq API Key:
```env
GROQ_API_KEY=your_groq_api_key
```
不要提交 `.env` 或真实 API Key。
### 3. 启动服务
```powershell
python -m uvicorn main:app --reload
```
- API 根路径:
- Swagger UI:
`main.py` 是轻量启动入口,具体 API、Agent 与数据库实现集中在 `app/`。如需在终端手动体验 Agent,可运行:
```powershell
python -m scripts.manual_agent
```
## RAG 知识库
将 UTF-8 编码的 `.md` 或 `.txt` 文档放入 `knowledge_base/`。Agent 遇到故障排查、SOP、FAQ 等问题时会调用 `search_knowledge_base` 工具,检索相关片段后再回答。当前实现使用本地 TF-IDF 检索,无需额外服务或 API Key;适合 MVP 和小型知识库。
检索过程包括:读取 Markdown/TXT 文档、重叠切片、分词、计算 TF-IDF 权重、余弦相似度排序以及 Top-K 结果返回。Groq 负责决定是否调用检索工具,并基于检索内容组织最终回答。
## API
```text
POST /tickets
GET /tickets
GET /tickets/{ticket_id}
PATCH /tickets/{ticket_id}
DELETE /tickets/{ticket_id}
POST /chat
```
创建工单:
```http
POST /tickets
Content-Type: application/json
{
"title": "办公室网络无法连接",
"priority": "high"
}
```
部分更新:
```http
PATCH /tickets/1
Content-Type: application/json
{
"status": "processing"
}
```
- `priority`:`low`、`normal`、`high`
- `status`:`pending`、`processing`、`completed`
聊天接口:
```http
POST /chat
Content-Type: application/json
{
"session_id": "demo-user",
"message": "创建一个标题为 VPN 无法连接的高优先级工单"
}
```
可使用自然语言,例如:
```text
查询 3 号工单
搜索打印机相关工单
把 3 号工单状态改成 completed
删除 3 号工单
```
## 测试
默认运行单元、API、Agent与RAG测试,不启动浏览器:
```powershell
python -m pytest -q
```
单独运行 Selenium 端到端测试:
```powershell
python -m pytest -q -m e2e -o "addopts=--basetemp=.test-tmp-e2e -p no:cacheprovider"
```
当前使用 Python 3.12.10 与本机 Chrome 的验证结果:
```text
11 passed, 2 deselected # 默认测试
2 passed, 11 deselected # Selenium E2E
```
当前测试覆盖:
- 创建、查询和 PATCH 部分更新
- 删除请求不会立即删除
- 确认删除与取消删除
- 不同会话之间的删除确认隔离
- 会话历史裁剪
- Tool Call 消息序列化与多轮历史复用
- TF-IDF 知识库相关片段检索
- Web关键区域加载
- 从创建弹层提交工单、刷新列表并按关键词过滤
API 测试使用独立的内存 SQLite 数据库;Selenium测试会启动临时Uvicorn服务和独立SQLite文件。Agent测试会Mock LLM,以上自动化测试均不会产生真实Groq请求,也不会修改本地 `tickets.db`。
## 项目结构
```text
ai-ticket-agent/
├── main.py # Uvicorn/ASGI 轻量启动入口
├── app/ # 正式应用源码
│ ├── api.py # FastAPI 路由与异常处理
│ ├── agent_service.py # Agent Loop、Tool Calling、会话与确认流程
│ ├── tools.py # 工单业务工具
│ ├── models.py # SQLAlchemy 模型
│ ├── database.py # 数据库连接与 Session
│ ├── llm_service.py # Groq 客户端配置
│ └── rag_service.py # 文档切片、TF-IDF 与 Top-K 检索
├── knowledge_base/ # 本地 IT SOP / FAQ 文档
├── data/ # 本地运行数据(SQLite 文件不提交)
├── static/ # Web 页面、样式与交互脚本
├── tests/ # pytest 单元/API/Agent/RAG测试
│ └── e2e/ # Selenium Chrome端到端测试
├── scripts/ # 手动演示和调试入口
│ ├── manual_agent.py # 命令行体验完整 Agent
│ ├── manual_llm.py # 单独验证 Groq 调用
│ └── manual_tools.py # 单独验证业务工具
├── requirements.txt
├── pytest.ini
├── .env.example
└── .gitignore
```
## 当前限制与下一步
- 会话状态保存在进程内存,重启后会丢失,多 worker 之间也不能共享。
- 尚未实现用户认证与权限控制,不应直接暴露到公网。
- REST `DELETE /tickets/{ticket_id}` 是直接删除的管理接口;只有 `/chat` 的删除流程包含二次确认。
- SQLite 适合本地开发和演示,生产环境建议迁移到 PostgreSQL 或 MySQL。
- TF-IDF 属于词法检索,对同义表达和复杂语义的召回能力有限;当前方案适合小型知识库基线。
- Web 页面保持原生HTML/CSS/JavaScript MVP,没有引入组件框架或复杂前端状态管理。
- 当前没有远程 CI、覆盖率门禁和并发性能测试。
后续可以增加向量检索对比评测、用户认证、持久化会话、覆盖率门禁和 Agent 任务成功率评测。
## 项目说明
本项目主要用于 AI Agent 工程学习、技术实践与作品展示。