You need to enable JavaScript to run this app.
导航
Prefill Response模式最佳实践
最近更新时间:2024.11.04 16:22:44首次发布时间:2024.11.01 13:00:06

在使用或调用大模型时,如果希望控制和引导模型的输出,可以通过预填(Prefill)部分Assistant 角色的内容,来引导和控制模型的输出。输出的控制可以是强制按照 JSON 或 XML 等特定格式输出;跳过已生成的文本;在角色扮演场景中保持角色一致性。

适用模型范围

豆包语言大模型lite及pro系列,0828版本及以后。
Image

主要用法

设置messages最后一个roleAssistant ,模型会对Assistant已有的内容按照现有格式和内容进行续写。

...
messages=[
        {"role": "user", "content": "你是一个计算器,请计算: 1 + 1 "},
        # 最后Role为Assistant
        {"role": "assistant", "content": "="},
        ]
...

续写即内容继续写作,输出内容不会包括用户填充的部分。

效果对比

模式

普通模式

Prefill Response模式

模型调用示例

import os
from volcenginesdkarkruntime import Ark

client = Ark(api_key=os.environ.get("ARK_API_KEY"))
completion = client.chat.completions.create(
    # 你的Endpoint ID
    model="ep-2024****-**zpz",
    messages=[
        {"role": "user", "content": "你是一个计算器,请计算: 1 + 1 "},
    ]
)
print(completion.choices[0].message.content)
import os
from volcenginesdkarkruntime import Ark

client = Ark(api_key=os.environ.get("ARK_API_KEY"))
completion = client.chat.completions.create(
    # 你的Endpoint ID
    model="ep-2024****-**zpz",
    messages=[
        {"role": "user", "content": "你是一个计算器,请计算: 1 + 1 "},
        # 最后Role为Assistant
        {"role": "assistant", "content": "="}
    ]
)
print(completion.choices[0].message.content)

模型输出示例

1+1等于2。
2

接下来,对于几种典型使用场景进行举例说明。

场景1:改善输出格式

