Created
June 13, 2024 19:16
-
-
Save johnowhitaker/b2a81394c5a3bd6ecda05c9ee42fa56c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests, json, glob | |
# Set up | |
api_key = ... | |
GPT_MODEL = "gpt-4-1106-preview" | |
# Read the wordlist and solution from a file | |
def get_words(idx=0): | |
files = sorted(glob.glob("connections_data/*.json")) | |
f = open(files[idx]) | |
data = json.load(f) | |
f.close() | |
shuffled_words = [w.lower() for group in data["startingGroups"] for w in group] | |
solution = data["groups"] | |
return shuffled_words, solution | |
# Format prompts | |
def get_prompts(shuffled_words): | |
main_prompt = f"""You are an expert word puzzle solver. | |
Play the Connections word game using the provided list of 16 words: {shuffled_words}. The objective is to identify groups of four words that share a common characteristic. Follow these steps to formulate your answer: | |
- Understand the rules: You must find groups of four items that have something specific in common. For example, if the commonality is 'fish,' valid words could be 'Bass, Flounder, Salmon, Trout.' Categories will be more specific than broad labels like '5-LETTER WORDS' or 'NAMES.' | |
- Brainstorm potential categories: Think broadly about the words. Consider their meanings, linguistic properties, cultural references, etc. Create a list of potential categories, aiming for more than four to start with. | |
- Formulate a hypothesis: Choose the most likely groups of four from your brainstormed list. For instance, if the words were 'Ant, Drill, Island, Opal,' and they all can be prefixed with 'Fire,' that's a valid group. Explain why you believe these groups fit together. | |
- Reflect on the grouping: Review your chosen groups and ensure each group adheres to the rule of sharing a specific commonality. Be wary of words that may fit into multiple categories and adjust accordingly. | |
- Finalize and submit: Make any necessary adjustments based on your reflection, then present your final answer. The solution should consist of four distinct groups of words, with each word used only once. | |
Begin by listing all possible groupings, refine your choices, and conclude with your final set of four groups. No word should be in two groupings. | |
""" | |
user_prompt = f"""Reminder, the words are: {shuffled_words}. | |
Use the function provided for your final submission.""" | |
return main_prompt, user_prompt | |
# From OpenAI cookbook | |
def chat_completion_request(messages, tools=None, tool_choice=None, model=GPT_MODEL): | |
headers = { | |
"Content-Type": "application/json", | |
"Authorization": "Bearer " + api_key, | |
} | |
json_data = {"model": model, "messages": messages} | |
if tools is not None: | |
json_data.update({"tools": tools}) | |
if tool_choice is not None: | |
json_data.update({"tool_choice": tool_choice}) | |
try: | |
response = requests.post( | |
"https://api.openai.com/v1/chat/completions", | |
headers=headers, | |
json=json_data, | |
) | |
return response | |
except Exception as e: | |
print("Unable to generate ChatCompletion response") | |
print(f"Exception: {e}") | |
return e | |
# Define the "function" we'll use to get structured output from the model | |
# In my defence this was written before breakfast! | |
tools = [ | |
{ | |
"type": "function", | |
"function": { | |
"name": "submit_goups", | |
"description": "Submit four groups of four words", | |
"parameters": { | |
"type": "object", | |
"properties": { | |
"group1_description": { | |
"type": "string", | |
"description": "The thing the first group of four words have in common", | |
}, | |
"group1": { | |
"type": "string", | |
"description": "The first group of four words", | |
}, | |
"group2_description": { | |
"type": "string", | |
"description": "The thing the second group of four words have in common", | |
}, | |
"group2": { | |
"type": "string", | |
"description": "The second group of four words", | |
}, | |
"group3_description": { | |
"type": "string", | |
"description": "The thing the third group of four words have in common", | |
}, | |
"group3": { | |
"type": "string", | |
"description": "The third group of four words", | |
}, | |
"group4_description": { | |
"type": "string", | |
"description": "The thing the fourth group of four words have in common", | |
}, | |
"group4": { | |
"type": "string", | |
"description": "The fourth group of four words", | |
}, | |
}, | |
"required": ["group1_description", "group1", "group2_description", "group2", "group3_description", "group3", "group4_description", "group4"], | |
}, | |
} | |
}, | |
] | |
# Solution | |
def solve(idx=0): | |
# Get the words and solution | |
shuffled_words, solution = get_words(idx) | |
# Format prompts | |
main_prompt, user_prompt = get_prompts(shuffled_words) | |
# Start the chat | |
messages = [] | |
messages.append({"role": "system", "content": main_prompt}) | |
messages.append({"role": "user", "content": user_prompt}) | |
# Get first response with "reasoning" and proposed answer | |
chat_response = chat_completion_request( | |
messages, | |
) | |
assistant_message = chat_response.json()["choices"][0]["message"] | |
messages.append(assistant_message) | |
print("First response:", assistant_message) | |
# Have it re-submit with the function | |
messages.append({"role": "user", "content": "Great, please re-submit with this function"}) | |
chat_response = chat_completion_request( | |
messages, tools=tools, | |
tool_choice={"type": "function", "function": {"name": "submit_goups"}} | |
) | |
assistant_message = chat_response.json()["choices"][0]["message"] | |
messages.append(assistant_message) | |
print("Second response:", assistant_message) | |
# Pretty-print | |
print("### MODEL GUESSES ###") | |
for k, v in json.loads(assistant_message['tool_calls'][0]['function']['arguments']).items(): | |
print(k, ":", v) | |
print("### SOLUTION ###") | |
for k, v in solution.items(): | |
print(k, ":", v) | |
return assistant_message, solution | |
if __name__ == "__main__": | |
solve(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment