Spaces:
Runtime error
Runtime error
update prompt
Browse files- __pycache__/app.cpython-310.pyc +0 -0
- app.py +62 -36
- data/rule.md +6 -4
- src/__pycache__/functions.cpython-310.pyc +0 -0
- src/__pycache__/semantle.cpython-310.pyc +0 -0
- src/__pycache__/utils.cpython-310.pyc +0 -0
- src/functions.py +19 -15
- src/semantle.py +12 -3
- src/utils.py +0 -15
__pycache__/app.cpython-310.pyc
CHANGED
Binary files a/__pycache__/app.cpython-310.pyc and b/__pycache__/app.cpython-310.pyc differ
|
|
app.py
CHANGED
@@ -7,7 +7,6 @@ import openai
|
|
7 |
|
8 |
from src.semantle import get_guess, get_secret, get_puzzle_num
|
9 |
from src.functions import get_functions
|
10 |
-
from src.utils import add_guess
|
11 |
|
12 |
GPT_MODEL = "gpt-3.5-turbo"
|
13 |
TITLE = "やりとりイミトル"
|
@@ -15,13 +14,17 @@ TITLE = "やりとりイミトル"
|
|
15 |
with open("data/rule.md", "r", encoding="utf-8") as f:
|
16 |
RULEBOOK = "\n".join(f.readlines())
|
17 |
|
18 |
-
def
|
|
|
|
|
|
|
19 |
# Step 3: call the function
|
20 |
# Note: the JSON response may not always be valid; be sure to handle errors
|
21 |
available_functions = {
|
22 |
"guess_word": get_guess,
|
23 |
"lookup_answer": get_secret,
|
24 |
-
"
|
|
|
25 |
}
|
26 |
function_name = function_call["name"]
|
27 |
function_to_call = available_functions[function_name]
|
@@ -30,29 +33,33 @@ def _execute_function(function_call, chat_messages):
|
|
30 |
**function_args
|
31 |
)
|
32 |
if function_call["name"] == "guess_word":
|
33 |
-
|
|
|
34 |
# Step 4: send the info on the function call and function response to GPT
|
35 |
chat_messages.append(
|
36 |
{"role": "function",
|
37 |
"name": function_name,
|
38 |
-
"content": function_response
|
39 |
) # extend conversation with function response
|
40 |
next_response = openai.ChatCompletion.create(
|
41 |
model=GPT_MODEL,
|
42 |
messages=chat_messages,
|
|
|
|
|
43 |
) # get a new response from GPT where it can se the function response
|
44 |
chat_messages.append(next_response.choices[0].message.to_dict())
|
45 |
-
return next_response, chat_messages
|
46 |
|
47 |
-
def create_chat(
|
48 |
-
|
49 |
-
|
50 |
-
{"role": "system", "content":
|
51 |
-
|
52 |
response = openai.ChatCompletion.create(
|
53 |
model=GPT_MODEL,
|
54 |
messages=chat_messages,
|
55 |
-
functions=get_functions()
|
|
|
56 |
)
|
57 |
response_message = response.choices[0].message.to_dict()
|
58 |
chat_messages.append(response_message) # extend conversation with assistant's reply
|
@@ -61,22 +68,24 @@ def create_chat(key, user_input):
|
|
61 |
while response_message.get("function_call"):
|
62 |
# Step 3: call the function
|
63 |
# Note: the JSON response may not always be valid; be sure to handle errors
|
64 |
-
response_message, chat_messages = _execute_function(response_message["function_call"], chat_messages)
|
65 |
-
|
66 |
-
return chat_messages
|
67 |
|
68 |
with gr.Blocks() as demo:
|
69 |
with gr.Row():
|
70 |
gr.Markdown(
|
71 |
"""
|
72 |
-
# やりとり
|
73 |
-
[semantle日本語版](https://semantoru.com/)
|
74 |
## ゲームのやり方
|
75 |
- 正解は一つの単語で、これを答えるとゲームの勝利になります。
|
76 |
- 推測した単語が正解じゃない場合、類似度スコアと順位が表示されます。それは正解を推測する大事なヒントになります。
|
77 |
-
##
|
78 |
- 単語のスコアとランク以外に他のヒントがもらえます。
|
79 |
- ゲームに関して困っている時、何か質問してみてください。
|
|
|
|
|
80 |
"""
|
81 |
)
|
82 |
|
@@ -86,10 +95,11 @@ with gr.Blocks() as demo:
|
|
86 |
idx = gr.State(value=0)
|
87 |
guessed = gr.State(value=set())
|
88 |
guesses = gr.State(value=list())
|
89 |
-
cur_guess = gr.
|
|
|
90 |
guesses_table = gr.DataFrame(
|
91 |
-
value=pd.DataFrame(columns=["
|
92 |
-
headers=["
|
93 |
datatype=["number", "str", "number", "str"],
|
94 |
elem_id="guesses-table",
|
95 |
interactive=False
|
@@ -105,27 +115,42 @@ with gr.Blocks() as demo:
|
|
105 |
|
106 |
def unfreeze():
|
107 |
return msg.update(interactive=True, placeholder="正解と思う言葉を答えてください。")
|
108 |
-
def
|
109 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
-
def respond(
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
114 |
time.sleep(2)
|
115 |
-
return
|
116 |
|
117 |
def update_guesses(cur, i, guessed_words, guesses_df):
|
118 |
-
if cur[
|
119 |
-
guessed_words.add(cur[
|
120 |
-
|
|
|
|
|
121 |
i += 1
|
122 |
-
guesses_df = guesses_df.sort_values(by=["
|
123 |
return i, guessed_words, guesses_df
|
124 |
|
125 |
-
api_key.change(unfreeze, [], [msg]).then(
|
126 |
-
msg.submit(respond, [
|
127 |
-
|
128 |
-
)
|
129 |
|
130 |
gr.Examples(
|
131 |
[
|
@@ -140,4 +165,5 @@ with gr.Blocks() as demo:
|
|
140 |
)
|
141 |
|
142 |
if __name__ == "__main__":
|
143 |
-
demo.queue(concurrency_count=20).launch()
|
|
|
|
7 |
|
8 |
from src.semantle import get_guess, get_secret, get_puzzle_num
|
9 |
from src.functions import get_functions
|
|
|
10 |
|
11 |
GPT_MODEL = "gpt-3.5-turbo"
|
12 |
TITLE = "やりとりイミトル"
|
|
|
14 |
with open("data/rule.md", "r", encoding="utf-8") as f:
|
15 |
RULEBOOK = "\n".join(f.readlines())
|
16 |
|
17 |
+
def get_rulebook():
|
18 |
+
return RULEBOOK
|
19 |
+
|
20 |
+
def _execute_function(function_call, chat_messages, guess_result):
|
21 |
# Step 3: call the function
|
22 |
# Note: the JSON response may not always be valid; be sure to handle errors
|
23 |
available_functions = {
|
24 |
"guess_word": get_guess,
|
25 |
"lookup_answer": get_secret,
|
26 |
+
"retrieve_puzzle_num": get_puzzle_num,
|
27 |
+
"read_rule": get_rulebook,
|
28 |
}
|
29 |
function_name = function_call["name"]
|
30 |
function_to_call = available_functions[function_name]
|
|
|
33 |
**function_args
|
34 |
)
|
35 |
if function_call["name"] == "guess_word":
|
36 |
+
guess_result = function_response
|
37 |
+
print(function_response)
|
38 |
# Step 4: send the info on the function call and function response to GPT
|
39 |
chat_messages.append(
|
40 |
{"role": "function",
|
41 |
"name": function_name,
|
42 |
+
"content": f"{function_response}"}
|
43 |
) # extend conversation with function response
|
44 |
next_response = openai.ChatCompletion.create(
|
45 |
model=GPT_MODEL,
|
46 |
messages=chat_messages,
|
47 |
+
functions=get_functions(),
|
48 |
+
temperature=0
|
49 |
) # get a new response from GPT where it can se the function response
|
50 |
chat_messages.append(next_response.choices[0].message.to_dict())
|
51 |
+
return next_response.choices[0].message.to_dict(), chat_messages, guess_result
|
52 |
|
53 |
+
def create_chat(system_input, user_input, guess_result=dict()):
|
54 |
+
chat_messages = []
|
55 |
+
for s in system_input:
|
56 |
+
chat_messages.append({"role": "system", "content": s})
|
57 |
+
chat_messages.append({"role": "user", "content": user_input})
|
58 |
response = openai.ChatCompletion.create(
|
59 |
model=GPT_MODEL,
|
60 |
messages=chat_messages,
|
61 |
+
functions=get_functions(),
|
62 |
+
temperature=0
|
63 |
)
|
64 |
response_message = response.choices[0].message.to_dict()
|
65 |
chat_messages.append(response_message) # extend conversation with assistant's reply
|
|
|
68 |
while response_message.get("function_call"):
|
69 |
# Step 3: call the function
|
70 |
# Note: the JSON response may not always be valid; be sure to handle errors
|
71 |
+
response_message, chat_messages, guess_result = _execute_function(response_message["function_call"], chat_messages, guess_result)
|
72 |
+
print(chat_messages)
|
73 |
+
return response_message, chat_messages, guess_result
|
74 |
|
75 |
with gr.Blocks() as demo:
|
76 |
with gr.Row():
|
77 |
gr.Markdown(
|
78 |
"""
|
79 |
+
# やりとりxイミトル
|
80 |
+
「イミトル」は[semantle日本語版](https://semantoru.com/)の名前で、こちらはイミトルをassistantと楽しめるspaceです。
|
81 |
## ゲームのやり方
|
82 |
- 正解は一つの単語で、これを答えるとゲームの勝利になります。
|
83 |
- 推測した単語が正解じゃない場合、類似度スコアと順位が表示されます。それは正解を推測する大事なヒントになります。
|
84 |
+
## assistantの仕事
|
85 |
- 単語のスコアとランク以外に他のヒントがもらえます。
|
86 |
- ゲームに関して困っている時、何か質問してみてください。
|
87 |
+
## ご了承のお願い
|
88 |
+
- ゲームをするため、openaiのapiが必要です。答えによって少々tokenを使うようになります。
|
89 |
"""
|
90 |
)
|
91 |
|
|
|
95 |
idx = gr.State(value=0)
|
96 |
guessed = gr.State(value=set())
|
97 |
guesses = gr.State(value=list())
|
98 |
+
cur_guess = gr.JSON(visible=False)
|
99 |
+
history = gr.State(list())
|
100 |
guesses_table = gr.DataFrame(
|
101 |
+
value=pd.DataFrame(columns=["i", "guess", "sim", "rank"]),
|
102 |
+
headers=["i", "guess", "score", "rank"],
|
103 |
datatype=["number", "str", "number", "str"],
|
104 |
elem_id="guesses-table",
|
105 |
interactive=False
|
|
|
115 |
|
116 |
def unfreeze():
|
117 |
return msg.update(interactive=True, placeholder="正解と思う言葉を答えてください。")
|
118 |
+
def reset_history():
|
119 |
+
return list()
|
120 |
+
def greet(key, gradio_messages):
|
121 |
+
openai.api_key = key
|
122 |
+
system_input = [get_rulebook(), "あなたは「イミトル」というゲームの進行役です。ユーザーが答えをするところです。よろしくお願いします。"]
|
123 |
+
user_input = ""
|
124 |
+
reply, _, _ = create_chat(system_input, user_input, guess_result=dict())
|
125 |
+
gradio_messages.append(("", reply["content"]))
|
126 |
+
# gradio_messages.append(("", f"今日のゲームのパズル番号は{get_puzzle_num()}です。それでは、始めましょう!言葉を当ててみてください。"))
|
127 |
+
time.sleep(2)
|
128 |
+
return gradio_messages
|
129 |
|
130 |
+
def respond(user_input, gradio_messages, guess_result=dict()):
|
131 |
+
system_input = [get_rulebook(), """あなたは「イミトル」というゲームの進行役です。
|
132 |
+
普段、ユーザーは答えをしますが、たまにゲームに関するヒントをリクエストをします。短くても丁寧に答えてください。
|
133 |
+
ヒントを教える場合、正解を必ず隠してください。絶対、正解を言わないでください。"""]
|
134 |
+
|
135 |
+
_user_input = "答え:" + user_input
|
136 |
+
reply, messages, guess_result = create_chat(system_input, _user_input, guess_result=dict())
|
137 |
+
gradio_messages.append((user_input, reply["content"]))
|
138 |
time.sleep(2)
|
139 |
+
return gradio_messages, guess_result
|
140 |
|
141 |
def update_guesses(cur, i, guessed_words, guesses_df):
|
142 |
+
if cur.get('guess') and cur['guess'] not in guessed_words:
|
143 |
+
guessed_words.add(cur['guess'])
|
144 |
+
cur['sim'] = round(cur['sim'], 2)
|
145 |
+
cur['i'] = i
|
146 |
+
guesses_df.loc[i] = cur
|
147 |
i += 1
|
148 |
+
guesses_df = guesses_df.sort_values(by=["sim"], ascending=False)
|
149 |
return i, guessed_words, guesses_df
|
150 |
|
151 |
+
api_key.change(unfreeze, [], [msg]).then(reset_history, [], [history]).then(greet, [api_key, chatbot], [chatbot])
|
152 |
+
msg.submit(respond, [msg, chatbot, cur_guess], [chatbot, cur_guess])
|
153 |
+
cur_guess.change(update_guesses, [cur_guess, idx, guessed, guesses_table], [idx, guessed, guesses_table])
|
|
|
154 |
|
155 |
gr.Examples(
|
156 |
[
|
|
|
165 |
)
|
166 |
|
167 |
if __name__ == "__main__":
|
168 |
+
demo.queue(concurrency_count=20).launch()
|
169 |
+
# demo.queue(concurrency_count=20).launch()
|
data/rule.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1 |
-
# イミトル
|
2 |
|
3 |
## ゲームの遊び方
|
4 |
今日の言葉を当てるゲームです。 正解と推測される単語を答えると、正解かどうかがわかります。正解でない場合、正解に近い度合いと順位がわかります。正解に近い程度とは単語の意味や文脈、単語の言語的特性などによって決まります。 推測した単語の近い度合いと順位を参考にして、答えを当て続けてみてください。
|
5 |
-
もし正解が難しかったり、ゲームのルールがわかりにくい場合は、ヒントを求めることができます。正解を直接聞くことはできませんが、正解に関する様々な情報を得ることができます。
|
6 |
|
7 |
-
##
|
8 |
-
|
|
|
|
|
|
|
|
1 |
+
# イミトル
|
2 |
|
3 |
## ゲームの遊び方
|
4 |
今日の言葉を当てるゲームです。 正解と推測される単語を答えると、正解かどうかがわかります。正解でない場合、正解に近い度合いと順位がわかります。正解に近い程度とは単語の意味や文脈、単語の言語的特性などによって決まります。 推測した単語の近い度合いと順位を参考にして、答えを当て続けてみてください。
|
|
|
5 |
|
6 |
+
## ヒントのについて
|
7 |
+
もし正解が難しかったり、ゲームのルールがわかりにくい場合は、ヒントを求めることができます。正解単語を使う例文、正解単語とある単語の意味や文法的な共通点など正解に関する様々な情報を聞くことができます。正し、ヒントに正解単語は`<mask>`などで隠すようになっています。
|
8 |
+
|
9 |
+
## 「近い度合いと順位」について
|
10 |
+
「近い度合い」は正解単語との類似度で、-100から+100までの数字で表します。「順位」はデータベースの中、近い度合いの相対的な位置で、1位から1000位まで表します。「近い度合い('sim')」が100の単語が正解単語です。
|
src/__pycache__/functions.cpython-310.pyc
CHANGED
Binary files a/src/__pycache__/functions.cpython-310.pyc and b/src/__pycache__/functions.cpython-310.pyc differ
|
|
src/__pycache__/semantle.cpython-310.pyc
CHANGED
Binary files a/src/__pycache__/semantle.cpython-310.pyc and b/src/__pycache__/semantle.cpython-310.pyc differ
|
|
src/__pycache__/utils.cpython-310.pyc
CHANGED
Binary files a/src/__pycache__/utils.cpython-310.pyc and b/src/__pycache__/utils.cpython-310.pyc differ
|
|
src/functions.py
CHANGED
@@ -7,25 +7,25 @@ guess_word = {"name": "guess_word",
|
|
7 |
"type": "string",
|
8 |
"description": "A single Japanese word to guess, which is can be a noun, verb, adverb or adjective. e.g. 空, 近い, 行く, etc."
|
9 |
},
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
},
|
15 |
-
"required": ["word"
|
16 |
}}
|
17 |
|
18 |
lookup_answer = {"name": "lookup_answer",
|
19 |
-
"description": "
|
20 |
"parameters": {
|
21 |
"type": "object",
|
22 |
"properties": {
|
23 |
-
"puzzle_num": {
|
24 |
-
|
25 |
-
|
26 |
}
|
27 |
-
},
|
28 |
-
"required": ["puzzle_num"]
|
29 |
}}
|
30 |
|
31 |
retrieve_puzzle_num = {"name": "retrieve_puzzle_num",
|
@@ -52,14 +52,18 @@ update_history = {"name": "update_history",
|
|
52 |
},
|
53 |
"required": ["current_guess", "guess_history"]
|
54 |
}}
|
55 |
-
|
56 |
-
"description": "Use this function to
|
57 |
-
"
|
58 |
"type": "object",
|
59 |
"properties": {},
|
60 |
}}
|
61 |
|
62 |
|
63 |
def get_functions():
|
64 |
-
functions = [guess_word,
|
|
|
|
|
|
|
|
|
65 |
return functions
|
|
|
7 |
"type": "string",
|
8 |
"description": "A single Japanese word to guess, which is can be a noun, verb, adverb or adjective. e.g. 空, 近い, 行く, etc."
|
9 |
},
|
10 |
+
# "puzzle_num": {
|
11 |
+
# "type": "integer",
|
12 |
+
# "description": "An index indicating today's puzzle."
|
13 |
+
# }
|
14 |
},
|
15 |
+
"required": ["word"]
|
16 |
}}
|
17 |
|
18 |
lookup_answer = {"name": "lookup_answer",
|
19 |
+
"description": "Use this function to check the correct answer of today's puzzle.",
|
20 |
"parameters": {
|
21 |
"type": "object",
|
22 |
"properties": {
|
23 |
+
# "puzzle_num": {
|
24 |
+
# "type": "integer",
|
25 |
+
# "description": "An index indicating today's puzzle."
|
26 |
}
|
27 |
+
# },
|
28 |
+
# "required": ["puzzle_num"]
|
29 |
}}
|
30 |
|
31 |
retrieve_puzzle_num = {"name": "retrieve_puzzle_num",
|
|
|
52 |
},
|
53 |
"required": ["current_guess", "guess_history"]
|
54 |
}}
|
55 |
+
read_rule = {"name": "read_rule",
|
56 |
+
"description": "Use this function to read the game rule for clarification of your response.",
|
57 |
+
"parameters": {
|
58 |
"type": "object",
|
59 |
"properties": {},
|
60 |
}}
|
61 |
|
62 |
|
63 |
def get_functions():
|
64 |
+
functions = [guess_word,
|
65 |
+
lookup_answer,
|
66 |
+
# retrieve_puzzle_num,
|
67 |
+
# update_history,
|
68 |
+
read_rule]
|
69 |
return functions
|
src/semantle.py
CHANGED
@@ -2,7 +2,8 @@ from datetime import date, datetime
|
|
2 |
from pytz import utc, timezone
|
3 |
import requests
|
4 |
|
5 |
-
def get_secret(
|
|
|
6 |
request_url = f"https://semantoru.com/yesterday/{puzzle_num+1}"
|
7 |
response = requests.get(request_url, timeout=5)
|
8 |
if response.status_code == 200:
|
@@ -10,12 +11,20 @@ def get_secret(puzzle_num: int):
|
|
10 |
else:
|
11 |
return "Not found error."
|
12 |
|
13 |
-
def get_guess(word: str
|
|
|
14 |
request_url = f"https://semantoru.com/guess/{puzzle_num}/{word}"
|
|
|
15 |
response = requests.get(request_url, timeout=5)
|
16 |
print(response.status_code)
|
17 |
if response.status_code == 200:
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
else:
|
20 |
return {"guess": word,
|
21 |
"sim": None,
|
|
|
2 |
from pytz import utc, timezone
|
3 |
import requests
|
4 |
|
5 |
+
def get_secret():
|
6 |
+
puzzle_num = get_puzzle_num()
|
7 |
request_url = f"https://semantoru.com/yesterday/{puzzle_num+1}"
|
8 |
response = requests.get(request_url, timeout=5)
|
9 |
if response.status_code == 200:
|
|
|
11 |
else:
|
12 |
return "Not found error."
|
13 |
|
14 |
+
def get_guess(word: str):
|
15 |
+
puzzle_num = get_puzzle_num()
|
16 |
request_url = f"https://semantoru.com/guess/{puzzle_num}/{word}"
|
17 |
+
print(request_url)
|
18 |
response = requests.get(request_url, timeout=5)
|
19 |
print(response.status_code)
|
20 |
if response.status_code == 200:
|
21 |
+
rtn = response.json()
|
22 |
+
print(rtn)
|
23 |
+
if rtn['rank'] == '正解!':
|
24 |
+
return rtn
|
25 |
+
elif rtn['rank'] > 1000:
|
26 |
+
rtn['rank'] = '?'
|
27 |
+
return rtn
|
28 |
else:
|
29 |
return {"guess": word,
|
30 |
"sim": None,
|
src/utils.py
CHANGED
@@ -1,18 +1,3 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
def add_guess(guess_result, guessed, guesses):
|
4 |
-
word, sim, rank = guess_result
|
5 |
-
if sim:
|
6 |
-
if word not in guessed:
|
7 |
-
sim = round(sim, 2)
|
8 |
-
rank = "情報なし" if rank == 1001 else rank
|
9 |
-
guesses.loc[len(guessed)] = ([len(guessed), word, sim, rank])
|
10 |
-
guessed.add(word)
|
11 |
-
cur_result = format_result(word, sim, rank)
|
12 |
-
else:
|
13 |
-
cur_result = "不正解: 正しくない単語"
|
14 |
-
return "\n".join([cur_result, "最高スコア:", format_table(guesses)]), guessed, guesses
|
15 |
-
|
16 |
def format_result(word, sim, rank):
|
17 |
return f"{word}: スコア {sim}, ランク {rank}"
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
def format_result(word, sim, rank):
|
2 |
return f"{word}: スコア {sim}, ランク {rank}"
|
3 |
|