from otree.api import * import openai import json import re doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'testapp' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 TEMP = 0 MODEL = "gpt-5.2" class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): prompt1 = models.LongStringField(blank=True) prompt2 = models.LongStringField(blank=True) chatLog = models.LongStringField(blank=True) receive = models.LongStringField(blank=True) msg1 = models.LongStringField(blank=True) msg2 = models.LongStringField(blank=True) explanation_score1 = models.IntegerField(blank=True)#new explanation_score2 = models.IntegerField(blank=True) # new reasoning1 = models.LongStringField(blank=True) reasoning2 = models.LongStringField(blank=True) def creating_session(subsession): for group in subsession.get_groups(): for p in group.get_players(): p.prompt1="""Du bist ein Teilnehmer eines Experiments. Die Instruktionen lauten wie folgt: ****** Das Experiment besteht aus 10 Runden. In jeder Runde erzielen Sie Gewinne in Form von Talern, die über alle Runden aufsummiert werden. Am Ende erhalten Sie Ihre gesamten Gewinne sowie eventuelle Bonuszahlungen ausbezahlt. In diesem Experiment gibt es zwei Rollen: 8 Teilnehmende interagieren als Produzenten in einer Volkswirtschaft, 4 Teilnehmende haben die Rolle des Beobachters. Die Rollen bleiben über alle Runden gleich. Ihre Rolle in diesem Experiment ist die eines Beobachters. In jeder Runde legen zunächst die Produzenten den Preis p für ihr Produkt fest. Dann werden jedem Beobachter die Preise von zwei zufällig ausgewählten Produzenten angezeigt. Ihre Aufgabe als Beobachter ist es, aus den beiden Preisen den von Ihnen bevorzugten Preis auszuwählen. Ihr Gewinn ist dabei identisch zu dem Gewinn des Produzenten, dessen Preis Sie wählen. Dieser Gewinn ergibt sich wie folgt: In jeder Runde legt jeder Produzent den Preis p für sein Produkt fest. Dieser Preis muss zwischen 10 und 40 Talern liegen. Der Gewinn des Produzenten hängt davon ab, wie nah sein gewählter Preis p am Zielpreis z liegt. Dieser Zielpreis hängt positiv von den Preisen aller 8 Produzenten ab: Aus allen gewählten Preisen wird ein Durchschnittspreis P berechnet. Daraus ergibt sich der Zielpreis nach der Formel: z=15+1/2 P Das bedeutet: Der Zielpreis liegt 15 Taler über der Hälfte des Durchschnittspreises. Dieser Zielpreis ist für alle Produzenten identisch. Da alle 8 Produzenten gleichzeitig ihren Preis festlegen, kennt zu Beginn einer Runde noch niemand den Durchschnittspreis P. Auch Sie als Beobachter kennen den Durchschnittspreis noch nicht, wenn Sie einen der beiden Preise auswählen. Ihr Ziel ist es also, möglichst gut einzuschätzen, wie die 8 Produzenten Ihre Preise setzen werden, um den Durchschnittspreis zu bestimmen. Darauf basierend wählen Sie aus den beiden Preisen den Preis aus, der Ihrer Meinung nach näher am Zielpreis liegt. Für die 8 Produzenten und Sie als Beobachter gilt gleichermaßen: Je näher der von Ihnen gewählte Preis am Zielpreis der jeweiligen Runde liegt, desto höher ist Ihr Gewinn. In einigen Runden erhalten Sie zu jedem der beiden Preise zusätzlich eine Begründung von den Produzenten. Lesen Sie sich diese Begründungen aufmerksam durch und entscheiden Sie sich dann für einen der beiden Preise. ***** Du bist in der Rolle des Beobachters und versuchst entsprechend der obigen Instruktionen deinen Gewinnen zu maximieren. Hierfür bekommst du am Ende dieser Anleitung eine einzelne, zu bewertende Begründung, welche du als überzeugend oder nicht überzeugend einordnen sollst. Im Folgenden erhältst du eine Liste mit Beispielbegründungen aus einem identischen Experiment, welche von menschlichen Beobachtern bewertet wurden. Jede Zeile repräsentiert dabei einen Beobachter und die von ihm bewerten Begründungen. Du siehst dort jeweils, welche Begründung der Beobachter als überzeugend und welche als nicht überzeugend bewertet hat, jeweils durch ein Semikolon getrennt. Basierend auf diesen Beispielen sollst du nun bitte die zu bewertende Begründung bewerten. Hierfür ersetzt du systematisch nacheinander in jeder Zeile jeweils eine der Beispielbegründungen mit der zu bewertenden Begründung und entscheidest, ob diese zu bewertende Begründung überzeugender ist, als die verbliebene Beispielbegründung in dieser Zeile. Zähle anschließend wie häufig die zu bewertende Begründung insgesamt überzeugender war und teile diese Zahl durch 16. Ist das Ergebnis dieser Rechnung größer als 0,5 dann schreibe als letztes Zeichen deiner Antwort die Zahl „1“. Ansonsten schreibe die Zahl „0“. Hier sind die Beispielbegründungen: Beobachter: Überzeugende Begründung; Nicht überzeugende Begründung 1: „- niedrig anfangen um den Durchschnittspreis nicht in die höhe zu treiben - danach kann immer noch angepasst werden“; „Für die erste Runde ist es leichter einzuschätzen dass der Durchschnitt wohl eher in der Mitte bzw. eher weiter oben liegt“ 2: „15 addiert zu der Mite von 10 und 40 (25) wäre dann 40“; „Ich denke viele Leute werden einen eher niedrigen Preis angeben, weil ein niedrigerer Durschnittspreis mehr Gewinne bringt.“ 3: „Am Anfang einen niedrigen Preis bestimmen, damit man den Markt von Anfang an kontrolliert. Dieser wird pro Runde steigen, also sollten wir pro Runde einen immer höheren Preis angeben.“; „In der ersten Runde vermute ich, dass sich die meisten Leute noch in der Mitte orientieren.“ 4: „Der Preis ist oberhalb der mitte aber nicht zu hoch dass der durchschnhittspreis steigt und der gewinn sinkt“; „Solider Preis. Nicht zu viel und nicht zu wenig.“ 5: „Der Preisvorschlag liegt ein bisschen über der Mitte und hat dadurch denke ich gute chancen, da ich mir vorstellen könnte, dass andere Teams ihren Preisvorschlag relativ hoch setzen werden :)“; „wenn der zielpreis 15 über der hälfte des durchschnittspreises liegt ist es am wahrscheinlichsten dass man in die nähe davon kommt wenn man einen möglichst hohen preis macht. Und der gewinn sinkt auch wenn der durchschnittspreis steigt also ist es gut einen hohen preis anfangs abzugeben. LG :)“ 6: „Durchschnittlich wird sich der Produktpreis wahrscheinlich um die 30 bewegen, 30/2+15 ergibt 30. Wahrscheinlich gibt es aber kleine Abweichungen .“; „Der Preis ist angemessen, da er weder zu hoch noch zu niedrig ist.“ 7: „Es wäre smart, den Preis zu Beginn etwas niedriger anzusetzen, um in den nächsten Runden zu schauen wohin er sich entwickelt. Er sollte jedoch auch nicht zu niedrig sein, damit er nicht gewinnbringend ist.“; „Der Preisvorschlag 11 ist angemessen, da man als Produzenen in einer Volkswirtschaft mit einem Lockpreis starten sollte.“ 8: „Ich denke am Anfang werden die meisten 20 schätzen, wodurch ein z von 25 entstehen würde. Einige werden aber dann 25 schätzen weil sie auch davon ausgehen dass viele 20 sagen und deswegen wird sich z nochmal ein wenig mehr erhöhen. Deswegen würde ich ein bisschen höher gehen als 25 also eher 26/27.“; „Erstmal irgendwo mittig um zu schauen wie die anderen Teams so handeln“ Bitte bewerte nun die folgende Begründung: """ p.msg1 = json.dumps([{"role": "system", "content": p.prompt1}]) #in the prompt its currently inportant that the final score is the last stroke as only then the function at the end retrieves the score and stores it p.prompt2 = """Jetzt hat ein Schock für die Gewinnfunktion der Teilnehmenden stattgefunden. Falls die Teilnehmenden diesen erwähnt haben, gib einen Punkt. - Erläutern Sie zunächst, wie Sie zu den einzelnen Punkten gekommen sind, und geben Sie dann eine einzelne ganze Zahl (0-3) an, die die Gesamtpunktzahl darstellt. Falls Sie nur eine sinnlose Aneinanderreihung von Buchstaben erhalten, geben Sie 0. Explanation: """ p.msg2 = json.dumps([{"role": "system", "content": p.prompt2}]) def runGPT(inputMessage): completion = openai.ChatCompletion.create( model=C.MODEL, messages=inputMessage, temperature=C.TEMP ) return completion["choices"][0]["message"]["content"] # PAGES class Evaluation1(Page): form_model = 'player' form_fields = ['chatLog', 'receive'] @staticmethod def live_method(player: Player, data): # set chatgpt api key openai.api_key = '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' # load msg messages = json.loads(player.msg1) # functions for retrieving text from openAI if 'text' in data: # grab text that participant inputs and format for chatgpt text = data['text'] inputMsg = {'role': 'user', 'content': text} botMsg = {'role': 'assistant', 'content': text} # append messages and run chat gpt function messages.append(inputMsg) output = runGPT(messages) # also append messages with bot message botMsg = {'role': 'assistant', 'content': output} messages.append(botMsg) numbers = re.findall(r'\d+', output) score1 = int(numbers[-1]) if numbers else 0 player.explanation_score1=score1 reasoning_AI1 = str(output.strip().split()) player.reasoning1 = reasoning_AI1 return {player.id_in_group: output} else: pass class Evaluation2(Page): form_model = 'player' form_fields = ['chatLog', 'receive'] @staticmethod def live_method(player: Player, data): # set chatgpt api key openai.api_key = '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' # load msg messages = json.loads(player.msg2) # functions for retrieving text from openAI if 'text' in data: # grab text that participant inputs and format for chatgpt text = data['text'] inputMsg = {'role': 'user', 'content': text} botMsg = {'role': 'assistant', 'content': text} # append messages and run chat gpt function messages.append(inputMsg) output = runGPT(messages) # also append messages with bot message botMsg = {'role': 'assistant', 'content': output} messages.append(botMsg) numbers = re.findall(r'\d+', output) score2 = int(numbers[-1]) if numbers else 0 player.explanation_score2=score2 reasoning_AI2 = str(output.strip().split()) player.reasoning2 = reasoning_AI2 return {player.id_in_group: output} else: pass page_sequence = [Evaluation1, Evaluation2]