ChatPromptTemplateで、会話履歴を文字列にして、すべて人間の入力として与える
multimodal_history = [
{"type": "text", "text": "会話履歴"},
{"type": "image_url", "image_url": {"url": "base64文字列"}},
{"type": "text", "text": "続きの会話"},
]
prompt = ChatPromptTemplate.from_messages([
("human", multimodal_history)
])
※HumanMessage
で与えると変数を認識しないため("human", リスト)
形式を採用
\n
)を指定して強制的に停止することで対応chain.invoke()
の代わりにchain.stream()
を使う。、?!
)で分割コラム
音声合成のソフトVOICEVOX, COEIROINK, AivisSpeechは、GUIを立ち上げるとlocalhostでAPIが立ち上がるため、Pythonからrequestを投げるだけで、GUIを触ること無く音声合成ができる
従来の機械学習モデル | LLM利用 | |
---|---|---|
更新 | データ準備→学習→オフライン評価→オンライン評価というステップを踏む | モデル名やプロンプトで簡単に変更が可能 |
評価 | 回帰や分類など定量化しやすい | 自然言語の対話体験は評価が難しく、人間による評価が必須 |
定量評価が難しいため、一度ユーザーに受け入れられた体験を後から変えることは、従来のモデル変更よりもはるかに難易度が高い。
オンライン評価に頼るなら、ユーザーによる明示フィードバックやABテスト基盤を整える必要がある。
リリースしないとわからないオンライン評価だけに頼るわけにはいかないので、
モデル変更やプロンプト変更時にデグレが起きないかを評価する枠組みが必要
→ プロンプトは最初から洗練させておき、人間のチェックの手間を減らしたい
いろいろあるけれど...
うまく動かない時、指示を足すのではなく、一度全体を見直すことが大切
無駄に長いプロンプトは、コストと応答時間の増加、内容の把握が困難になる
LLMのプロンプトの先頭が同じなら差分計算で高速化できる技術
当初、コスパの良いGemini 2.0 Flashを利用していたが、2〜6%の頻度で異言語が混入
20回の対話で一度でも異言語が混入する確率は、
変更候補 | 結果 |
---|---|
Gemini 2.5 Flash-Lite | 同価格だが、体感性能が明らかに低下 |
Gemini 2.5 Flash (思考オフ) |
コストが3倍以上。指示の忠実さ、長文コンテキストの扱いに弱く、体感性能は劣る印象。同じ発言の繰り返し、古いメッセージへの返信、AI同士の対話で無限ループ。 |
Gemini 1.5から2.0への移行がアナウンスされたように、今後どんどんモデル更新が行われる。そのたびにメンテナンスが必要になる → 評価の枠組みがあると楽になる
統一インターフェース: モデル切り替えが簡単
トレース機能: プロンプトやレイテンシ確認
invoke
のcallbacks
に設定するだけテスト用モック
FakeListLLM
(LLMの応答文字列をモック)FakeMessagesListChatModel
(より高度にLLMの応答情報をモック)利用経験: Claude Code, Cline, Cursor, Devin, Copilot, Gemini Canvas, Google AI Studio
メリットは言うまでもないので懸念点の話:
uithub: GitHubをテキスト化 (任意のLLMへ入力しやすい)
deepwiki: 対話してリポジトリ理解
このスライドはMarkdownでスライドを作るMarpで作りました。QiitaからAIで土台を作らせ、時間をかけて直しました (ここでも人間チェック)
興味のある方はこちらから:
Web Speech APIでストリーミングASR
サーバーでバッチASR
バッチでサーバーに音声を投げるためには、発話開始/終了を検知する必要がある
対話履歴から状況説明LLMの出力を画像出力モデルに入れてシーン生成
いまだと Gemini 2.5 Flash Image (Nano Banana) ですね
タイトルのみページ番号スキップ
pdf用
<a href="https://www.youtube.com/embed/ioRYvKl0VoE"><img src="fig/youtube.png" height="450"></a>
<span class="small">トレースツールLangSmithで確認</span>
--- # 発話生成LLM - 話者決定LLMにより決まった話者の発話内容を生成 - 発話内容は**ストリーミング出力**することで、体感の待ち時間を減らす - `chain.invoke()`の代わりに`chain.stream()`を使う
1vs1の対話: ...→AI→人間→AI→人間→...