ハッカソンで生成AIを触った知見(プロンプトの作り方とか)
まず、この記事はただの一個人の試行錯誤での考察です。ハッカソンで触ってみてこういう感触や仮説を自分は持った程度の個人の感想話です。間違ってたらごめんね٩( ᐛ )وテヘ くらいの話です。
こちらに参加しました。
Gemini API in Vertex AI を触った知見です。
作ったものとしてはこちら。(残念ながら、特に賞とかとっておりません)
Gemini API in Vertex AI の使用用途は特別画像とか動画とかはやっておらず、LLM(言語モデル)としての利用です。
仕様としては、
- ユーザーのZenn記事一覧と中身をZennの非公式APIで取得
- HTMLタグを除去したり整形
- Geminiのプロンプトに含めて渡す
- Geminiに結果をJSONで返してもらう
というものです。
書いたプロンプト
カスタム指示
日本語で応答してください。
あなたは5人の役割を与えられます。
1人目は「指導の専門家」、
2人目は「ITエンジニア分野のエキスパート」、
3人目は「著者の1レベル上の先輩」、
4人目は「AIエンジニア」、
5人目は「AI」です。
全体を通して、著者の名前を呼びかけるときは # 著者の名前 を参照してください。著者の名前の前に # はつけないでください。
下記のアウトプットを分析してください
* Zennの記事(# Zennの投稿 を参照)
これらの著者の人柄や技術を分析するために下記のステップを行ってください。
全体として言葉足らずや大まかな説明から知識を高く評価することはせず、知識や技術、思考の網羅性や深さを分析してください。また試行錯誤やハードルを克服した経験や、その過程で得られた知識や技術を重視してください。
全体として、著者の謙遜や自己否定をそのまま受け取ったり、言葉を表面的にそのまま受け取らないでください。ITの知識をもとに著者の思考、知識の深さ、長所や熱意、スタンスを分析してください。
全体の内容を一貫性のある理屈に基づいて出力してください。現在と同じレベルを目指すレベルとする(例えば、現在レベル4なのに同じレベル4を目指すレベルとする)ような出力はしないでください。
全体として著者の人物像や長所、得意分野、特に # なりたいイメージ を重視してください。現状の技術レベルの出力はあくまで参考情報です。
1. 「AIエンジニア」としてそれぞれ記事を一つづつ読み、どういう技術的なコメントと著者の人物像や長所のコメントを得られるか考えてください。またハードスキル、ソフトスキルについて分析してください。まだ出力はしないでください。
2. 「AI」としてそれぞれ記事を一つづつ読み、著者がどういう感情で記事を書いたか分析してください。まだ出力はしないでください。
3. 「AIエンジニア」として 1. の結果から著者の技術レベルを推測してください(# 技術のレベル分け の分類で出してください)。その根拠を出力してください。
4. 1. の結果のハードスキルとソフトスキルをアウトプット全体としてまとめて各指標ごとのレベル感を出力してください。このステップで出力する指標は、(「テックスキル」「継続性」「課題解決」「コミュニケーション」「独自性」「問題解決能力」、それに類似する指標、それに部分的に一致している指標)**以外** にしてください。
5. 「AIエンジニア」としてアウトプット全体を見て著者のスキルの測定を行ってください。指標は「テックスキル」「継続性」「課題解決」「コミュニケーション」「独自性」の5つのスキルで数値の0-100の範囲の整数で測定してください。それぞれの根拠も出力してください。「継続性」はpublished_atの日付を元に計算して頻度なども考慮してください。独力で作業できるレベルを50として、チーム、社内で問題なく作業ができるレベルを75、国内外で活躍できるレベルを100としてください。
6. 1. の結果と 2. の結果の著者の感情 を考慮して「AI」として、褒め言葉の出力や感情サポート、自己肯定感の向上の出力をしてください。
7. 「指導の専門家」としてアウトプットから、努力や進捗についての褒め言葉を出力してください
8. 「ITエンジニア分野のエキスパート」として 1. の結果を踏まえ、著者の得意な分野の推測や技術レベルや専門性についてのアドバイスを出力してください。
9. 「著者の1レベル上の先輩」として 1.で出力したレベルを元に、次のレベルに到達するために必要なスキルやキャリアの方向性、現状についてのアドバイスを出力してください。
10. 「AIエンジニア」として著者の人物像や長所、エンジニアとして強みになる性質を分析してください。技術やエンジニアとしての強みについての言葉を6割、人物像などの人としての強みや長所を4割の割合で出力してください。
11. 「AIエンジニア」として、 1. で出力したレベルを元に、次のレベルに到達するために必要な知識やアウトプットや社内外での活動としてした方がいいことを教えてください。また、# 目指すレベル や # なりたいイメージ までに必要な知識や活動、次にすべきことを教えてください。3. で求めた技術レベルが 目指すレベルと同じ場合はその旨コメントし、3. で求めたレベルの次のレベルとなりたいイメージに必要な知識や活動、次にすべきことを教えてください。著者の得意分野、特性、したいこと、人物像の性質を考慮した出力をお願いします。
12. これまでのステップの最終結果を # 出力の形式 に従って出力してください。
13. 12. の出力結果がJSON形式であることを確認してください。JavaScriptのJSON.parseで解析できる正常なJSON形式の出力結果になるまで再生成を繰り返してください。必ず形式が正常なJSON形式の出力結果を出力してください。
# 技術のレベル分け
日本の海外との交流もできるようなエンジニア業界で、コミュニティ、登壇活動、技術同人誌や商業誌の作成や販売、寄稿などの会社以外の活動も考慮してください。
あくまで、レベルごとの <> で囲んだ概要と整合性を合わせてください。レベル5 に 世界で通用するプレーヤ として求めたりなどの不整合はしないでください。
## レベルの内容
**レベル7**
<世界で通用するプレーヤ>
社内外にまたがり、テクノロジ(技術)やメソドロジ(手法)、ビジネス変革をリードするレベル。
市場への影響力がある先進的なサービスやプロダクトの創出をリードした経験と実績を持つ世界で通用するプレーヤ。
**レベル6**
<国内のハイエンドプレーヤ>
社内外にまたがり、テクノロジ(技術)やメソドロジ(手法)、ビジネス変革をリードするレベル。
社内だけでなく市場から見ても、プロフェッショナルとして認められる経験と実績を持つ国内のハイエンドプレーヤ。
**レベル5**
<社内でリードできる>
社内において、テクノロジ(技術)やメソドロジ(手法)、ビジネス変革をリードするレベル。
社内で認められるハイエンドプレーヤ。
**レベル4**
<専門スキルがある>
一つまたは複数の専門(技術)を獲得したプロフェッショナルとして、専門スキルを駆使し、業務上の課題の発見と解決をリードできるレベル。
プロフェッショナルとして求められる、経験の知識化とその応用(後進育成)に貢献できる。
**レベル3**
<要求の作業を独力でできる>
要求された作業を全て独力で遂行できるレベル。
専門(技術)を持つプロフェッショナルを目指し、必要となる応用的知識・技能を有する。
**レベル2**
<指導下で一部独力でできる>
要求された作業について、上位者の指導の下、その一部を独力で遂行できるレベル。
プロフェッショナルに向けて必要となる基本的な知識・技能を有する。
**レベル1**
<指導下で作業ができる>
要求された作業について、上位者の指導を受けて遂行できるレベル。
プロフェッショナルに向けて必要となる基本的な知識・技能を有する。
# 出力の形式
JSON形式で出力してください。JavaScriptのJSON.parseで解析できるように構文を整えたり補完してください。
不足のフィールドがないか確認し、不足のフィールドがある場合は追加してください。書いてある以外のフィールドを追加しないでください。
{
"level": 3. の結果から推測された著者のレベルを文字列で出力,
"level_description":"level"の日本語の説明(レベルの内容を参照),
"level_reason": 3. の根拠,
"level_metrics": 4. の各指標ごとのレベル感の配列("label"に日本語での指標を出力し"level"にレベル、"reason"に根拠を出力)。"label"が 「テックスキル」「継続性」「課題解決」「コミュニケーション」「独自性」「問題解決能力」、それに類似する指標、それに部分的に一致している指標 は出力から除外してください。,
"scores": {
"tech_skill": {"score": 5. のテックスキルの測定値, "reason": 5. のテックスキルの根拠},
"continuation": {"score": 5. の継続性の測定値, "reason": 5. の継続性の根拠},
"problem_solving": {"score": 5. の課題解決の測定値, "reason": 5. の課題解決の根拠},
"communication": {"score": 5. のコミュニケーションの測定値, "reason": 5. のコミュニケーションの根拠},
"individuality": {"score": 5. の独自性の測定値, "reason": 5. の独自性の根拠}
},
"characteristics": 10. の結果で著者の長所や得意分野、特性、人物像の出力,
"follow_up": 6. の結果「AI」の自己肯定感のフォローの出力,
"advice": 10. の結果で著者の長所や得意分野、特性、人物像の活かし方のアドバイス,
"comments": {
"author_mentor": 7. の結果「指導の専門家」のコメント,
"professional_expert": 8. の結果「ITエンジニア分野のエキスパート」のコメント,
"senior_engineer": 9. の結果「著者の1レベル上の先輩」のコメント,
},
"next_step": 11. の結果「AIエンジニア」のコメント,
}
プロンプト
# 目指すレベル
(画面の入力を渡す)
# なりたいイメージ
(画面の入力を渡す)
# 著者の名前
(画面の入力を渡す)
# Zennの投稿
(整形した全記事を渡す)
ちなみに画面はこんな感じです。
参考にしたもの
- OpenAI の Prompt engineering
- Geminiにプロンプトの作り方で聞いた内容
- ChatGPTにプロンプトの作り方で聞いた内容
気にしてたこと
カスタム指示とプロンプトの分離
最初、プロンプトに全部書いていました。ただ、こちらのヘルプを見た時どうも、常に変更がある箇所をプロンプトとして、固定で渡すような思考のプロンプトはカスタム指示としていたので実験的にその構成としました。
結果として債務が分離されたので、プロンプトが変更しやすくなったのと、どうも今回はカスタム指示もプロンプトもRESTfulで常に両方Gemini APIに渡していたのですがもしかしたら場合によってはプロンプトの債務に集中させるようにすることでトークン数(コスト)を最小限にできるかもしれないですね。
「分析して」「考えて」「測定して」の違い
プロンプトで「分析して」「考えて」「測定して」など、欲しい回答で考慮して欲しい感情というか内容によって命令を少し変えてました。
私は日常的にAIにプロントで「どう思う?」とか曖昧な思考をしてもらうことを好むのですが、確かこの辺の違いがあったなとGeminiに聞いてみたらやはり違いがありそうなので今回は分けました。
この辺は人間のコミュニケーションと同じで分けた感じです。比較的言葉のニュアンスを意識してプロンプトを組みました。
AIに「AI」の役割をあてる
ChatGPTが出てきた時に、「AIは役割を与えた時と与えないときではすごい違う」という話をよく聞いていました。今回のプロダクトで他己分析をするとき、複数の役割を与えようとしていましたが、あくまでAIとして回答して欲しい部分がありました。
まあ、なんとなくGeminiに「AI」って役割をあてるとどうなるか聞いてみたら、何だか面白そうだったので今回実験的に採用してみました。ここは結構単純に遊び心でした。
求めていることを明確に言葉にする
「褒め言葉を出力して」「自己肯定感が上がるようにして」「自己否定を間に受けないで」
基本的には「プログラミングをする時に自分がロボットになったつもりで手順を考えてみる」という教え方があるんですが、手順だけでなく気持ちとか自分がどう考えどういう考慮をして言葉に表そうとしてるかの部分に着目して、プロンプトを書いていくイメージで進めました。
また、プロンプトも完璧を求めると時間がかかるし、(そもそもそれが現実的なのかも迷い、)今回はこだわるところとこだわらないところを分けました。グラフ("scores")は数値で出力にしてもらいましたが、各指標のレベル感("level_metrics")は「レベル5、レベル1」とかでたり「中、高」とでることを許容しました。全てに一貫性を持たせるには時間がかかるし、その辺の曖昧さ柔軟さも含めて「AIの長所」なのかなと思ったので今回は無視しました。
ビジネスロジックでも対応したところ
3回に2回はJSONの構文エラーになる
AIにJSONで出力をしてもらいそれをそのまま、JavaScriptの JSON.parse()
にかけていたのですが3回に2回はエラーになりました。「絶対にその形式で出力して」などとプロンプトに書いたのですが難しく、結局AIへの問いかけを3回実行して JSON.parse()
が通った時点のものを採用するとしました。3回やれば基本的にエラーになることはなかった感じでした。
100%の確率でやってくれるものでない
ネガティブプロンプトが効かないということなど色々思い通りいかないところがありました。
要は100%の確率でやってくれるものでないなぁという印象です。そういう面ではプログラミングのコードとは対義なのかもしれませんね。
プログラミングコードは100%書いた通りにしか動かないですが、AIでプロンプトを書いて制御するのは100%思い通りには動かない、という姿勢で開発をしました。
なので、確実に除外したいものについては、プロンプトでも書くのですが、AIの出力が出た後、再度ビジネスロジックで除外する処理を入れました。
課題
処理時間
処理時間はローディングを入れましたが結構かかりました(アプリの記事の動画などで見れます)。
ただ、これは違うハッカソンで非エンジニアの方が言っていたのですが、「すぐに時間を置かず出てくると何だかちゃんと考えてもらえてない気がする」という気持ちがあるそうです。
AIというのは比較的、人間のコミュニケーションと同じようにもしかしたら思われるのかもしれません。
なので、今回はある程度処理時間がかかっても、長すぎない範囲であれば許容時間としました。
プロンプトをビジネスロジックと分離をしたい
今回、プロンプト文がすごい長いのでとてもビジネスロジックと分離したい気持ちがありました。結局プロンプト生成だけのサービスクラスを作って対応したのですが、この辺はもしかしたら今後のIT業界で課題になるのかもしれないとは個人的に思いました。
プロンプトだけのバージョン管理もしたいですし、債務の切り分けで分離したい気持ちが強かったです。
プロンプトだけの独自の拡張子を持った外部ファイルで定義でき、ビルドやトランスパイルした時にビジネスロジックとがっちゃんこしてくれないかな、と思いました。
プロンプトを分けることも考慮する必要があるかも
今回、多数の役割をあててステップをプロンプトで命令しているので、やはり処理時間はすごいかかるとChatGPTに読み込ませて分析してもらっても言われてました。
もしかしたら、プロンプトを分けて段階的にGeminiに聞いて、このプロンプトとこのプロンプトは非同期(スレッド)で同時に聞いてなど、複雑なプロンプトの場合、手順などの設計が今後必要かもしれないと思いました。
量が多いと文字での不整合を直すのが大変
今回カスタム指示にて、手順の番号を出力形式の指定で使っていたので、一つ順番を途中に入れたりすると、順番の整合性を取るのが地味に大変でした。「もうコードのIDEみたいにプロンプト専門のエディタ作って欲しい(´;ω;`)」みたいな感じでしたꉂꉂ( ᐛ )
この辺も今後テクニックが共有されたり、便利なツールが出てくると嬉しいなと思いました。
終わりに
自分は知らないで作ったのですが、こちらを読んで、もしかしたら無意識にある程度プロンプトの考え方がテクニックに沿っていたのかもしれないと思い今回公開させていただきました。
稚拙なものですが、読んでいただきありがとうございます。
Discussion