1K Views
March 22, 24
スライド概要
2024/03/22 LT発表資料
https://yumenosora.connpass.com/event/311293/
name: - いけだしんのすけ work: - インフラ・情シス like: - バイク - 読書 - 映画 - アニメ - ゲーム
LLMのプロンプトを自動テストした際の苦労(仮) プロンプトの評価ツール promptfooって知ってる?
自己紹介 name: いけだしんのすけ X: @orc_jj like: - バイク - 読書 - 映画 - アニメ work: - インフラ ・ SRE certification: - Azure Solutions Architect Expert - Azure Developer Associate - AWS Solutions Architect Associate etc.. topic: - 子供が小学校2年生に LLMに負けず劣らずの 成長の速さに驚き
ここ最近... 最近はもっぱらLLMのモデル性能についての話題が盛りだくさん。 また、システムプロンプトのチューニングも重要課題に (もはや必須 といってもいいのかも)
悩み... 新しいモデルが出るたびに、現在使ってるモデルとの比較を イチイチAPI叩いて確認して、それを報告用の表にまとめて... 正直ちょっとめんどい..
promptfoo (プロンプトフー) って? https://promptfoo.dev/
やってみた結果
こんな感じで評価結果が確認できた export OPENAI_API_KEY=<APIKEY> npx promptfoo@latest eval npx promptfoo@latest view
CSVとかでも結果出せるし… これいいじゃん!
基本的な定義ファイル(yaml) の記載 プロンプトを複数用意 実行するモデルを羅列 description: 'My first eval’ prompts: - file://prompt/prompt1.json - file://prompt/prompt2.json providers: - id: openai:gpt-3.5-turbo config: temperature: 0.5 max_tokens: 1000 JsonやTxt形式で用意 同一プロンプトで複数の モデルをテスト - id: openai:gpt-4 config: temperature: 0.5 max_tokens: 1000 tests: - vars: topic: バナナ assert: - type: contains value: バナナ 評価する内容 文中に単語が存在し ているか - type: llm-rubric value: 出力にユーモアが含まれていない事を確認する。 provider: id: openai:gpt-4 - type: similar value: バナナは食物繊維がたっぷりです。 threshold: 0.85 provider: id: openai:embeddings:text-embedding-ada-002002 LLMで生成した回答 を、またLLMで評価 する 指定した文章との類似度を 計測
prompts:
- file://prompt/prompt1.json
- file://prompt/prompt2.json
用意するプロンプトはよく見る
下記の形
[
{
"role": "system",
"content": "あなたは猫です。{{topic}}の内容について面白おかしく雑学を言ってください。"
},
{
"role": "user",
"content": "{{topic}}でお願いします。"
}
]
Providers 主要なAIサービスは大 体網羅している。 ・OpenAI ・Amazon Bedrock ・Azure OpenAI ・Google AI Studio etc… https://www.promptfoo.dev/docs/providers
評価の種類 手法 内容 Deterministic metrics LLMの出力に対して実行されるアサーションテスト (例) 期待される文字列が存在するか Model-graded metrics LLMモデルを使ったアサーションテスト (例) 期待する回答と同じような内容かどうか確認させる。 Javascript assertions カスタム JavaScript 関数での評価を実行 Python assertions カスタム Python 関数での評価を実行 Similarity (embeddings) コサイン類似度のしきい値を使用して、LLM の出力の埋め込み が期待値と意味的に類似しているかどうかをチェック。 Classifier grading LLM 出力を HuggingFace テキスト分類器に通す。 (例) 出力に有害文章が含まれるか否か。
独自関数を作ってそれを実行することもできる 手法 内容 Deterministic metrics LLMの出力に対して実行されるアサーションテスト (例) 期待される文字列が存在するか Model-graded metrics LLMモデルを使ったアサーションテスト (例) 期待する回答と同じような内容かどうか確認させる。 Javascript assertions カスタム JavaScript 関数での評価を実行 Python assertions カスタム Python 関数での評価を実行 Similarity (embeddings) コサイン類似度のしきい値を使用して、LLM の出力の埋め込み が期待値と意味的に類似しているかどうかをチェック。 Classifier grading LLM 出力を HuggingFace テキスト分類器に通す。 (例) 出力に有害文章が含まれるか否か。
(以下はRAGで回答を生成する関数の例)
★ 関数名は’call_api’ じゃないと駄目
★ options[“config”]にパラメータが渡ってくる
def call_api(prompt, options, context):
prompt_file_path = options["config"].get(“system_prompt_file_path", "")
search_client = SearchClient(service_endpoint, index_name, credential=credential)
vector_query = VectorizedQuery(vector=get_embedding(prompt),
k_nearest_neighbors=2,
fields="vectorContent")
documents = search_client.search(
search_text=prompt,
vector_queries= [vector_query],
select=["Q", "A"],
)
ans_items = "¥n".join(f'A: {doc["A"]}' for doc in documents)
system_prompt = get_prompt(prompt_file_path, prompt, ans_items)
★ 戻り値は{“output”: 文字列} の形にする
completion = openai.chat.completions.create(
model="gpt-35-turbo-16k",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt},
],
temperature=0.5,
)
return { "output": completion.choices[0].message.content }
実行モデルを指定するところに、 Pythonファイル名を指定してあげ ればOK。 関数に渡したいパラメータはconfig: に 記述できる。 … providers: - id: python:retrieval.py config: prompt_file_path: prompts/system_prompts/system_prompt1.txt - id: python:retrieval.py config: prompt_file_path: prompts/ system_prompts /system_prompt2.txt tests: - vars: topic: 有給の取得方法を教えて 以降の書き方は同じ assert: - type: contains value: 有給の取得方法はまず...
Github Actionsでも name: 'Prompt Evaluation' on: pull_request: branches: - 'main' jobs: evaluate: runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - uses: actions/checkout@v4 ローカルの実行と同じ用に WEB画面形式で確認可能 - name: Set up promptfoo cache uses: actions/cache@v3 with: path: ~/.cache/promptfoo key: ${{ runner.os }}-promptfoo-v1 restore-keys: | ${{ runner.os }}-promptfoo- name: Run promptfoo evaluation uses: promptfoo/promptfoo-action@v1 with: openai-api-key: ${{ secrets.OPENAI_API_KEY }} github-token: ${{ secrets.GITHUB_TOKEN }} prompts: 'promptfoo/prompt/*.json' config: 'promptfoo/promptfooconfig.yaml' cache-path: ~/.cache/promptfoo
ドキュメント通りやれば簡単に実行できます! https://promptfoo.dev/docs/getting-started
まとめ ● 始めるの簡単、分かりやすい ● 評価結果は意外と見やすい ● CSVやHTMLでも評価結果を出力できるの嬉しい ● 当たり前だが、LLMの評価をLLMに行わせるとトークン消費 量ハンパない。 ● まだ若いツールなので、情報は少なめ
ご清聴有難うございました。