Skip to content

Latest commit

 

History

History
347 lines (263 loc) · 12.1 KB

prompt.md

File metadata and controls

347 lines (263 loc) · 12.1 KB

Prompt

千帆平台提供对 Prompt 进行管理的接口,鉴权需要 Access Key 和 Secret Key,获取方式详见 官方文档

SDK 提供了 Prompt 类,可以方便快速地使用千帆的 Prompt 能力,也在 resources 包内提供了原始的 Prompt 接口供使用。

Prompt 类

我们提供了 Prompt 的 cookbook,可以通过案例快速了解如何使用

可以通过如下方式引用

from qianfan.common import Prompt

快速使用

平台上预置的 Prompt 以及用户自定义的模型都可以在 千帆控制台 获得,之后可以在 SDK 的 hub 能力从平台快速获取 Prompt 对象,并进行渲染等操作。

from qianfan.common.hub import hub

# 获取平台上的 Prompt,name 为控制台上显示的名称
p = hub.load("prompt/区域美食推荐")
# 第二个参数是 negative prompt,仅文生图场景使用,此处可忽略
prompt, _ = p.render(region="上海")

# 之后就可以将渲染后的结果送入模型进行推理
qianfan.Completion().do(prompt)

# 文生图的 Prompt 使用方法相同,具体类型可以从控制台查看
txt2img_prompt = hub.load("prompt/角色设计")
# 类型通过变量属性获取
from qianfan.consts import PromptSceneType
txt2img_prompt.scene_type == PromptSceneType.Text2Image # => True

prompt, negative_prompt = txt2img_prompt.render()
# 之后将 prompt 和 negative_prompt 送入模型进行推理
qianfan.Text2Image().do(
    prompt=prompt, 
    negative_prompt=negative_prompt
)

本地 Prompt

如果不想使用平台上的 Prompt,也可以直接使用 template 参数构造 Prompt 对象。

p = Prompt(
    template="本地 prompt {var1}",
)

prompt, _ = p.render(var1="hello") # => 本地 prompt hello

# 文生图 Prompt 同样支持
prompt = Prompt(
    name="txt2img",
    template="txt2img template ((v1))",
    scene_type=PromptSceneType.Text2Image, 
    negative_template="negative template ((v3))", # 负向 prompt
    identifier="(())", # prompt 中变量的标识符
)

上传&更新 Prompt

通过 hub 能力可以将本地 Prompt 上传到平台,或者是更新已有的 Prompt。

p = Prompt(
    template="本地 prompt {var1}",
)

# 对于平台上的 prompt 来说,name 是必须的,因此上传前必须先设置
p.name = "cookbook_prompt"
hub.push(p)

p.id # => 188

上传后就可以获得 Prompt 的 ID,之后可以通过 id 属性获取 Prompt 对象。

也可以对 prompt 进行更新后再推送至平台上进行更新。

p.set_template("新的 Prompt {new_var}")
hub.push(p) # 更新至平台

print(p.variables) # => ['new_var']
print(p.render(new_var="hello")) # => 新的 Prompt hello

删除 Prompt

调用 delete 方法可以删除 Prompt,如果是本地 Prompt 或者预置 Prompt,那么该函数将没有作用,删除后 Prompt 仍可以本地使用。

p = hub.load("prompt/cookbook_prompt")
p.delete()

保存&加载

SDK 提供了 save_to_file 方法,可以将 Prompt 保存保存至本地。 再次使用时,只需要通过 from_file 方法即可读取 Prompt。

p = Prompt(template="这是一个用于{usage}的 Prompt")
p.save_to_file("test_prompt.tpl")

p = Prompt.from_file("test_prompt.tpl")
prompt, _ = p.render(usage="测试")
print(prompt) # => 这是一个用于测试的 Prompt

优化 Prompt

为了提升模型推理的准确率,可以通过 optimize 方法对 Prompt 进行优化。

prompt = Prompt(template="帮我写一份{job}年终总结")
optimized_prompt = prompt.optimize()

