みなさん、ChatGPTのAPIは使っているでしょうか?
簡単に使えて便利な反面、トークン数節約は重大な問題でしょう。そのために送るメッセージ数に上限をつけるようなこともあるでしょう。
そんな時にsliceでシンプルに書けることに気づかずに回りくどい書き方をしてしまっていたので、戒めとして記事にします。
なお、chatGPTのpromptエンジニアリングを楽にするツールを作成しているときに気づいた話なので、そのツールもあとで紹介しておきますね。
AI同士で対話させられるツールになっています
基本: JavaScript/TypeScriptにおけるArray.slice()の挙動について
Array.slice()
は、配列の一部分を切り出すためのメソッドです。このメソッドは、引数として開始位置と終了位置を指定することができます。
例えば、次のようなコードを考えてみましょう。
const fruits = ["りんご", "バナナ", "みかん", "ぶどう", "メロン"];
// 開始位置のみを指定する
console.log(fruits.slice(1)); // 出力: ["バナナ", "みかん", "ぶどう", "メロン"]
// 開始位置と終了位置を指定する
console.log(fruits.slice(1, 4)); // 出力: ["バナナ", "みかん", "ぶどう"]
この場合、fruits.slice(1)
という記述によって、配列の2番目以降の要素を切り出すことができます。また、fruits.slice(1, 4)
という記述によって、2番目から4番目の要素を切り出すことができます。
さらに、開始位置や終了位置をマイナスの値にすることもできます。この場合、末尾からの位置を表すことになります。
const fruits = ["りんご", "バナナ", "みかん", "ぶどう", "メロン"];
console.log(fruits.slice(-3)); // 出力: ["みかん", "ぶどう", "メロン"]
なお、マイナスの値を指定した場合には、開始位置が配列の長さよりも大きい場合は0、終了位置が配列の長さよりも大きい場合は配列の長さとみなされます。
const fruits = ["りんご", "バナナ", "みかん", "ぶどう", "メロン"];
console.log(fruits.slice(-10)); // 出力: ["りんご", "バナナ", "みかん", "ぶどう", "メロン"]
console.log(fruits.slice(1, -2)); // 出力: ["バナナ", "みかん"]
ChatGPT APIを例にしたユースケース
ChatGPTのAPIを使用してサービスを作るときには、トークン数を節約するために、送信するメッセージ数を制限することがあります。
その時にこのsliceの知識は役立ちます。
例えば、次のようなコードを考えてみましょう。
const messages = [
{ role: "system", content: "はじめまして。" },
{ role: "user", content: "こんにちは。天気を教えてください。" },
{ role: "assistant", content: "今日は晴れです。" },
{ role: "user", content: "ありがとうございます。" },
{ role: "assistant", content: "お役に立てて良かったです。" }
];
const limit = 3;
const slicedMessages = messages.slice(-limit);
console.log(slicedMessages);
// 出力: [
// { role: "user", content: "こんにちは。天気を教えてください。" },
// { role: "assistant", content: "今日は晴れです。" },
// { role: "user", content: "ありがとうございます。" }
// ]
上記のコードでは、配列messages
から末尾の3つの要素を切り出しています。この場合、messages.slice(-limit)
という記述によって、messages
配列の末尾から3つの要素が切り出されます。
また、もしlimit
がmessages.length
よりも大きい場合、全ての要素が切り出されます。
const messages = [
{ role: "system", content: "はじめまして。" },
{ role: "user", content: "こんにちは。天気を教えてください。" },
{ role: "assistant", content: "今日は晴れです。" }
];
const limit = 10;
const slicedMessages = messages.slice(-limit);
console.log(slicedMessages);
// 出力: [
// { role: "system", content: "はじめまして。" },
// { role: "user", content: "こんにちは。天気を教えてください。" },
// { role: "assistant", content: "今日は晴れです。" }
// ]
limit
がmessages.length
よりも大きい場合、全体を送っても制限数以下になるので、シンプルにslicedMessages = messages.slice(-limit);
という記述が成立します。
自分はこれに気づかず、回りくどい書き方してたんですけどね(汗)
最後に
この話は、chatGPTのpromptエンジニアリングを楽にするツールを作成しているときに気づいた話です
対話型のシステムに組み込みたい場合なんかに、性能を上げるためにプロンプトエンジニアリングしてると、「いちいちユーザーの入力考えて入れるのめんどくせえええ」ってなるわけです(実体験)
なので、ユーザーの入力もchatGPTに作らせてしまえばいいと思い、AI同士で対話可能なツールを作りました!
開発者の皆さんはもちろん、AI同士で話させて遊びたいだけでも見てみてください
(AgentGPTなんかと同じで今のところapi keyを入れてもらいます。もちろんopenAIのAPIサーバーにしか送ってないです!)