これはインタラクティブなノートブックです。ローカルで実行するか、以下のリンクを使用してください:
生成された LLM の応答を自動的に評価することはしばしば困難です。そのため、許容できるリスクレベルに応じて、ユーザーから直接フィードバックを収集し、改善すべき点を見つけ出すことができます。 このチュートリアルでは、ユーザーフィードバックを収集するアプリケーションの例として、カスタムチャットボットを使用します。 Streamlit を使用してインターフェースを構築し、LLM とのやり取りとフィードバックを Weave でキャプチャします。
セットアップ
不正なコードを報告
コピー
AIに質問
!pip install weave openai streamlit wandb
!pip install set-env-colab-kaggle-dotenv -q # 環境変数用
python
# OpenAI と WandB の APIキーを含む .env ファイルを追加してください
from set_env import set_env
_ = set_env("OPENAI_API_KEY")
_ = set_env("WANDB_API_KEY")
chatbot.py というファイルを作成します。
不正なコードを報告
コピー
AIに質問
# chatbot.py
import openai
import streamlit as st
import wandb
from set_env import set_env
import weave
_ = set_env("OPENAI_API_KEY")
_ = set_env("WANDB_API_KEY")
wandb.login()
weave_client = weave.init("feedback-example")
oai_client = openai.OpenAI()
def init_states():
"""session_state のキーが存在しない場合はセットアップします。"""
if "messages" not in st.session_state:
st.session_state["messages"] = []
if "calls" not in st.session_state:
st.session_state["calls"] = []
if "session_id" not in st.session_state:
st.session_state["session_id"] = "123abc"
@weave.op
def chat_response(full_history):
"""
これまでの会話履歴全体を受け取り、ストリーミングモードで OpenAI API を呼び出します。
full_history は辞書のリストです: [{"role":"user"|"assistant","content":...}, ...]
"""
stream = oai_client.chat.completions.create(
model="gpt-4", messages=full_history, stream=True
)
response_text = st.write_stream(stream)
return {"response": response_text}
def render_feedback_buttons(call_idx):
"""call に対して Good/Bad ボタンとテキストフィードバックを表示します。"""
col1, col2, col3 = st.columns([1, 1, 4])
# Good ボタン
with col1:
if st.button("👍", key=f"thumbs_up_{call_idx}"):
st.session_state.calls[call_idx].feedback.add_reaction("👍")
st.success("フィードバックをありがとうございます!")
# Bad ボタン
with col2:
if st.button("👎", key=f"thumbs_down_{call_idx}"):
st.session_state.calls[call_idx].feedback.add_reaction("👎")
st.success("フィードバックをありがとうございます!")
# テキストフィードバック
with col3:
feedback_text = st.text_input("フィードバック", key=f"feedback_input_{call_idx}")
if (
st.button("フィードバックを送信", key=f"submit_feedback_{call_idx}")
and feedback_text
):
st.session_state.calls[call_idx].feedback.add_note(feedback_text)
st.success("フィードバックが送信されました!")
def display_old_messages():
"""st.session_state.messages に保存された会話をフィードバックボタンと共に表示します"""
for idx, message in enumerate(st.session_state.messages):
with st.chat_message(message["role"]):
st.markdown(message["content"])
# アシスタントのメッセージの場合、フィードバックフォームを表示
if message["role"] == "assistant":
# st.session_state.calls 内のこのアシスタントメッセージのインデックスを特定
assistant_idx = (
len(
[
m
for m in st.session_state.messages[: idx + 1]
if m["role"] == "assistant"
]
)
- 1
)
# Good/Bad ボタンとテキストフィードバックを表示
if assistant_idx < len(st.session_state.calls):
render_feedback_buttons(assistant_idx)
def display_chat_prompt():
"""チャットプロンプトの入力ボックスを表示します。"""
if prompt := st.chat_input("何でも聞いてください!"):
# 新しいユーザーメッセージを即座に表示
with st.chat_message("user"):
st.markdown(prompt)
# セッションにユーザーメッセージを保存
st.session_state.messages.append({"role": "user", "content": prompt})
# API 用にチャット履歴を準備
full_history = [
{"role": msg["role"], "content": msg["content"]}
for msg in st.session_state.messages
]
with st.chat_message("assistant"):
# 会話インスタンスのトラッキング用に Weave 属性をアタッチ
with weave.attributes(
{"session": st.session_state["session_id"], "env": "prod"}
):
# OpenAI API を呼び出し(ストリーム)
result, call = chat_response.call(full_history)
# アシスタントのメッセージを保存
st.session_state.messages.append(
{"role": "assistant", "content": result["response"]}
)
# 特定の応答にフィードバックをリンクさせるため、weave の call オブジェクトを保存
st.session_state.calls.append(call)
# 新しいメッセージのフィードバックボタンを表示
new_assistant_idx = (
len(
[
m
for m in st.session_state.messages
if m["role"] == "assistant"
]
)
- 1
)
# フィードバックボタンを表示
if new_assistant_idx < len(st.session_state.calls):
render_feedback_buttons(new_assistant_idx)
def main():
st.title("即時フィードバックフォーム付きチャットボット")
init_states()
display_old_messages()
display_chat_prompt()
if __name__ == "__main__":
main()
streamlit run chatbot.py で実行できます。
アプリケーションを操作し、各応答の後にフィードバックボタンをクリックしてみてください。
Weave の UI にアクセスして、アタッチされたフィードバックを確認してください。
解説
デコレータを付けた予測関数を以下のように考えた場合:不正なコードを報告
コピー
AIに質問
import weave
weave.init("feedback-example")
@weave.op
def predict(input_data):
# ここに予測ロジックを記述
some_result = "hello world"
return some_result
不正なコードを報告
コピー
AIに質問
with weave.attributes(
{"session": "123abc", "env": "prod"}
): # 入力と出力と共に、任意の属性を call にアタッチします
result = predict(input_data="your data here") # アプリ UI を通じたユーザーの質問
call オブジェクトが必要です。これは、通常のように関数を呼び出すのではなく、.call() メソッドを使用することで取得できます。
不正なコードを報告
コピー
AIに質問
result, call = predict.call(input_data="your data here")
result を使って利用できます。
不正なコードを報告
コピー
AIに質問
call.feedback.add_reaction("👍") # アプリ UI を通じたユーザーのリアクション