优化可以开启不同选项:

  • optimize_quality:优化 prompt 质量
  • simplify_prompt:简化 prompt,可以省去“的”、“吧”等含义不强的文本实体,精炼语料内容并降低推理成本
  • iteration_round:优化迭代轮数,默认为 1
  • enable_cot:开启思维链,将指引模型拆解Prompt内容,逐步进行推理。建议仅在数学计算、逻辑推理等场景下开启使用。
  • app_id:优化时使用的 App ID,可选参数
  • service_name:优化时使用的服务名称,可选参数

评估 Prompt

SDK 提供了 evaluate 方法,可以评估不同 Prompt 在不同场景下的质量。

prompts = [old_prompt, new_prompt]
scenes = [
    {
        "args": {"job": "程序员"},
        "expected": "代码"
    },
    {
        "args": {"job": "产品经理"},
        "expected": "用户量"
    }
]
model = Completion()

results = Prompt.evaluate(prompts, scenes, model)

其中 prompts 是一个 Prompt 列表,model 是进行生成的模型对象,scenes 是一个场景列表,每个场景包含 argsexpected 两个字段,args 是 Prompt 变量参数,expected 是该 Prompt 期望的输出。

输出是一个列表,列表中每个元素是一个 PromptEvaluateResult 对象,对应了每个 Prompt 的评估结果,具有以下字段:

  • prompt:评估的 Prompt 对象
  • scene:不同场景下的表现
    • new_prompt:变量填充后的新 prompt
    • variables:变量列表
    • expected_target:期望的输出
    • response:模型生成的输出
    • score:对模型输出的打分
  • summary:对该 Prompt 表现的总结

框架类型

为了能够让模型更好的理解输入,需要提供足够详细的信息,千帆提供了数个 Prompt 框架类型,能够帮助用户编写出足够高质量的 Prompt,目前 SDK 支持如下框架类型:

  • NotUse(默认):不使用框架
  • Basic:通过指令、背景信息、补充数据、输出格式四个维度表述 Prompt,详见 文档
  • CRISPE:通过 Capacity and Role 人设、Insight 背景信息和上下文、Statement 执行的任务、Personality 风格、Experiment 实践几个维度表述 Prompt,详见 文档
  • Fewshot:通过少数几个示例指导模型进行回答,详见 文档
# 引入 PromptFrameworkType
from qianfan.consts import PromptFrameworkType
from qianfan.common import Prompt

# Basic 类型
basic_prompt = Prompt.base_prompt(
    prompt="帮我写一个年终总结",
    background="今年个人业绩情况为{var}。",
    additional_data="要去做演讲,风格要简约。",
    output_schema="输出内容要有成绩总结、遗留问题、改进措施和未来规划4项。"
)
prompt = Prompt(
    template=basic_prompt,
    framework_type=PromptFrameworkType.Basic
)

# CRISPE 类型
crispe_prompt = Prompt.crispe_prompt(
    capacity="你现在是一个资深律师。",
    insight="最近你接了一个财务侵占的官司,涉案金额{money}元,你是受害人的辩护律师。",
    statement="请帮忙出一个法律公告,警示被告尽快偿还非法侵占的财务。",
    personality="公告内容要严谨严肃专业。",
    experiment="公告内容不宜超过800字。",
)
prompt = Prompt(
    template=crispe_prompt,
    framework_type=PromptFrameworkType.CRISPE
)

# Fewshot 类型
fewshot_prompt = Prompt.fewshot_prompt(
    prompt="现在在做一个数学计算游戏,请根据下述规则回答最后一个示例的问题",
    examples=[
        ("1 2","3"),
        ("2 3","5"),
        ("3 4","")
    ]
)
prompt = Prompt(
    template=fewshot_prompt,
    framework_type=PromptFrameworkType.Fewshot
)

Prompt 接口

目前支持的 Prompt 操作有:

使用前需要从 resources 中引入 Prompt,注意与上述 Prompt 位置不同,建议非必要请使用上述的 Prompt 类,使用体验更佳:

