公众号:dify实验室
众多资源分享:企业实战的dify DSL案例文件、交流群、大模型token资源等。
在 Dify 的工作流构建中,模板转换节点凭借其对 Jinja2 模板语言的强大支持,早已成为数据处理和格式化的得力助手。我们或许已经熟练运用它来生成 HTML 表格、格式化 JSON,或者拼接提示词。但实际上,这块小小的画布蕴藏着远超基础操作的潜力。只要我们敢于想象,并结合 Jinja2 的灵活性,就能解锁一系列既实用又“好玩”的动态文本生成功能。
本文将带你跳出常规思维,探索 Dify 模板转换节点的更多可能性,看看它如何在你构建的 AI 应用中扮演更富创造力的角色。我们将通过具体的代码示例和输入参数,展示这些功能的实际应用。
一、 个性化体验的魔法师:动态内容定制
想象一下,你的 AI 应用不再是千篇一律的冰冷机器,而是能根据用户或情境展现出个性化关怀的贴心伙伴。模板转换节点正是实现这一点的关键。
1.1 智能问候与互动
功能描述:
根据用户名称和当前时间生成个性化问候。
输入参数 (user 对象和假设的 current_time 对象或可调用函数):
{
"user": {
"name": "李明"
},
"current_time": { // 实际可能通过 Dify 内置变量或代码节点获取
"hour": 14 // 假设当前是下午2点
}
}
Jinja2 模板代码:
你好,{{ user.name }}!
{% if current_time.hour < 6 %}夜深了,早点休息。
{% elif current_time.hour < 12 %}早上好!
{% elif current_time.hour < 14 %}中午好!
{% elif current_time.hour < 18 %}下午好!
{% else %}晚上好!
{% endif %}
今天有什么可以帮您的吗?
预期输出:
你好,李明!
下午好!
今天有什么可以帮您的吗?
示例场景: 一个 AI 客服在对话开始时,能根据时间向用户致以“李先生,早上好!”或“王女士,下午茶时间愉快!”的问候。
1.2 定制化产品推荐语
功能描述:
根据用户偏好和推荐产品信息生成推荐语。
输入参数 (user_preference 字符串和 recommended_product 对象):
{
"user_preference": "户外运动",
"recommended_product": {
"name": "超轻防水冲锋衣",
"features": ["Gore-Tex面料", "轻量化设计", "多口袋"],
"category": "户外服装"
}
}
Jinja2 模板代码:
考虑到您对【{{ user_preference }}】的兴趣,我们特别向您推荐这款【{{ recommended_product.name }}】。
它属于{{ recommended_product.category }}类别,主要特点包括:{{ recommended_product.features | join('、') }}。
相信它能满足您的需求!
预期输出:
考虑到您对【户外运动】的兴趣,我们特别向您推荐这款【超轻防水冲锋衣】。
它属于户外服装类别,主要特点包括:Gore-Tex面料、轻量化设计、多口袋。
相信它能满足您的需求!
示例场景: 电商应用的 AI 助手,在用户浏览某类商品后,能结合其偏好说:“根据您对简约风格的喜爱,这款新到的【纯色亚麻衬衫】或许正是您在寻找的。”
二、 信息梳理与呈现:动态报告与摘要
面对复杂的数据和信息,如何清晰、高效地呈现给用户或后续处理步骤?模板转换节点同样能大显身身手。
2.1 知识库检索结果美化 (Markdown格式)
功能描述:
将知识库检索的多个片段整理成带小标题的 Markdown 报告。
输入参数 (retrieved_chunks 列表):
{
"retrieved_chunks": [
{
"title": "Jinja2 循环",
"content": "Jinja2 使用 {% for item in list %} ... {% endfor %} 进行循环。",
"score": 0.92
},
{
"title": "Jinja2 条件判断",
"content": "条件语句使用 {% if condition %} ... {% else %} ... {% endif %}。",
"score": 0.88
}
]
}
Jinja2 模板代码:
## 知识检索报告
{% if retrieved_chunks and retrieved_chunks | length > 0 %}
{% for chunk in retrieved_chunks %}
### {{ loop.index }}. {{ chunk.title }} (相似度: {{ "%.2f" | format(chunk.score) }})
{{ chunk.content | replace('\n', '\n\n') }}
---
{% endfor %}
{% else %}
未检索到相关信息。
{% endif %}
预期输出 (Markdown):
## 知识检索报告
### 1. Jinja2 循环 (相似度: 0.92)
Jinja2 使用 {% for item in list %} ... {% endfor %} 进行循环。
---
### 2. Jinja2 条件判断 (相似度: 0.88)
条件语句使用 {% if condition %} ... {% else %} ... {% endif %}。
---
2.2 数据分析结果展示
功能描述:
将数据分析得到的关键指标格式化成文本摘要。
输入参数 (metrics 对象):
{
"metrics": {
"new_users": 125,
"active_user_percentage": 0.675,
"revenue": 15800.50,
"top_feature": "数据导出"
}
}
Jinja2 模板代码:
本周关键业务指标摘要:
- 新增用户数:{{ metrics.new_users }} 人
- 活跃用户占比:{{ "%.1f%%" | format(metrics.active_user_percentage * 100) }}
- 总营收:¥{{ "%.2f" | format(metrics.revenue) }}
- 最受欢迎功能:{{ metrics.top_feature | default('暂无数据') }}
预期输出:
本周关键业务指标摘要:
- 新增用户数:125 人
- 活跃用户占比:67.5%
- 总营收:¥15800.50
- 最受欢迎功能:数据导出
示例场景: 一个数据分析应用,每日自动生成一份包含“新增用户数:XXX”、“核心功能使用率:YYY%”等关键数据的文本摘要。
三、 复杂数据结构的构造师:API 请求体与配置文件
在与其他系统或服务集成时,我们常常需要构造特定格式的请求体(如 JSON、XML)或配置文件。
3.1 动态构建 API 请求 (JSON)
功能描述:
根据输入动态生成 JSON 格式的 API 请求体。
输入参数 (user_query 字符串, filter_type 字符串 (可选), user_id 字符串 (可选), start_date_iso 字符串, page_size 数字 (可选)):
{
"user_query": "查找最近的订单",
"filter_type": "completed",
"user_id": "user_123",
"start_date_iso": "2023-10-01T00:00:00Z",
"page_size": 20
}
Jinja2 模板代码:
{
"query": "{{ user_query }}",
"filters": {
"status": "{{ filter_type | default('any') }}",
{% if user_id %}
"customer_id": "{{ user_id }}",
{% endif %}
"created_after": "{{ start_date_iso }}"
},
"pagination": {
"limit": {{ page_size | default(10) }},
"offset": 0
}
}
预期输出 (JSON):
{
"query": "查找最近的订单",
"filters": {
"status": "completed",
"customer_id": "user_123",
"created_after": "2023-10-01T00:00:00Z"
},
"pagination": {
"limit": 20,
"offset": 0
}
}
3.2 生成动态 SQL 查询语句
功能描述:
根据参数动态生成 SQL 查询语句。
输入参数 (table_name 字符串, columns 列表, conditions 列表 (每个元素是字符串条件), limit 数字 (可选)):
{
"table_name": "orders",
"columns": ["order_id", "customer_name", "total_amount"],
"conditions": ["status = 'paid'", "order_date >= '2023-10-01'"],
"limit": 5
}
Jinja2 模板代码:
SELECT {{ columns | join(', ') }}
FROM {{ table_name }}
{% if conditions and conditions | length > 0 %}
WHERE {{ conditions | join(' AND ') }}
{% endif %}
{% if limit %}
LIMIT {{ limit }}
{% endif %};
预期输出 (SQL):
SELECT order_id, customer_name, total_amount
FROM orders
WHERE status = 'paid' AND order_date >= '2023-10-01'
LIMIT 5;
示例场景: 根据用户选择的数据库表名和筛选条件,动态生成一条 SQL 查询语句。
四、 创意无限:互动娱乐与文本游戏
谁说工作流只能处理严肃的任务?模板转换节点也能为你的应用注入趣味元素。
4.1 “文字冒险游戏”场景生成
功能描述:
根据当前场景和可用选项生成游戏文本。
输入参数 (current_scene 对象, available_options 列表):
{
"current_scene": {
"description": "你站在一个古老城堡的沉重木门前,门上刻着奇异的符文。",
"environment_details": ["空气中弥漫着尘土和一丝硫磺味。"]
},
"available_options": [
{"id": "opt1", "text": "尝试推开大门"},
{"id": "opt2", "text": "仔细研究门上的符文"},
{"id": "opt3", "text": "大声呼喊,看是否有人回应"}
]
}
Jinja2 模板代码:
{{ current_scene.description }}
{% for detail in current_scene.environment_details %}
{{ detail }}
{% endfor %}
你现在可以:
{% for option in available_options %}
{{ loop.index }}. {{ option.text }} (选择ID: {{ option.id }})
{% endfor %}
请输入你的选择对应的ID:
预期输出:
你站在一个古老城堡的沉重木门前,门上刻着奇异的符文。
空气中弥漫着尘土和一丝硫磺味。
你现在可以:
1. 尝试推开大门 (选择ID: opt1)
2. 仔细研究门上的符文 (选择ID: opt2)
3. 大声呼喊,看是否有人回应 (选择ID: opt3)
请输入你的选择对应的ID:
4.2 “Mad Libs”(疯狂填词)游戏
功能描述:
将用户提供的词语填充到故事模板中。
输入参数 (words 对象):
{
"words": {
"adjective1": "滑稽的",
"noun1": "香蕉",
"place": "月球表面",
"verb_present_tense": "跳舞",
"adjective2": "愤怒的",
"noun2": "机器人",
"verb_past_tense": "歌唱"
}
}
Jinja2 模板代码:
很久很久以前,有一只非常 {{ words.adjective1 }} 的 {{ words.noun1 }}。
它最喜欢在 {{ words.place }} 上 {{ words.verb_present_tense }}。
有一天,它在 {{ words.place }} 遇到了一个 {{ words.adjective2 }} 的 {{ words.noun2 }},
于是它们一起愉快地 {{ words.verb_past_tense }} 了一整天!这是一个多么 {{ words.adjective1 }} 的故事啊!
预期输出:
很久很久以前,有一只非常滑稽的香蕉。
它最喜欢在月球表面上跳舞。
有一天,它在月球表面遇到了一个愤怒的机器人,
于是它们一起愉快地歌唱了一整天!这是一个多么滑稽的故事啊!
五、 实用工具:格式转换与文本处理
5.1 JSON 转 CSV
功能描述:
将产品列表的 JSON 数据转换为 CSV 格式。
输入参数 (products 列表):
{
"products": [
{"id":"P001","name":"智能降噪耳机","category":"数码配件","price":599,"stock":150},
{"id":"P002","name":"有机棉T恤, 白色","category":"服装","price":129.5,"stock":300},
{"id":"P003","name":"《\"科幻\"概论》","category":"图书","price":78.99,"stock":80}
]
}
(注意:products 输入与之前表格示例相同,这里为了简洁省略重复展示)
Jinja2 模板代码 (注意CSV中对特殊字符的处理):
id,name,category,price,stock
{%- for item in products -%}
{{ item.id }},"{{ item.name | replace('"', '""') }}","{{ item.category | replace('"', '""') }}",{{ item.price }},{{ item.stock }}
{% endfor %}
注意: {%- ... -%} 中的 - 用于移除前导或尾随的空白/换行,使输出更紧凑。replace('"', '""') 是 CSV 中处理包含双引号的字段的标准方法。
预期输出 (CSV 文本):
id,name,category,price,stock
P001,"智能降噪耳机","数码配件",599,150
P002,"有机棉T恤, 白色","服装",129.5,300
P003,"《""科幻""概论》","图书",78.99,80
5.2 自定义日志格式化
功能描述:
根据传入的日志事件数据,生成符合预设格式的日志条目。
输入参数 (log_event 对象):
{
"log_event": {
"timestamp_iso": "2023-10-27T10:30:15Z",
"level": "INFO",
"workflow_id": "wf_abc123",
"node_id": "node_xyz789",
"message": "User query processed successfully.",
"user_id": "usr_001"
}
}
Jinja2 模板代码:
[{{ log_event.timestamp_iso }}] [{{ log_event.level | upper }}] [Workflow: {{ log_event.workflow_id }}] [Node: {{ log_event.node_id }}] {% if log_event.user_id %}[User: {{ log_event.user_id }}] {% endif %}- {{ log_event.message }}
预期输出:
[2023-10-27T10:30:15Z] [INFO] [Workflow: wf_abc123] [Node: node_xyz789] [User: usr_001] - User query processed successfully.
如何释放模板转换节点的潜力?
深入理解输入数据: 你的模板设计强依赖于上游节点提供的变量名称、数据类型和结构。熟练掌握 Jinja2 语法: 变量输出 {{ ... }}、控制结构 {% ... %}(如 if/else/endif, for/endfor)、过滤器(如 | length, | join, | format, | default)是实现动态逻辑的基础。明确目标输出格式: 清晰定义你想要生成的文本是纯文本、Markdown、HTML、JSON、XML 还是其他特定格式。从小处着手,逐步迭代: 对于复杂的功能,可以先实现核心部分,然后逐步添加更多细节和逻辑,并不断测试。
重要提示: 本文中的输入参数示例是为了演示 Jinja2 模板的用法。在实际的 Dify 工作流中,这些输入变量通常来自上游节点(如 API 请求节点、代码节点、知识库检索节点等)的输出,或者通过 Dify 的全局变量机制传入。请根据您的具体工作流设计来获取和使用这些变量。
Dify 的模板转换节点不仅仅是一个简单的数据转换工具,它更像是一把多功能的瑞士军刀,等待着富有创造力的你去发掘和运用。通过巧妙地结合 Jinja2 的强大功能,你可以在 Dify 工作流中实现远超预期的动态文本生成效果,为你的 AI 应用增添更多智能、个性和趣味。
公众号:dify实验室
关注我可得:众多企业实战的DSL案例文件、交流群、大模型token资源等。