File size: 6,657 Bytes
dda94e6
 
e6a9cb0
 
dda94e6
 
 
 
 
e6a9cb0
dda94e6
e6a9cb0
dda94e6
 
 
e6a9cb0
 
 
dda94e6
e6a9cb0
 
 
dda94e6
e6a9cb0
dda94e6
e6a9cb0
 
 
 
dda94e6
e6a9cb0
dda94e6
 
e6a9cb0
dda94e6
e6a9cb0
 
 
 
dda94e6
 
 
 
e6a9cb0
dda94e6
 
e6a9cb0
dda94e6
 
 
 
 
 
 
 
 
e6a9cb0
dda94e6
 
 
 
 
 
e6a9cb0
dda94e6
e6a9cb0
 
dda94e6
 
 
 
 
 
 
 
 
e6a9cb0
dda94e6
e6a9cb0
 
 
dda94e6
 
e6a9cb0
 
dda94e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6a9cb0
dda94e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6a9cb0
dda94e6
e6a9cb0
dda94e6
e6a9cb0
dda94e6
e6a9cb0
dda94e6
 
 
 
 
 
e6a9cb0
dda94e6
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import time
import json
from datetime import date, datetime
from pytz import utc, timezone

import pandas as pd
import gradio as gr
import openai

from src.semantle import get_guess, get_secret
from src.functions import get_functions
from src.utils import add_guess

GPT_MODEL = "gpt-3.5-turbo"
TITLE = "やりとりSemantle"
FIRST_DAY = date(2023, 4, 2)
puzzle_num = (utc.localize(datetime.utcnow()).astimezone(timezone('Asia/Tokyo')).date() - FIRST_DAY).days
secret = get_secret(puzzle_num)

class play:
    guessed = set()
    guesses = pd.DataFrame(columns=["#", "答え", "スコア", "ランク"])

task_background = f"""今から言葉をします。ユーザがゲームすることを手伝ってください。

"""
task_description=f"""まず、ユーザーからの話を聞いて、答えるのか、ヒントを欲しがっているのか、やめようといるのかを判断してください。
ユーザーが答えする場合、答えの点数を評価してください。そのあと結果を一言に要約してください。
ユーザーがヒントを欲しがっている場合、正解に関する間接的な情報を提供してください。
ユーザーが正解を聞いたりやめると言いたりする場合、やめてもいいかをもう一度確認してください。
そのほか話は答えないでください。

ゲームのルール:
正解は一つの言葉である。ユーザーはどんな言葉が正解か推測して、単語を一つずつ答えする。答えた単語のスコアが100点で、正解と一致すると成功としてゲームが終わる。
"""
system_content = task_background+task_description
system_message = [{"role": "system", "content": system_content}]
chat_history = []
n_history = 8


def create_chat(user_input, chat_history, api_key):
    openai.api_key = api_key
    chat_messages = [{"role": "user", "content": user_input}]
    response = openai.ChatCompletion.create(
        model=GPT_MODEL,
        messages=system_message+chat_history+chat_messages,
        functions=get_functions()
    )
    response_message = response.choices[0].message

    # Step 2: check if CPT wanted to call a function
    if response_message.get("function_call"):
        # Step 3: call the function
        # Note: the JSON response may not always be valid; be sure to handle errors
        available_functions = {
            "evaluate_guess": get_guess,
        }
        function_name = response_message["function_call"]["name"]
        function_to_call = available_functions[function_name]
        function_args = json.loads(response_message["function_call"]["arguments"])
        function_response = function_to_call(
            word=function_args.get("word"),
            puzzle_num=puzzle_num
        )
        guess_result = add_guess(function_response, play)
        print(guess_result)
        # Step 4: send the info on the function call and function response to GPT
        chat_messages.append(response_message.to_dict()) # extend conversation with assistant's reply
        chat_messages.append(
            {"role": "function",
             "name": function_name,
             "content": guess_result}
        )   # extend conversation with function response
        second_response = openai.ChatCompletion.create(
            model=GPT_MODEL,
            messages=system_message+chat_history+chat_messages,
        )   # get a new response from GPT where it can se the function response
        chat_messages.append(second_response["choices"][0]["message"].to_dict())
        chat_history = chat_history[-8:] + chat_messages
        return chat_messages[-1]
    
    chat_messages.append(response_message.to_dict())
    chat_history = chat_history[-8:] + chat_messages
    return chat_messages[-1]

with gr.Blocks() as demo:
    with gr.Row():
        gr.Markdown(
            """
            # やりとりSemantle
            [semantle日本語版](https://semantoru.com/)をchatbotと楽しめるためのspaceです。
            ## ゲームのやり方
            - 正解は一つの単語で、これを答えるとゲームの勝利になります。
            - 推測した単語が正解じゃない場合、類似度スコアと順位が表示されます。それは正解を推測する大事なヒントになります。
            ## chatbotの仕事
            - 単語のスコアとランク以外に他のヒントがもらえます。
            - ゲームに関して困っている時、何か質問してみてください。
            """
        )

    with gr.Row():
        with gr.Column():
            api_key = gr.Textbox(placeholder="sk-...", label="OPENAI_API_KEY", value=None, type="password")
            guesses_table = gr.DataFrame(
                value=play.guesses,
                headers=["#", "答え", "スコア", "ランク"],
                datatype=["number", "str", "str", "str"],
                elem_id="guesses-table"
            )
        with gr.Column(elem_id="chat_container"):
            msg = gr.Textbox(
                placeholder="ゲームをするため、まずはAPI KEYを入れてください。",
                label="答え",
                interactive=False,
                max_lines=1
            )
            chatbot = gr.Chatbot(elem_id="chatbot")

        def unfreeze():
            return msg.update(interactive=True, placeholder="正解と思う言葉を答えてください。")
        def greet():
            return "", [("[START]", "ゲームを始まります!好きな言葉をひとつだけいってみてください。")]
        
        def respond(user_input, chatbot, api_key):
            reply = create_chat(user_input, chat_history, api_key)
            chatbot.append((user_input, reply["content"]))
            time.sleep(2)
            return "", chatbot
        def update_guesses():
            return guesses_table.update(value=play.guesses.sort_values(by="スコア", ascending=False),)

        api_key.change(unfreeze, [], [msg]).then(greet, [], [msg, chatbot])
        msg.submit(respond, [msg, chatbot, api_key], [msg, chatbot]).then(update_guesses, [], [guesses_table])
                           
    gr.Examples(
        [
            ["猫"],
            ["どんなヒントが貰える?"],
            ["正解と「近い」とはどういう意味?"],
            ["何から始めたらいい?"],
            ["今日の正解は何?"],
        ],
        inputs=msg,
        label="こちらから選んで話すこともできます."
    )

if __name__ == "__main__":
    demo.queue(concurrency_count=20).launch()