1776654103
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
一种"带插件的文本生成器"。它允许你创建一个包含变量和逻辑的"模板"文件,然后在渲染时填入具体数据,最终生成想要的文本格式(如 HTML、JSON、Markdown 等)。
|
||||
|
||||
它的语法简单直观,主要有三种核心元素:
|
||||
|
||||
- **`{{ … }}`**:用于输出变量值,例如 `{{ user_name }}` 会在渲染时被具体的用户名替换。
|
||||
- **`{% … %}`**:用于执行逻辑,例如循环 `{% for item in items %}` 或判断 `{% if user_logged_in %}`。
|
||||
- **`{# … #}`**:用于添加注释,不会出现在最终输出中。
|
||||
|
||||
### 提示词(Prompt)工程
|
||||
|
||||
主要用于**动态、精确地构建和管理提示词(Prompt)**。其核心价值在于将"提示词模板"与"可变数据"分离。
|
||||
|
||||
#### 1. 构建动态、结构化的提示词
|
||||
|
||||
在实际应用中,很少会发送固定的文本给 AI。你需要将用户问题、聊天历史、检索到的知识等动态拼接到提示词中。Jinja 让这件事变得优雅和可控。
|
||||
|
||||
**示例:一个智能客服的提示词模板**
|
||||
|
||||
```jinja
|
||||
你是一名专业的客服助手,名叫"小智"。
|
||||
请基于以下提供的资料,回答用户的问题。
|
||||
如果资料中找不到答案,请直接说"不知道",不要编造。
|
||||
|
||||
### 参考资料:
|
||||
{% for doc in search_results %}
|
||||
- {{ doc.title }}: {{ doc.content }}
|
||||
{% endfor %}
|
||||
|
||||
### 对话历史:
|
||||
{% for msg in chat_history %}
|
||||
{{ msg.role }}: {{ msg.content }}
|
||||
{% endfor %}
|
||||
|
||||
### 用户当前的问题是:
|
||||
{{ current_question }}
|
||||
|
||||
请给出你的回答:
|
||||
```
|
||||
|
||||
在这个模板中,`search_results`、`chat_history` 和 `current_question` 都是变量。渲染时,Jinja 会循环填入所有搜索结果和对话记录,生成一个结构清晰、信息完整的提示词。
|
||||
|
||||
#### 2. 统一聊天模型的提示词格式(Chat Template)
|
||||
|
||||
这是 Jinja 在 AI 领域最"杀手级"的应用。每个大模型(如 Llama、Mistral、ChatGLM)对聊天对话的输入格式要求都不同。**Chat Template** 就是用 Jinja 语法写的一段脚本,定义了如何将 `messages` 数组(包含 role 和 content 的对话)转换成模型能理解的单一字符串。
|
||||
|
||||
**一个简化的 Chat Template 示例:**
|
||||
|
||||
```jinja
|
||||
{% for message in messages %}
|
||||
{% if message['role'] == 'user' %}
|
||||
{{ '[INST] ' + message['content'] + ' [/INST]' }}
|
||||
{% elif message['role'] == 'assistant' %}
|
||||
{{ ' ' + message['content'] + ' </s>' }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
- **输入(Messages)**: `[{"role": "user", "content": "你好"}, {"role": "assistant", "content": "你好!有什么可以帮你的?"}]`
|
||||
- **输出(Prompt String)**: `[INST] 你好 [/INST] 你好!有什么可以帮你的? </s>`
|
||||
|
||||
AI 框架如 Hugging Face Transformers 已经内置了对 Jinja Chat Template 的支持。你只需调用 `tokenizer.apply_chat_template(messages)`,它就会自动使用模型对应的 Jinja 模板来生成正确的输入,极大地简化了开发流程。
|
||||
|
||||
#### 3. 在 AI 工作流和数据转换中作为"胶水"
|
||||
|
||||
在复杂的 AI 应用(如 RAG 检索增强生成、Agent)和工作流平台(如阿里云的 AI Studio、Azure 的 Prompt Flow)中,Jinja 常被用作轻量级的**数据处理和格式化工具**。
|
||||
|
||||
例如,可以将检索到的多个相关文档片段,通过一个 Jinja 模板快速格式化为一个结构清晰的 Markdown 列表,再输入给大模型。
|
||||
|
||||
```
|
||||
{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<|tool▁call▁end|>'}}{%- set ns.is_first = true -%}{%- else %}{{'\\n' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<|tool▁call▁end|>'}}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = message['content'].replace('</think>', '').split('<think>')[-1] %}{% endif %}{{'<|Assistant|>' + content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<|Assistant|>'}}{% endif %}
|
||||
```
|
||||
Reference in New Issue
Block a user