from qianfan.resources import Prompt

创建 Prompt

最简单的方式是直接使用 Prompt.create 方法,传入 Prompt 名称和模板内容即可创建 Prompt,模版中通过 {} 表示待填充的变量名。返回结果可以通过 ['result']['templatePK'] 字段获取模板 ID。返回字段详见 API 文档

resp = Prompt.create(
    name="example_prompt",
    # 变量必须字母开头,仅包含字母、数字和下划线,长度 2-30
    template="example template {var1}", 
)
print(resp['result']['templatePK'])

SDK 也提供了其他参数,能够根据需求创建 Prompt,例如通过 identifier 字段指定识别变量的符号,示例如下

from qianfan.consts import PromptFrameworkType

resp = Prompt.create(
    name="example_prompt",
    identifier="()", # 支持的标识符有 ()、[]、{}、(())、[[]]、{{}}
    template="template (v1) {v2} (v3)", # 由于指定了标识符,所以此处 v2 不是变量
    framework=PromptFrameworkType.CRISPE, # 指定框架类型
    variables=["v1"], # 指定变量,不指定则自动识别
    label_ids=[10, 20] # 指定该 Prompt 对应的标签,获取方式见下方 `获取标签列表`
)

关于框架类型,参见 框架类型 一节。

千帆还提供了针对文生图场景的 Prompt,与上述使用方式一致,区别在于额外提供了 negative_templatesnegative_variables 字段,表示负面 Prompt,这一参数通过 scene=PromptSceneType.Text2Image 开启。

from qianfan.consts import PromptSceneType

resp = Prompt.create(
    name="txt2img_prompt",
    identifier="{}", 
    template="template {v1}",
    scene=PromptSceneType.Text2Image, # 设定 Prompt 场景为文生图
    negative_template="negative prompt {v2} {v3}", # 负面 Prompt 列表
    negative_variables=["v2"] # 与 variables 相同,可以指定变量,不指定会自动识别
)

更新 Prompt

SDK 提供了根据 Prompt ID 更新 Prompt 的能力,示例如下,返回字段详见 API 文档

resp = Prompt.update(
    id = 10, # Prompt ID
    name="new_name", # 更新 Prompt 名称,可选
    label_ids=[10, 20] # 更新 Prompt 标签,可选
    template="new template {v1}", # 更新 Prompt 模板,可选
    identifier="{}", # 更新 Prompt 变量标识符,可选
    negative_template="new negative template {v2} {v3}", # 更新 Prompt 负面模板,可选
)

渲染 Prompt 模版并获取详情

通过传入 Prompt ID 和变量值,SDK 可以渲染 Prompt 模版并获取详情,返回字段详见 API 文档

resp = Prompt.info(
    id=10, # Prompt ID
    var1="example", # 变量值
    var2="example"
)
print(resp['result']['content'])

删除 Prompt

通过传入 Prompt ID,SDK 可以删除 Prompt,返回字段详见 API 文档

resp = Prompt.delete(id=10)
print(resp['result']) # => True

获取 Prompt 列表

SDK 提供了获取 Prompt 列表的接口,通过 Prompt.list 方法即可获取到 Prompt 列表,并可以通过 name 字段进行筛选。返回字段详见 API 文档

from qianfan.consts import PromptType

resp = Prompt.list(
    offset=0, # 偏移量,可选,默认 0
    page_size=10, # 页大小,可选,默认 10
    name="example", # 筛选 Prompt 名称,可选
    label_ids=[10, 20] # 筛选 Prompt 标签,可选,为空表示不筛选
    type=PromptType.User # 筛选 Prompt 类型,可选,默认用户自制模版,Preset 表示预置模版
)

获取标签列表

SDK 提供了获取标签列表的接口,返回字段详见 API 文档

resp = Prompt.list_labels(
    offset=0, # 偏移量,可选,默认 0
    page_size=10, # 页大小,可选,默认 10
)