POML 模板引擎(Template Engine)

POML 模板引擎(Template Engine)

参考官方文档:microsoft.github.io/poml/stable...

概览

POML 的模板引擎让你在提示中使用"变量、表达式、循环、条件、文件包含"等动态能力,从而构建可复用、可组合的复杂提示。


表达式(Expressions)

  • 基本用法:使用双花括号 {{ }} 在内容位置插入变量或表达式结果。
poml 复制代码
<poml>
  <p>Hello, {{ name }}!</p>
</poml>
  • 属性中的表达式:也可用于属性值。
poml 复制代码
<poml>
  <task caption="Task #{{ index }}">This is task No. {{ index }}.</task>
</poml>
  • 支持的表达式(JavaScript 语法):
    • 变量:{{variableName}}
    • 算术:{{a + b}}{{x * y}}{{count / total}}
    • 字符串拼接:{{firstName + " " + lastName}}
    • 数组访问:{{myArray[0]}}
    • 对象属性:{{myObject.property}}
    • 函数调用:{{myFunction(arg1, arg2)}}(若函数在上下文中可用)
    • 三元运算:{{condition ? A : B}}
    • 循环变量:{{loop.index}} 等(见下文)

提示:属性中的表达式会先求值再进行类型自动转换(见"类型自动转换")。


let 变量与数据导入(Let Expressions)

<let> 用于定义变量、导入外部数据,并在模板内复用。

1) 从字面量设置变量

  • 内容作为字面量:
poml 复制代码
<poml>
  <let name="greeting">Hello, world!</let>
  <p>{{ greeting }}</p>
</poml>
  • 使用 value 属性(会按 JS 表达式求值,注意字符串需要引号):
poml 复制代码
<poml>
  <let name="greeting" value="'Hello, world!'" />
  <p>{{ greeting }}</p>
</poml>

2) 从文件导入数据(命名变量)

  • users.json 的内容导入到 users 变量:
poml 复制代码
<poml>
  <let name="users" src="users.json" />
  <p>First user: {{ users[0].name }}</p>
</poml>

type 可指定文件类型(如 jsontextcsv),不提供时按扩展名推断。

3) 从文件导入(不命名)

  • 直接把 JSON 顶层的键注入到当前上下文:
poml 复制代码
<poml>
  <let src="config.json" />
  <p>API Key: {{ apiKey }}</p>
</poml>

config.json 示例:

json 复制代码
{ "apiKey": "your_api_key" }

4) 使用内联 JSON 与类型标注

poml 复制代码
<poml>
  <let name="person">{ "name": "Alice", "age": 30 }</let>
  <p>Name: {{ person.name }}, Age: {{ person.age }}</p>

  <let name="count" type="integer">5</let>
  <p>Count: {{ count }}</p>
</poml>

5) 基于表达式设置变量

poml 复制代码
<poml>
  <let name="base" value="10" />
  <let name="increment" value="5" />
  <let name="total" value="{{ base + increment }}" />
  <p>Total: {{ total }}</p> <!-- 输出:15 -->
</poml>

类型自动转换(Type-Autocasting in Attributes)

  • 组件属性会根据其定义的类型自动转换:
    • Boolean:"true"1"1"{{true}}true"false"0"0"{{false}}false
    • Number:"123"45.6{{anyNumber}}{{myNumber+1.3}} → 相应数值
    • Object:尝试解析为 JSON 对象,例如:
      • data='{"name":"John","age":30}'
      • data="{{{name: 'John', age: 30}}}"(三花括号语法,直接提供对象字面量)
    • String:不做转换

示例(概念演示):

poml 复制代码
<poml>
  <let name="boolVar" type="boolean" value="true"/>
  <let name="numVar"  type="number"  value="42"/>
  <let name="objVar"  type="object"  value="{{ { key: 'value' } }}"/>
  <MyComponent
    boolProp="{{ boolVar }}"
    numProp="{{ numVar }}"
    objProp="{{ objVar }}"
    stringProp="hello"
  />
</poml>