由于模型自身会基于自己的理解去响应用户的请求,会导致输出无法直接被其他程序解析。可以通过预填充 { 符号,引导模型跳过一些场景回复,直接输出 JSON 对象,会让回答更加简洁和工整,可以被其他程序更好地解析。
示例:

模式

普通模式

Prefill Response模式

输入

import os
from volcenginesdkarkruntime import Ark

client = Ark(api_key=os.environ.get("ARK_API_KEY"))
completion = client.chat.completions.create(
    # 你的Endpoint ID
    model="ep-2024****-**",
    messages=[
        {"role": "user", "content": "用 JSON 描述豆包模型的name和function"}
    ]
)
print(completion.choices[0].message.content)
import os
from volcenginesdkarkruntime import Ark

client = Ark(api_key=os.environ.get("ARK_API_KEY"))
completion = client.chat.completions.create(
    # 你的Endpoint ID
    model="ep-****-**",
    messages=[
        {"role": "user", "content": "用 JSON 描述豆包模型的name和function"},
        {"role": "assistant", "content": "{"},
    ]
)
print(completion.choices[0].message.content)

说明

使用 Prefill Response 进行预先填充 { 符号。

输出

以下是一个简单的 JSON 示例来描述豆包模型的名称和功能:

```json
{
  "name": "豆包",
  "function": [
        "回答各种各样的知识类问题,包括但不限于科学知识(如物理、化学、生物等)、历史事件、文化传统、地理信息等",
        "提供关于语言学习方面的帮助,如语法解释、词汇辨析、翻译建议等",
        "对各种创意性话题进行讨论,例如给出故事创意、艺术创作的思路等",
        "解答生活常识问题,像家居维修建议、健康生活小贴士等"
    ]
}
``` 当然,您可以根据更详细和具体的需求来进一步完善和扩展这个 JSON 描述。

说明

该内容因为一些多余的内容,会导致无法直接被 JSON 解析。

"name": "豆包",
  "function": [
        "回答各种各样的知识类问题,包括但不限于科学知识(如物理、化学、生物等)、历史事件、文化传统、地理信息等",
        "提供关于语言学习方面的帮助,如语法解释、词汇辨析、翻译建议等",
        "对各种创意性话题进行讨论,例如给出故事创意、艺术创作的思路等",
        "解答生活常识问题,像家居维修建议、健康生活小贴士等"
    ]
}

说明

和前置的Assistant内容组合成JSON格式的内容。

注意事项

由于模型具有一定的随机性,使用该方法也无法 100% 保证回复能被 JSON 解析器解析,您可以使用针对大模型生成的 JSON 内容进行修复的方法。下面是一个示例,您可以使用社区的 json_repair 库来进行兜底解析。

import os
from volcenginesdkarkruntime import Ark
import json
# 通过命令 pip install json-repair 安装json_repair库
import json_repair

PREFILL_PRIFEX = "{"
client = Ark(api_key=os.environ.get("ARK_API_KEY"))
completion = client.chat.completions.create(
    # 你的Endpoint ID
    model="ep-2024****-**",
    messages=[
        {"role": "user", "content": "用 JSON 描述豆包模型的名称和功能"},
        {"role": "assistant", "content": PREFILL_PRIFEX},
    ]
)
# 拼接 PREFILL_PRIFEX 和模型输出
json_string = PREFILL_PRIFEX + completion.choices[0].message.content
# 解析 JSON Object
obj = {}
try:
    obj = json.loads(json_string)
except json.JSONDecodeError as e:
    obj = json_repair.loads(json_string)

print(obj)

场景2:跳过已生成的文本

由于服务器资源的约束,一次请求不能提供长文本的输出(目前输出最大tokens参数 max_tokens 可设置范围[0,4096])。使用 Prefill Response 模式让大模型跳过已生成的文本,实现输出超长内容。

import os
from volcenginesdkarkruntime import Ark

client = Ark(api_key=os.environ.get("ARK_API_KEY"))
messages = [
    {"role": "user", "content": '''请翻译下面的文本为英文:****** '''},
    {"role": "assistant", "content": ""}
]
ark_model="ep-2024****-**"
completion = client.chat.completions.create(
    model=ark_model,
    messages=messages
)
# 触发因为输出长度限制,循环生成 assistant 回复
while completion.choices[0].finish_reason == "length":
    messages[-1]["content"] += completion.choices[0].message.content
    completion = client.chat.completions.create(
        model=ark_model,
        messages=messages
    )

# 不管是否触发 finish_reason == "length",都返回最后一条回复
messages[-1]["content"] += completion.choices[0].message.content
print(messages[-1]["content"])

场景3:增强角色扮演一致性

我们通常使用 System 来设置角色的一些信息,但是随着对话轮次的增多,模型可能会跳脱出角色的约束,通过 Prefill Response 模式,可以使的每一轮对话都提醒模型当前的角色,保证模型扮演角色的一致性。

import os
from volcenginesdkarkruntime import Ark

client = Ark(api_key=os.environ.get("ARK_API_KEY"))
ark_model="ep-2024****-**"
messages = [
    {"role": "system", "content": "下面是一个西游记中的场景,请按照指定的角色来进行对话,每轮对话只用回复当前角色的内容,不要再回复新的内容。:\n\n唐僧师徒离了五庄观,又走了一个多月,来到一座大山前。悟空一看,四周崇山峻岭,杂草丛生,山势十分险恶。"},
    {"role": "assistant", "content": "悟空说:"}
]
completion = client.chat.completions.create(
    model=ark_model,
    messages=messages
)
print(messages[-1]['content']+completion.choices[0].message.content)

模型输出示例:

悟空说:“师父,这山看起来险恶得很,俺老孙先去探探路,你们且在此等候。”

您也可以通过变更messages最后消息,实现角色切换。

...
messages[-1] = {"role": "assistant", "content": "唐僧说:"}
completion = client.chat.completions.create(
    model=ark_model,
    messages=messages
)
print(messages[-1]['content']+completion.choices[0].message.content)

模型输出示例:

唐僧说:“悟空,此山看起来甚是险恶,你定要小心查看,莫要着了妖怪的道。”