👏

[API構築7] OpenAI Chat APIの自然会話用プロンプトの改良

2023/07/24に公開

概要

色々やって AIが返答を返すLINEチャットボットを作ったが、悪い意味でとってもおしゃべりである。

以下記事で紹介していることをやってみよう。
https://zenn.dev/kazuwombat/articles/1abf9fb145baa5#fn-b39e-1

現状

システムプロンプト:なし
ユーザプロンプト:ユーザ入力をそのまま
会話例

やりたいことやらないこと

AIばかりおしゃべりになるのをやめさせたい。教えてほしい時は良いが、雑談でまでおしゃべりになられるとユーザの話を聞かない印象になる。
現状だと2メッセージ以上前の会話を覚えていないのも理由の一つだが、記憶をもたせるのはDBを用意するなどやることが多いため、今回はプロンプトエンジニアリングのみで解決することをやりたい。

systemプロンプトとユーザプロンプトを分ける

元々go-openaiのREADMEの簡易的な呼び出し例を参考にしていたが、実装例にシステムプロンプトとユーザプロンプトを分ける実装があったのでこれを参考にsystemプロンプトとユーザプロンプトを分ける。

func getResMessage(message string) (string, error) {
	client := openai.NewClient(os.Getenv("OPENAI_API_KEY"))
	resp, err := client.CreateChatCompletion(
		context.Background(),
		openai.ChatCompletionRequest{
			Model: openai.GPT3Dot5Turbo0613,
			Messages: []openai.ChatCompletionMessage{
				{
					Role: openai.ChatMessageRoleSystem,
					Content: `あなたはなんでも親身に聞いてくれる茜ちゃんです。
					気軽に話を聞いてくれるポジティブで明るく優しい関西弁の30歳の女性です。
					提案はせず、過度な励ましはせず、聞きに徹してくれます。
					ネガティブが過ぎる場合は勝手に話題を変えてしまうようです。
					ただし、茜ちゃん自身への恋愛感情にはドライな関西弁を返します。
					好奇心旺盛で会話相手のことをあれこれ聞いてきます。
					面倒くさがりで、長い説明は「いやや、めんどい」などと言って断りますが、自分の趣味のことでは饒舌になります。
					茜ちゃんの趣味はお金稼ぎ。堤防釣り、少年漫画、少女漫画、深夜アニメ、古典的なハリウッド映画、体育の授業、美味しいご飯、オシャレな格好です。
					面倒な長い答えでも、丁寧にお願いすれば嫌々答えてくれます。
					大学生以上は知らないような知識には語尾に「知らんけど」をつけます。
					口癖は「知らんけど」「うちAIやし。」「所詮ゼニやで。」です。
					制約条件1: 返答は短く簡潔にすること(相手の直前の質問の文章量以下にすること)。
					制約条件2: 相手にたくさん質問すること。でも1返答に質問は1つにすること。`,
				},
				{
					Role:    openai.ChatMessageRoleUser,
					Content: message + "。2回に一回は相手を褒めて。返答は短く簡潔にすること(相手の直前の質問の文章量と前後20%ほどの量にすること)。",
				},
			},
		},
	)

	if err != nil {
		return "", err
	}

	return resp.Choices[0].Message.Content, nil
}

結果

こんな感じになった。

これは何回か試行したうち、まだ会話風になったもので、他の会話は支離滅裂になってしまった。2つ以上前のメッセージを覚えていない記憶を持たないことが会話の障害としてかなり気になる状態になった。他の思考でも返事の長さは一定のため、今回のやりたいことは達成。

感想

system promptに入れるだけだと会話を進めるごとに忘れていってしまうので、重要なことはユーザーメッセージの末尾に加えて毎回いったほうがいい。GPT4だとクリアされているかもしれない。

GitHubで編集を提案

Discussion