基于 DSL(领域特定语言)驱动的智能客服Agent系统,支持自定义对话流程、数据库集成和LLM智能交互。
DSL-Driven Agent 是一个基于领域特定语言的多业务场景智能客服系统。系统核心是一套自定义的DSL脚本语言及其解释器,能够描述客服机器人的应答逻辑和业务流程。通过集成大型语言模型(LLM)API,系统能够对用户的自然语言输入进行意图识别和槽位提取,从而驱动DSL脚本的解释执行,实现智能化的人机交互。
核心特性:
- 🎯 自定义 DSL:简洁的语法定义对话流程,支持状态机、控制流和内置函数
- 🤖 LLM 集成:支持 OpenAI、Kimi、通义千问等 LLM 服务,实现智能意图识别
- 🗄️ 数据库集成:PostgreSQL 支持,实现数据持久化和业务数据查询
- 🔐 用户认证:JWT 认证机制,支持用户注册登录和会话管理
- 🌐 多运行模式:支持 CLI 命令行、Web API 和前端界面三种运行方式
- 变量声明和类型系统(string, int, float, bool)
- 控制流语句(if/else, switch/case, while循环)
- 关系运算符(==, !=, <, >, <=, >=)和逻辑运算符(&&, ||, !)
- 内置函数(say, input, goto, llm_chat)
- AI 能力调用(intent, extract_slot)
- 数据库操作(db_get, db_query)
- 状态管理(state blocks)
- 意图识别(LLM 驱动)
- 槽位提取(实体识别)
- 会话持久化和历史记录
- 用户数据隔离
- RESTful API 接口
- Web 前端界面(毛玻璃效果)
- 完整测试覆盖(pytest)
- Python 3.11+
- FastAPI - 现代Web框架
- SQLAlchemy - ORM框架
- PostgreSQL - 关系型数据库
- OpenAI API - LLM集成
- JWT - 身份认证
- Pytest - 测试框架
- Vanilla JavaScript - 原生JS
- HTML5/CSS3 - 现代Web标准
- Fetch API - HTTP请求
- Python 3.11+
- PostgreSQL 12+
- UV(Python 包管理器)
如果还未安装 UV:
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"git clone https://github.com/Yokumii/DSL-driven-Agent.git
cd DSL-driven-Agent使用 UV 安装项目依赖:
# 同步依赖
uv sync
# 如果需要开发依赖
uv sync --all-extras创建 .env 文件:
cp .env.example .env编辑 .env 文件,配置必要的环境变量:
# 数据库配置
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/dsl_agent
# LLM 配置(可选)
LLM_PROVIDER=openai
OPENAI_API_KEY=your-api-key-here
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
# JWT 认证
JWT_SECRET_KEY=your-secret-key-here
JWT_ALGORITHM=HS256
# 服务器配置
SERVER_HOST=127.0.0.1
SERVER_PORT=8000# 创建数据库
createdb dsl_agent
# 初始化校园助手数据(包含学生、课程、图书等测试数据)
uv run python init_campus_db.py执行后会自动创建以下测试数据:
- 默认用户(testuser/password123)
- 10个学生信息
- 10门课程信息
- 选课记录
- 30本图书信息
- 借阅记录
本项目支持三种运行模式:
直接执行 DSL 脚本,适合测试和调试:
uv run python main.py examples/campus_assistant.dsl交互示例:
🎓 欢迎使用智能校园助手!
请输入您的学号(例如: 2021001):2021001
您好,张三!
请问需要什么帮助?您可以:
1. 查询课表
2. 查看成绩
3. 借阅图书
4. 查看通知
...
启动 FastAPI 后端服务:
# 使用 main.py 启动
uv run python main.py
# 或者直接使用 uvicorn(开发模式,支持热重载)
uv run uvicorn src.api.main:app --reload --host 127.0.0.1 --port 8000API 服务地址:
- 主页:http://localhost:8000
- API 文档(Swagger UI):http://localhost:8000/docs
- 健康检查:http://localhost:8000/api/v1/health
完整的 Web 应用模式,包含图形化界面。
uv run python main.py# 在项目根目录执行
uv run python -m http.server 8080在浏览器中打开:http://localhost:8080/frontend/web/
DSL-driven-Agent/
├── main.py # 主入口(CLI/API 启动)
├── init_campus_db.py # 数据库初始化脚本
├── pyproject.toml # 项目配置和依赖
├── .env # 环境变量配置
├── pytest.ini # pytest 配置
├── run_tests.sh # 测试运行脚本
│
├── src/ # 源代码
│ ├── api/ # FastAPI 应用
│ │ ├── main.py # API 主入口
│ │ ├── routes.py # 对话 API 路由
│ │ ├── auth.py # JWT 认证中间件
│ │ ├── auth_routes.py # 认证 API 路由
│ │ └── models.py # Pydantic 模型
│ │
│ ├── db/ # 数据库模块
│ │ ├── database.py # 数据库连接
│ │ └── models.py # SQLAlchemy 模型
│ │
│ ├── handlers/ # 业务处理器
│ │ ├── llm_handler.py # LLM 交互处理
│ │ └── db_handler.py # 数据库操作处理
│ │
│ ├── services/ # 业务逻辑
│ │ ├── dialog_manager.py # 对话管理
│ │ ├── llm_service.py # LLM 服务封装
│ │ ├── auth_service.py # 认证服务
│ │ ├── conversation_service.py # 对话历史服务
│ │ └── session_store.py # 会话存储
│ │
│ ├── utils/ # 工具模块
│ │ ├── config.py # 配置管理
│ │ └── logger.py # 日志系统
│ │
│ ├── lexer.py # 词法分析器
│ ├── parser.py # 语法分析器
│ ├── ast_nodes.py # AST 节点定义
│ └── executor.py # DSL 执行器
│
├── frontend/ # 前端代码
│ └── web/ # Web 客户端
│ ├── index.html # 主页面
│ ├── app.js # JavaScript 逻辑
│ ├── style.css # 样式文件
│ └── ls1-icn1.png # 图标资源
│
├── examples/ # DSL 示例脚本
│ └── campus_assistant.dsl # 校园助手场景
│
├── tests/ # 测试文件
│ ├── conftest.py # pytest 配置
│ ├── test_lexer.py # 词法分析器测试
│ ├── test_parser.py # 语法分析器测试
│ ├── test_executor.py # 执行器测试
│ ├── test_api.py # API 测试
│ └── test_services.py # 服务层测试
│
├── config/ # 配置文件
│ ├── config.yaml # 应用配置
│ └── logging.yaml # 日志配置
│
├── logs/ # 日志文件(自动生成)
│ ├── app.log
│ └── error.log
│
└── docs/ # 文档
├── DSL_Syntax.md # DSL 语法手册
├── report.md # 项目报告(Markdown)
└── report.pdf # 项目报告(PDF)
应用主配置文件:
app:
name: "DSL-Driven Agent"
version: "1.0.0"
debug: false
server:
host: "127.0.0.1"
port: 8000
reload: true # 开发模式热重载
workers: 1 # 工作进程数
cors:
enabled: true
allow_origins: ["*"]
allow_methods: ["*"]
allow_headers: ["*"]
database:
pool_size: 5
max_overflow: 10
executor:
max_iterations: 10000 # 循环最大迭代次数
llm:
timeout: 30 # LLM API 超时时间
max_retries: 3 # 最大重试次数敏感配置通过环境变量管理:
# 数据库
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/dsl_agent
# LLM 服务
LLM_PROVIDER=openai # openai | kimi | qwen
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
# JWT 认证
JWT_SECRET_KEY=your-secret-key-here-change-in-production
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
# 日志
LOG_LEVEL=INFO
LOG_FILE_PATH=logs/app.log# 安装依赖
uv sync
# 添加新依赖
uv add <package-name>
# 添加开发依赖
uv add --dev <package-name>
# 运行脚本
uv run python <script.py>
# 运行测试
uv run pytest
# 激活虚拟环境(可选)
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows项目使用 pytest 进行测试,配置文件为 pytest.ini。
# 运行所有测试
uv run pytest
# 使用测试脚本(包含覆盖率报告)
./run_tests.sh
# 运行特定测试文件
uv run pytest tests/test_executor.py
# 运行测试并显示详细输出
uv run pytest -v
# 运行测试并显示覆盖率
uv run pytest --cov=src --cov-report=html测试覆盖率:
- 总体覆盖率:69%
- 测试用例数:102个
- 所有测试通过
项目遵循以下代码规范:
- Python 代码:PEP 8 规范
- 注释:使用中文,简洁明了
- 类型提示:使用 Python typing
- 文档字符串:保留核心说明,避免冗余
- 在
examples/目录创建新的.dsl文件 - 按照 DSL 语法编写脚本(参考
docs/DSL_Syntax.md) - 如需数据库支持,在
src/db/models.py添加模型 - 在
init_campus_db.py或创建新的初始化脚本添加测试数据 - 测试脚本:
uv run python main.py examples/your_script.dsl
version 1.0.0
# 变量声明
var (
user_name string
user_id string
credits int
)
# 状态定义
state main {
say("欢迎使用系统")
input(user_input)
intent(user_input, user_intent)
switch user_intent {
"query" goto(query_state)
"help" goto(help_state)
default goto(main)
}
}
state query_state {
db_get("students", "stu")
say("您的学分:" + stu_credits)
goto(main)
}| 函数 | 说明 | 示例 |
|---|---|---|
say(text) |
输出文本 | say("欢迎") |
input(var) |
获取用户输入 | input(user_name) |
goto(state) |
跳转状态 | goto(menu) |
intent(input, result) |
意图识别 | intent(text, intent_type) |
extract_slot(input, slot, result) |
槽位提取 | extract_slot(text, "学号", id) |
db_get(table, prefix) |
查询单条记录 | db_get("students", "stu") |
db_query(table, limit, prefix) |
查询多条记录 | db_query("courses", 10, "c") |
llm_chat(input, output) |
LLM 对话 | llm_chat(question, answer) |
完整语法参考:docs/DSL_Syntax.md
POST /api/v1/auth/register
Content-Type: application/json
{
"username": "testuser",
"email": "user@example.com",
"password": "password123"
}POST /api/v1/auth/login
Content-Type: application/x-www-form-urlencoded
username=testuser&password=password123返回:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "bearer"
}POST /api/v1/conversations
Authorization: Bearer <token>
Content-Type: application/json
{
"scenario_name": "campus_assistant",
"use_llm": true
}POST /api/v1/conversations/{conversation_id}/messages
Authorization: Bearer <token>
Content-Type: application/json
{
"user_input": "查询课表"
}GET /api/v1/conversations/{conversation_id}/messages
Authorization: Bearer <token>DELETE /api/v1/conversations/{conversation_id}
Authorization: Bearer <token>完整的 API 文档访问:http://localhost:8000/docs
See the LICENSE for more details.