for 循环(For Attribute)

  • 语法:for="itemName in listExpr"
poml 复制代码
<poml>
  <list>
    <item for="item in ['apple', 'banana', 'cherry']">{{ item }}</item>
  </list>
</poml>

循环变量(Loop Variables)

  • loop.index:当前索引(从 0 开始)
  • loop.length:总长度
  • loop.first:是否第一项(true/false)
  • loop.last:是否最后一项(true/false)
poml 复制代码
<poml>
  <let name="all_demos" value='[
    { "input": "What is your name?", "output": "My name is POML." },
    { "input": "What can you do?",  "output": "I can generate prompts." }
  ]'/>
  <examples>
    <example for="example in all_demos" chat="false"
             caption="Example {{ loop.index + 1 }}" captionStyle="header">
      <input>{{ example.input }}</input>
      <output>{{ example.output }}</output>
    </example>
  </examples>
</poml>

条件渲染(If Condition)

  • 使用 if 属性按条件渲染元素:
poml 复制代码
<poml>
  <let name="isVisible" value="true"/>
  <let name="isHidden"  value="{{ !isVisible }}"/>
  <p if="isVisible">This paragraph is visible.</p>
  <p if="isHidden">This paragraph is hidden.</p>
</poml>

if 的值可直接写变量名(按布尔解释)或任意表达式。


文件包含(Include Files)

  • 使用 <include src="..." /> 将其他 POML 片段注入当前文件;被包含文件可访问当前上下文的变量。
  • forif 可与 include 同用:
poml 复制代码
<poml>
  <include src="row.poml" for="i in [1,2,3]" />
  <include src="footer.poml" if="showFooter" />
</poml>

路径 src 相对于当前 POML 文件;避免循环包含。


实战组合示例

  • 目标:从 JSON 读取人员列表,循环渲染为多行,页脚按条件包含。

目录结构:

  • people.json
  • row.poml
  • main.poml

people.json

json 复制代码
[
  { "name": "Alice", "role": "PM" },
  { "name": "Bob",   "role": "Engineer" }
]

row.poml

poml 复制代码
<p><b>{{ person.name }}</b> - {{ person.role }}</p>

main.poml

poml 复制代码
<poml>
  <let name="people" src="people.json" />
  <let name="showFooter" value="true" />

  <section>
    <include src="row.poml" for="person in people" />
  </section>

  <footer if="showFooter">
    <p>Total: {{ people.length }}</p>
  </footer>
</poml>

实践建议与常见坑

  • 字符串字面量在 value 中必须加引号;内容写法则按字面量处理。
  • 对象型属性可用 JSON 字符串或三花括号对象字面量:
    • data='{"name":"John","age":30}'
    • data="{{{name: 'John', age: 30}}}"
  • 文件路径相对当前 .poml;注意编码与格式(如 JSON 的逗号与引号)。
  • 循环与条件可叠加在 include 上,便于模块化拆分。
  • 谨慎使用自定义函数调用;优先使用纯表达式与 let,保证可移植性与可调试性。

相关推荐
掘金安东尼43 分钟前
Claude Code 的“隐藏护城河”:GPT-5 也过不去的优化秘密
人工智能·llm
RainbowSea2 小时前
1. LangChain4J 理论概述
java·langchain·llm
RainbowSea3 小时前
2. LangChain4J 中的 Hello World
langchain·llm·ai编程
用户4183785530053 小时前
从零开始训练一个LLM
llm
掘我的金3 小时前
POML 语法基础(Language Basics)
llm
深度学习机器5 小时前
aisuite:统一的大模型SDK,简化LLM开发流程
chatgpt·llm·openai
811735 小时前
我开发了一个面向大模型训练的数据集构建平台:DatasetLoom
开源·llm
用户84913717547161 天前
joyagent智能体学习(第6期)Python工具服务深度剖析
llm·agent
AI大模型1 天前
AI老爱“瞎编”?给它请个RAG“私人秘书”,从此只说真话!
chatgpt·程序员·llm