# 使用 JSON 配置在 Python 中管理多步对话
构建调查、入门流程和复杂向导通常会导致条件逻辑堆积,这些逻辑难以维护和扩展。dialog-engine 库提供了一种声明式替代方案:对话结构、字段可见性规则和导航均在 JSON 或 YAML 中定义。引擎会根据会话上下文自动计算可用步骤,从而消除为每个场景编写嵌套结构的需求。
构建向导的声明式方法
传统多步表单实现需要显式状态管理。开发者需要手动跟踪当前阶段、检查转换条件并组装界面。当业务逻辑变更或添加新分支时,代码很快就会变得杂乱,成为一堆 if 语句和 match 块的意大利面条式代码。dialog-engine 则反其道而行之:对话成为数据结构,而非指令序列。
配置文件包含一个步骤数组。每项定义 ID、输入类型、文本以及可选验证参数。引擎不解释字段类型——text、choice、photo 或自定义值通过配置和渲染层之间的约定处理。这允许使用同一文件构建 Telegram 机器人、Web 界面或控制台工具。
{
"steps": [
{ "id": "name", "type": "text", "text": "What is your name?" },
{ "id": "plan", "type": "choice", "text": "Choose a plan",
"choices": { "free": "Free", "pro": "Professional" } },
{ "id": "company_inn", "type": "text", "text": "Enter the company tax ID",
"show_when": { "field": "plan", "equals": "pro" } },
{ "id": "confirm", "type": "text", "text": "Is everything correct? Sending!" }
]
}
核心安装无需外部依赖。根据需要通过 extras 安装额外模块,保持基础包轻量级。
pip install dialog-engine
pip install dialog-engine[validation,yaml,aiogram]
条件可见性和导航机制
引擎的核心特性是依赖上下文的路由。不必硬编码转换,它使用用户响应的字典来计算下一个和上一个可见步骤的索引。隐藏阶段会自动从进度条和导航逻辑中排除,确保位置计数准确,例如“第 2 步,共 3 步”。
可见性条件通过 show_when 和 skip_when 字段设置。它支持基本比较运算符和存在性检查,还支持 any_of 和 all_of 等复合规则,用于复杂业务逻辑。规则可以无深度限制地嵌套。
{
"skip_when": {
"any_of": [
{ "field": "plan", "equals": "free" },
{ "field": "age", "lt": 18 }
]
}
}
Python API 提供了处理索引和位置的方法,允许精确控制会话状态,而无需手动遍历条件。
ctx = {"plan": "free"}
next_idx = engine.next_index(1, ctx)
prev_idx = engine.previous_index(3, ctx)
pos = engine.effective_position(next_idx, ctx)
total = engine.effective_total(ctx)
if engine.is_last_visible(next_idx, ctx):
# Complete dialog
...
为了会话持久化,DialogSessionState 类将当前索引和上下文序列化为 JSON。这简化了在用户请求之间将状态存储到 Redis 或关系型数据库的过程。
与 aiogram 3 的集成及回调处理
库核心与框架无关,但为 Telegram 生态提供了现成助手。它们生成内联键盘、自动标记选中值并形成正确的 callback_data。回调处理是类型化的,并分离了选择、跳过和后退的逻辑。
from dialog_engine.integrations.aiogram import (
build_step_keyboard,
parse_choice_callback,
is_named_callback,
KeyboardCallbacks,
)
step = engine.get_step(current_index)
kb = build_step_keyboard(step, translate, show_back=True, current_value=ctx.get(step.id))
await message.answer(step.text, reply_markup=kb)
传入回调解析由返回步骤 ID 和选中值的解析器处理。这消除了手动解析 callback.data 字符串,并降低了前缀冲突风险。
@router.callback_query()
async def on_callback(callback: CallbackQuery):
cb = KeyboardCallbacks()
pair = parse_choice_callback(callback.data, cb)
if pair:
step_id, choice_key = pair
ctx[step_id] = choice_key
next_idx = engine.next_index(current_index, ctx)
...
CLI 工具和配置验证
声明式配置支持需要静态分析工具。包含的 CLI 在应用启动前检查文件结构,查找重复 ID、损坏引用和语法错误。严格模式使用 Pydantic 进行完整类型检查。
dialog-engine validate wizard.json— 基本结构检查。dialog-engine validate --strict wizard.json— Pydantic 验证。dialog-engine mermaid wizard.json— 为文档生成转换图。dialog-engine schema > dialog.schema.json— 输出 JSON Schema 以支持 IDE 自动补全。dialog-engine init -o my-dialog.json— 创建新的对话模板。
将验证集成到 CI/CD 管道中,确保无效配置不会进入生产环境。JSON Schema 为代码编辑器提供语法高亮和自动补全,降低了产品经理和分析师编辑表单的门槛。
关键点
- 对话在 JSON/YAML 中声明式描述,将业务逻辑与应用代码分离,并允许无需重新部署即可编辑场景。
- 导航和步骤可见性从会话上下文中动态计算,避免嵌套条件结构。
- aiogram 3 集成提供现成的键盘生成器和类型化回调解析器,减少样板代码。
- CLI 工具和 JSON Schema 支持静态配置检查和平滑的 IDE 开发。
- 该库采用源可用许可分发:允许在项目中使用,但修改和重新分发源代码受限。
— Editorial Team
暂无评论。