Skip to content

Zero, One and Few Shot Prompting #138

Closed
@realskyrin

Description

@realskyrin

Few-show 可以简单的理解为在发送 prompt 时提前做一个 context mock,通过少量引导可以显著提升 AI 回复质量的技巧。

例如这个查单词小工具

#!/usr/bin/env python3
# This is an English word search assistant.

import json
import requests
import sys
import os

OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
OPENAI_BASE_URL = os.environ.get('OPENAI_BASE_URL')


def query(message):
    message = json.dumps(message)

    if len(sys.argv) > 1:
        prompt = "你是一个英语单词查询助手,每当用户发送一个英语单词给你,你都要以固定格式响应用户," \
                 "如果用户发给你的不是一个单词,回复 'invalid token'"

        response_few_shot_text = "run [/rʌn/]" \
                                 "\n\nn. 奔跑;竞赛;连续的演出\nHe went for a run after work. (他下班后去跑步了)" \
                                 "\n\nv. 奔跑;运行\nI like to run in the park every morning. (我喜欢每天早上在公园里跑步)" \
                                 "\n\nadj. 连续的;流畅的\nThis printer is really fast and runs smoothly. (这台打印机速度非常快,而且运行流畅)"
    else:
        print("This is an English word search assistant")
        print("Usage: qr word")
        return

    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {OPENAI_API_KEY}"
    }

    data = {
        "model": "gpt-3.5-turbo",
        "temperature": 0,
        "top_p": 1,
        "frequency_penalty": 1,
        "presence_penalty": 1,
        "stream": False,
        "messages": [
            {"role": "system", "content": prompt},
            {"role": "user", "content": "run"},
            {"role": "assistant", "content": response_few_shot_text},
            {"role": "user", "content": message}
        ]
    }

    response = requests.post(OPENAI_BASE_URL, headers=headers, data=json.dumps(data))

    answer = json.loads(response.content)["choices"][0]["message"]["content"].strip()
    print("\033[32m---🤖---------\033[0m")
    print(answer)
    print("\033[32m--------------\033[0m")


if __name__ == "__main__":
    query(" ".join(sys.argv[1:]))

我在 request message 中 mock 了 system prompt、user 发送的第一个 prompt 以及 assistant 的一个 response

"messages": [
    {"role": "system", "content": prompt},
    {"role": "user", "content": "run"},
    {"role": "assistant", "content": response_few_shot_text},
    {"role": "user", "content": message}
]

那么我之后再发送任何单词,它都会很规范的返回结果 (返回单词的所有词性并造句),因为 context 里已经 mock 了它返回的第一个结果,它知道接下来该怎么回复,而无需向它解释过多的东西
image

如果直接给它发消息作为 prompt 也就是直接一条 user prompt,效果就会差很多,有时候每个词性给出多条例句,或者就只给一个词性的例句

image

image

这是 openai-cookbook 中关于 Few shot 的介绍:https://github.com/openai/openai-cookbook/blob/main/techniques_to_improve_reliability.md#few-shot-examples

除此之外,Few-shot 也有助于 AI 进行链式思维以提升结果的准确率,可以应用到很多场景。

我的想法是,可以给每个可以给每个 chat 单独设置 system、user、assistant 这些预设,简单一点的做法是给一个输入框,可以填入整个 request message 部分的 json :

"messages": [
    {"role": "system", "content": sys_prompt},
    {"role": "user", "content": "user_prompt"},
    {"role": "assistant", "content": response_few_shot_text},
    {"role": "user", "content": user_message}
]

请求的时候直接带上这个预设的 message。而且每次 request 仅带这个 message,不需要传入其它上下文,这样一来这个 chat 就变成一个相当稳定且节省 Token 的小工具了。

总之,这个项目非常很赞,只可惜自己不会前端所以以上想法没法直接提 PR,今天现在开始学前端 😂

支持一波
4321680072417_ pic

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationfaqMost asked questions

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions