An AI-powered blog

Kategorie: Programmieren mit ChatGPT

Ableiten eines JSON-Schemas aus JSON-Daten

In der Welt der Softwareentwicklung und Datenverwaltung hat sich JSON (JavaScript Object Notation) aufgrund seiner Einfachheit und Flexibilität als beliebte Wahl zur Strukturierung und Austausch von Daten etabliert. JSON bietet eine bequeme Möglichkeit, komplexe Datenstrukturen darzustellen, die sowohl von Menschen als auch von Maschinen leicht verstanden und verarbeitet werden können. Bei der Arbeit mit großen JSON-Datensätzen können jedoch manchmal Herausforderungen auftreten, insbesondere wenn es um die Gewährleistung von Datenintegrität und Validierung geht. Hier kommt GPT (Generative Pre-trained Transformer) ins Spiel und bietet eine leistungsstarke Lösung, um ein JSON-Schema aus JSON-Daten abzuleiten.

Das JSON-Schema

Bevor wir uns in die Magie von GPT vertiefen, wollen wir kurz über JSON-Schema sprechen. JSON-Schema ist eine Vokabular, mit dem Sie JSON-Dokumente annotieren und validieren können. Es bietet eine formale Definition der erwarteten Struktur, Datentypen und Einschränkungen für einen bestimmten JSON-Datensatz. Durch die Definition eines JSON-Schemas können Sie sicherstellen, dass die Daten bestimmten Regeln und Anforderungen entsprechen, was eine robuste Validierung und effiziente Datenverarbeitung ermöglicht.

Nutzung von GPT zur Ableitung eines JSON-Schemas

GPT, basierend auf seinen fortschrittlichen natürlichsprachlichen Verarbeitungsfähigkeiten, kann genutzt werden, um aus vorhandenen JSON-Inhalten ein JSON-Schema abzuleiten. Es ist kein Training erforderlich, da GPT (in diesem Fall Version 3.5) alles mitbringt, was Sie benötigen. Alles, was Sie brauchen, ist ein Zugang zur OpenAI-API und einen geeigneten Prompt wie den folgenden, der GPT anweist, sich wie eine Python-Funktion mit Eingabe und Rückgabewert zu verhalten:

"role": "system", "content": "You are a python function to analyze JSON string input to generate a JSON schema from it as a JSON string result"
"role": "user", "content": "Extract the JSON schema of the following JSON content and return it as a JSON string. Treat NULL-Values as optional: {JSON CONTENT}"

In unserem Fall verwenden wir die folgende JSON-Beispieldatei, um das geeignete Schema zu bestimmen:

{
"articles": [
  {
	"url": "https://www.britannica.com:443/technology/artificial-intelligence",
	"url_mobile": null,
	"title": "Artificial intelligence ( AI ) | Definition , Examples , Types , Applications , Companies , & Facts",
	"seendate": "20230612T054500Z",
	"socialimage": "https://cdn.britannica.com/81/191581-050-8C0A8CD3/Alan-Turing.jpg",
	"domain": "britannica.com",
	"language": "English",
	"sourcecountry": "United States",
	"id": 1
  },
  {
	"url": "https://www.drive.com.au/news/jeep-says-artificial-intelligence-is-heading-off-road/",
	"url_mobile": null,
	"title": "Jeep says Artificial Intelligence is heading off - road",
	"seendate": "20230611T203000Z",
	"socialimage": "https://images.drive.com.au/driveau/image/upload/c_fill,f_auto,g_auto,h_675,q_auto:good,w_1200/cms/uploads/mm6gqcquwz10snybg79k",
	"domain": "drive.com.au",
	"language": "English",
	"sourcecountry": "Australia",
	"id": 2
  },
  {
	"url": "https://labusinessjournal.com/featured/artificial-intelligence-on-call/",
	"url_mobile": null,
	"title": "Artificial intelligence on Call - Los Angeles Business Journal",
	"seendate": "20230612T080000Z",
	"socialimage": "https://images.labusinessjournal.com/wp-content/uploads/2023/06/SR_COVEROPTION_Pearl-Second-Opinion-dentist-with-patietn-point-at-caries-HiRes-copy.jpg",
	"domain": "labusinessjournal.com",
	"language": "English",
	"sourcecountry": "United States",
	"id": 3
  },
  {
	"url": "https://www.emirates247.com/uae/artificial-intelligence-office-organises-ai-enabled-entrepreneurs-conference-in-collaboration-with-nvidia-2023-06-11-1.712994",
	"url_mobile": "https://www.emirates247.com/uae/artificial-intelligence-office-organises-ai-enabled-entrepreneurs-conference-in-collaboration-with-nvidia-2023-06-11-1.712994?ot=ot.AMPPageLayout",
	"title": "Artificial Intelligence Office organises AI - Enabled Entrepreneurs conference in collaboration with NVIDIA",
	"seendate": "20230611T194500Z",
	"socialimage": "https://www.emirates247.com/polopoly_fs/1.712995.1686498090!/image/image.jpg",
	"domain": "emirates247.com",
	"language": "English",
	"sourcecountry": "United Arab Emirates",
	"id": 4
  },
  {
	"url": "https://www.business-standard.com/india-news/ai-offers-new-opportunities-also-brings-threats-to-privacy-amitabh-kant-123061200521_1.html",
	"url_mobile": "https://www.business-standard.com/amp/india-news/ai-offers-new-opportunities-also-brings-threats-to-privacy-amitabh-kant-123061200521_1.html",
	"title": "AI offers new opportunities , also brings threats to privacy : Amitabh Kant",
	"seendate": "20230612T120000Z",
	"socialimage": "https://bsmedia.business-standard.com/_media/bs/img/article/2023-02/14/full/1676346078-2487.jpg",
	"domain": "business-standard.com",
	"language": "English",
	"sourcecountry": "India",
	"id": 5
  },
  {
	"url": "https://www.jamaicaobserver.com/latest-news/tufton-says-pnp-using-ai-to-spread-misinformation-threaten-democracy/",
	"url_mobile": "https://www.jamaicaobserver.com/latest-news/tufton-says-pnp-using-ai-to-spread-misinformation-threaten-democracy/amp/",
	"title": "Tufton says PNP using AI to spread misinformation , threaten democracy",
	"seendate": "20230612T010000Z",
	"socialimage": "https://imengine.public.prod.jam.navigacloud.com/?uuid=49085626-2689-402B-BA2C-7224FE707AF4&function=fit&type=preview",
	"domain": "jamaicaobserver.com",
	"language": "English",
	"sourcecountry": "Jamaica",
	"id": 6
  },
  {
	"url": "https://www.foxnews.com/world/chatgpt-delivers-sermon-packed-german-church-tells-congregants-fear-death",
	"url_mobile": "https://www.foxnews.com/world/chatgpt-delivers-sermon-packed-german-church-tells-congregants-fear-death.amp",
	"title": "ChatGPT delivers sermon to packed German church , tells congregants not to fear death",
	"seendate": "20230611T151500Z",
	"socialimage": "https://static.foxnews.com/foxnews.com/content/uploads/2023/06/Fuerth3.jpg",
	"domain": "foxnews.com",
	"language": "English",
	"sourcecountry": "United States",
	"id": 7
  },
  {
	"url": "https://www.standardmedia.co.ke/opinion/article/2001474967/lets-embrace-ai-for-better-efficient-future-of-work",
	"url_mobile": "https://www.standardmedia.co.ke/amp/opinion/article/2001474967/lets-embrace-ai-for-better-efficient-future-of-work",
	"title": "Let embrace AI for better , efficient future of work",
	"seendate": "20230611T143000Z",
	"socialimage": "https://cdn.standardmedia.co.ke/images/articles/thumbnails/fnIyghHfNlwyrVSTk7HEFSkG6Mb3IkndZiu2Yg6v.jpg",
	"domain": "standardmedia.co.ke",
	"language": "English",
	"sourcecountry": "Kenya",
	"id": 8
  },
  {
	"url": "https://techxplore.com/news/2023-06-chatbot-good-sermon-hundreds-church.html",
	"url_mobile": "https://techxplore.com/news/2023-06-chatbot-good-sermon-hundreds-church.amp",
	"title": "Can a chatbot preach a good sermon ? Hundreds attend church service generated by ChatGPT to find out",
	"seendate": "20230611T140000Z",
	"socialimage": "https://scx2.b-cdn.net/gfx/news/hires/2023/can-a-chatbot-preach-a.jpg",
	"domain": "techxplore.com",
	"language": "English",
	"sourcecountry": "United States",
	"id": 9
  },
  {
	"url": "https://technology.inquirer.net/125039/openai-ceo-asks-china-to-help-create-ai-rules",
	"url_mobile": "https://technology.inquirer.net/125039/openai-ceo-asks-china-to-help-create-ai-rules/amp",
	"title": "OpenAI CEO Asks China For AI Rule Making | Inquirer Technology",
	"seendate": "20230612T074500Z",
	"socialimage": "https://technology.inquirer.net/files/2023/06/pexels-andrew-neel-15863000-620x349.jpg",
	"domain": "technology.inquirer.net",
	"language": "English",
	"sourcecountry": "Philippines",
	"id": 10
  }
]
}

In den nächsten Schritten implementieren wir einige kurze Python-Skripte, um die JSON-Datei zu lesen und eine OpenAI-API-Anfrage zu stellen. Zuerst verwenden wir den folgenden Wrapper für den API-Aufruf:

import os
import openai

class OpenAIWrapper:
    def __init__(self, temperature):
        self.key = os.environ["OPENAI_API_KEY"]
        self.chat_model_id = "gpt-3.5-turbo-0613"
        self.temperature = temperature
        self.max_tokens = 2048
        self.top_p = 1
        self.time_out = 7
    
    def run(self, prompt):
        return self._post_request_chat(prompt)

    def _post_request_chat(self, messages):
        try:
            openai.api_key = self.key
            response = openai.ChatCompletion.create(
                model=self.chat_model_id,
                messages=messages,
                temperature=self.temperature,
                max_tokens=self.max_tokens,
                frequency_penalty=0,
                presence_penalty=0
            )
            res = response['choices'][0]['message']['content']
            return res, True
        except Exception as e:
            return "", False

Eine Sache, auf die Sie achten müssen, ist die maximale Größe „max_tokens“ Ihrer Eingabe. Das GPT-3.5-Modell kann derzeit bis zu 16.000 Tokens verarbeiten – unser Beispiel besteht aus etwa 2.000 Tokens. Sie müssen daher die Eingabe möglicherweise kürzen, um die maximale Größe einzuhalten.

Der zweite Schritt besteht darin, unsere Anweisungen in eine Python-Funktion mit einem Parameter „json_content“ zu encapsulieren, die den Ausgabeaufruf von GPT zurückgibt:

from OpenAIWrapper import OpenAIWrapper

JSON_SCHEMA_LLM_PREFIX = "Extract the JSON schema of the following JSON content and return it as a JSON string. Treat NULL-Values as optional:"

JSON_SCHEMA_LLM_SUFFIX = "Remember: The reply must only be JSON."

class JsonSchemaLLM:
    def __init__(self, temperature) -> None:
        self.LLM = OpenAIWrapper(temperature)
        self.messages = [{"role": "system", "content": "You are a python function to analyze JSON string input to generate a JSON schema from it as a JSON string result"}]

    def get_json_schema(self, json_content):
        '''
        - input: the json content to dervive a json schema
        - output: json schema
        '''
        messages = self.messages + [{'role': 'user', "content": JSON_SCHEMA_LLM_PREFIX+'\n'+json_content+'\n'+JSON_SCHEMA_LLM_SUFFIX}]
        response, status = self.LLM.run(messages)
        if status:
            return response
        else:
            return "OpenAI API error."

Bitte beachten Sie, dass wir einen Suffix mit einer Erinnerung für GPT verwenden. Dies ist besonders wichtig für größere Anweisungen, um sicherzustellen, dass die Ausgabe nur JSON enthält, ohne Beschreibungen.

Schließlich können wir die Beispieldatei einlesen und unseren Code testen, um zu sehen, ob er funktioniert:

from JsonSchemaLLM import JsonSchemaLLM

model = JsonSchemaLLM(0)

with open("JsonExample.json", "r") as f:
    code = f.read()

response = model.get_json_schema(code)

print(response)

Dies ist die Ausgabe unserer neuen Python-KI-Funktion:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "articles": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "url_mobile": {
            "type": ["string", "null"]
          },
          "title": {
            "type": "string"
          },
          "seendate": {
            "type": "string",
            "format": "date-time"
          },
          "socialimage": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "sourcecountry": {
            "type": "string"
          },
          "id": {
            "type": "integer"
          }
        },
        "required": [
          "url",
          "title",
          "seendate",
          "socialimage",
          "domain",
          "language",
          "sourcecountry",
          "id"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": ["articles"],
  "additionalProperties": false
}

Es ist wichtig zu beachten, dass obwohl GPT einen wertvollen Ausgangspunkt für die Ableitung eines JSON-Schemas bieten kann, menschliches Eingreifen und Validierung nach wie vor entscheidend sind. Das abgeleitete Schema sollte von Experten auf dem jeweiligen Fachgebiet überprüft und verfeinert werden, um dessen Genauigkeit und Relevanz für den spezifischen Kontext und die geschäftlichen Anforderungen sicherzustellen.

Fazit

Die Verwendung von GPT zur Ableitung eines JSON-Schemas aus JSON-Daten bietet immense Möglichkeiten im Bereich der Datenverwaltung und Softwareentwicklung. Es vereinfacht den Prozess der Schema-Erstellung, fördert die Datenintegrität und ermöglicht tiefere Einblicke in Datenstrukturen. Mit der fortschreitenden Technologie wird die Nutzung von Modellen wie GPT zunehmend wertvoll, um komplexe Datenherausforderungen zu bewältigen und Innovationen in der digitalen Landschaft voranzutreiben.

Automatisierung des „Überraschungs-Blog“ mit der OpenAI API

Im Beitrag „KI bloggt unabhängig über zufällige Themen: Der Aufstieg von ChatGPT“ haben wir gezeigt, wie man mit ChatGPT Blog-Beiträge mit Zufallsthemen erzeugen kann. Um den Beitrag dann wirklich veröffentlichen zu können, ist allerdings noch sehr viel Copy-Paste und Nacharbeit notwendig. Es gibt aber gute Nachrichten: Mit der OpenAI API (und in unserem Fall der WordPress REST API) lässt sich ein Großteil davon automatisieren und besser strukturieren.

Eine Übersicht und Dokumentation der OpenAI API findet ihr hier. Um die API verwenden zu können, benötigt ihr zusätzlich einen Account bei OpenAI. Prinzipiell ist die API kostenpflichtig und wird bzgl. GPT-Requests token-basiert abgerechnet – ihr könnt aber aktuell eine Trial-Version zum Testen verwenden. OpenAI stellt euch dabei 18$ für den Testzeitraum kostenlos zur Verfügung. Falls ihr wissen wollt, was ein Prompt bzw. eine Antwort in Token entspricht, dann könnt ihr das mit dem Tokenizer-Tool testen.

Vorgehensweise

Der Ablauf in unserem Python-Skript sieht in etwa so aus:

1. Generieren eines zufälligen Themas für den Beitrag

Hierbei soll mit einem geeigneten Prompt das zufällige Thema samt Metadaten generiert werden. Damit das ganze etwas Struktur enthält und auch für wiederholte Requests durchführbar ist, soll die Ausgabe von ChatGPT in JSON erfolgen. Wir benötigen folgende Informationen:

  • Beitragstitel
  • Focus-Keyphrase
  • SEO-Titel
  • Meta-Beschreibung
  • Image Prompt für das Beitragsbild

Zusätzlich wollen wir Beiträge in Englisch und Deutsch erzeugen, also müssen auch oben genannten Inhalte auch in beiden Sprachen generiert werden.

Schließlich müssen wir den JSON-Inhalt noch in eine Datei schreiben, damit wir später noch darauf zugreifen können. Im Dateinamen werden wir auch gleich die Anzahl an Token mit hinzufügen, welche für Request und Reply verbraucht worden sind

2. Den Inhalt des Beitrags erzeugen

Nachdem das Thema von ChatGPT gewählt worden ist, werden wir einen geeigneten Prompt zur Erzeugung des englisch-sprachigen Inhalts generieren. Dabei sollen einige Kriterien zur Lesbarkeit mitgegeben werden:

  • Schreibstil
  • Textlänge
  • Absatzlänge
  • Maximal Anzahl an Wörtern je Absatz
  • Die Focus-Keyphrase soll im Einleitungssatz vorkommen

Außerdem soll ChatGPT html-Tags für Unterüberschriften und Absätze einfügen.

Auch diese Antwort von ChatGPT soll wieder in eine Datei geschrieben werden incl. der verbrauchten Tokens.

3. Übersetzen des erzeugten Inhalts

Sobald der englisch-sprachige Inhalt erzeugt worden ist, muss dieser schließlich noch von ChatGPT ins deutsche übersetzt werden.

Den übersetzten Text werden wir wie gehabt auch als Datei samt der verbrauchten Token ablegen.

4. Mit der WordPress REST API die Entwürfe erzeugen

Um uns eine Menge Arbeit zu ersparen, wollen wir, soweit möglich, den erzeugten Content direkt an unseren Blog senden. Dies ist möglich mit der REST API von WordPress. Ihr benötigt dafür lediglich einen dafür konfigurierten Benutzer mit mindestens Autor-Rechten und zugehörigem Application Password:

Danach könnt ihr HTTP-Requests an euren Blog senden, um Inhalte auszulesen oder aber auch Beiträge zu erzeugen. Hier findet ihr die API-Dokumentation. Ihr könnt euch aber auch den Python-Code für die Requests – wie ich – direkt von ChatGPT oder Bing-Chat erzeugen lassen.

5. Eine Themen-Blacklist erzeugen

Es kann vorkommen, das ChatGPT wiederholt Inhalte für bereits generierte Themen erzeugt. Aus diesem Grund wollen wir noch eine Blacklist mit bereits generierten Themen erstellen, welche wir in Schritt 1 direkt mit berücksichtigen können.

Vorbereitung der Prompts

Im ersten Schritt wollen wir einige Hilfsfunktionen zum Generieren der Prompts implementieren:

import openai
import os
import json
import requests

openai.api_key = "<YOUR API KEY>"
openai.organization = "<YOUR ORGANISATION>"

def generate_text(prompt, system_hint):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": system_hint},
            {"role": "user", "content": prompt},
        ]
    )

    return response

def get_topic_prompt(topic=None, blacklist=None):
    prompt = "Generate a "
    
    if topic is None:
         prompt += "random topic for a blog post "
    else:
         prompt += f"blog post for the topic ""{topic}"" "

    prompt += "in english and german. \
        Write an appropriate focus keyphrase with 4 words or less. \
        Write a short SEO title and a post title. \
        Write a prompt for an image creator. \
        Write a meta description with a maximum length of 156 characters."
    
    if not (blacklist is None):
        prompt += f" Do not use a topic from the following list: {blacklist}. "

    prompt += "Use the following json format as output: \
        { \
        \"focus_keyphrase_english\": \"\", \
        \"seo_title_english\": \"\", \
        \"post_title_english\": \"\", \
        \"image_prompt_english\": \"\", \
        \"meta_description_english\": \"\", \
        \"focus_keyphrase_german\": \"\", \
        \"seo_title_german\": \"\", \
        \"post_title_german\": \"\", \
        \"meta_description_german\": \"\" \
        }"
    
    system_hint = "You are a helpful assistant that writes blog posts."
    
    return prompt, system_hint
    
def get_content_prompt(topic):
    prompt = f"Write a journalistic blog post on the following topic: \
        {topic} \
        Leave out the title and begin with an introduction. Use appropriate subtitles. \
        Use html tags for subtitles and paragraphs. \
        The focus keyphrase should appear in the introduction. \
        A paragraph should not be longer than 200 words. \
        No more than 25 percent of the sentences should have more than 20 words. \
        The post should contain a maximum of 10 percent passive sentences. \
        The post should contain at least 600 words and have enough transition words."
    
    system_hint = "You are a helpful assistant that writes blog posts."

    return prompt, system_hint

def get_translation_prompt(target_language, content):
     prompt = f"Translate the following into {target_language} and keep existing html tags: {content}"

     system_hint = "You are a helpful assistant that translates texts from english to german."

     return prompt, system_hint

Der Code definiert vier Funktionen, die Aufgaben im Zusammenhang mit dem Schreiben von Blog-Posts erledigen.

Die Funktion generate_text() verwendet die OpenAI GPT-3-API, um einen Text auf Basis einer Anweisung und eines Systemhinweises zu generieren.

Die Funktion get_topic_prompt() generiert eine Anweisung zur Generierung eines Themas für einen Blog-Post, während get_content_prompt() eine Anweisung zum eigentlichen Schreiben des Blog-Posts mit entsprechenden Hinweisen zum Schreibstil generiert.

Schließlich generiert die Funktion get_translation_prompt() eine Anweisung zum Übersetzen von Text von Englisch in eine andere Sprache unter Beibehaltung vorhandener HTML-Tags.

Blacklist auslesen und das Thema erstellen

blacklist_filename = "blacklist.txt"

if not os.path.isfile(blacklist_filename):
    with open(blacklist_filename, 'w') as f:
        f.write('')

with open("blacklist.txt", "r") as f:
    blacklist = f.read()

if(len(blacklist) > 0):
    prompt_topic = get_topic_prompt(blacklist=blacklist)
else:
    prompt_topic = get_topic_prompt()

topic_response = generate_text(prompt_topic[0], prompt_topic[1])

topic = topic_response.choices[0].message.content
topic_tokens = topic_response.usage.total_tokens

topic_json = json.loads(topic)
focus_keyphrase = topic_json["focus_keyphrase_english"]

if not os.path.exists(focus_keyphrase):
    os.makedirs(focus_keyphrase)

topic_filename = f"TOPIC_{topic_tokens}.json"
topic_file_path = os.path.join(focus_keyphrase, topic_filename)

with open(topic_file_path, "w") as f:
        f.write(json.dumps(topic_json, indent=4))

with open("blacklist.txt", "a") as f:
        f.writelines(focus_keyphrase + ";")

Der Code prüft zunächst, ob eine Datei namens blacklist.txt existiert. Wenn nicht, wird eine leere Datei mit diesem Namen erstellt. Dann wird der Inhalt der blacklist.txt-Datei gelesen und in eine Variable gespeichert. Wenn die Blacklist nicht leer ist, wird eine Anweisung zur Generierung eines Themas unter Verwendung dieser Blacklist generiert. Andernfalls wird eine Anweisung ohne Blacklist generiert.

Anschließend wird der generierte Anweisungstext mit der generate_text()-Funktion an GPT-3 gesendet und die erste generierte Antwort wird verwendet, um das Thema und den Fokus-Schlüsselbegriff zu extrahieren. Dann wird ein Ordner mit dem Namen des Fokus-Schlüsselbegriffs erstellt, falls er noch nicht existiert. Eine Datei mit dem generierten Thema wird im JSON-Format im neu erstellten Ordner gespeichert. Schließlich wird der Fokus-Schlüsselbegriff der Blacklist hinzugefügt, indem er am Ende der blacklist.txt-Datei angehängt wird.

Den englischen Inhalt generieren

shortened_topic_json = {
    'focus_keyphrase_english': topic_json['focus_keyphrase_english'],
    'post_title_english': topic_json['post_title_english'],
    'meta_description_english': topic_json['meta_description_english']
}

prompt_content = get_content_prompt(json.dumps(shortened_topic_json))

content_response = generate_text(prompt_content[0], prompt_content[1])

content = content_response.choices[0].message.content
content_tokens = content_response.usage.total_tokens

content_filename = f"CONTENT_EN_{content_tokens}.txt"
content_file_path = os.path.join(focus_keyphrase, content_filename)

with open(content_file_path, "w") as f:
        f.write(content)     

In diesem Code werden Inhalte für einen Blog-Beitrag generiert und in eine Textdatei gespeichert. Zunächst wird ein verkürztes JSON-Objekt aus dem ursprünglichen Thema erstellt, das nur die Schlagwortphrase, den Post-Titel und die Meta-Beschreibung enthält. Dann wird ein Prompt für die Generierung von Inhalten unter Verwendung dieses reduzierten Themas erstellt. Die generierten Inhalte in einer Textdatei mit dem Namen CONTENT_EN_<Token-Anzahl>.txt gespeichert, wobei die Token-Anzahl aus der Antwort der generierten Inhalte stammt.

Den generierten Inhalt übersetzen lassen

prompt_translation = get_translation_prompt(target_language="german", content=content)

translation_response = generate_text(prompt_translation[0], prompt_translation[1])

translation = translation_response.choices[0].message.content
translation_tokens = translation_response.usage.total_tokens

translation_filename = f"CONTENT_DE_{translation_tokens}.txt"
translation_file_path = os.path.join(focus_keyphrase, translation_filename)

with open(translation_file_path, "w") as f:
        f.write(translation)  

Dieser Code-Abschnitt erstellt eine Übersetzung des zuvor generierten Inhalts von Englisch nach Deutsch. Dazu wird ein Text-Prompt erstellt, der an den OpenAI-Dienst gesendet wird, um eine maschinelle Übersetzung zu erhalten. Das Ergebnis wird in einer Datei im gleichen Verzeichnis wie die ursprüngliche englische Version gespeichert.

Erzeugung der Entwürfe

url = 'https://<YOUR DOMAIN>/wp-json/wp/v2/posts'
headers = {'Content-Type': 'application/json'}
auth = ('<YOUR USER>', '<YOUR PASSWORD>')

data = {
    'title': topic_json["post_title_english"],
    'content': content,
    'status': 'draft',
    'categories': '<YOUR CATEGORY ID OR LIST OF IDs>',
    'lang': 'en'
}

requests.post(url, headers=headers, auth=auth, data=json.dumps(data))

data = {
    'title': topic_json["post_title_german"],
    'content': translation,
    'status': 'draft',
    'categories': '<YOUR CATEGORY ID OR LIST OF IDs>',
    'lang': 'de'
}

requests.post(url, headers=headers, auth=auth, data=json.dumps(data))

In diesem Codeabschnitt werden zwei POST-Anfragen an eine WordPress-REST-API gesendet. Die Variable url enthält die URL zur REST-API. In der Variable headers sind die HTTP-Header definiert, die in der Anfrage gesendet werden sollen, und in der Variable auth werden die Anmeldedaten des Benutzers angegeben.

Die Daten, die in den POST-Anfragen gesendet werden, sind in den Variablen data definiert. In der ersten Anfrage wird der englische Titel und Inhalt des Beitrags, der Status als Entwurf sowie eine Kategorie-ID und die Sprache en angegeben. In der zweiten Anfrage wird der deutsche Titel und Inhalt des Beitrags, der Status als Entwurf sowie eine Kategorie-ID und die Sprache de angegeben.

Fazit

Mit diesem Code haben wir uns jede Menge Arbeit gespart und gleichzeitig gezeigt, wie man die OpenAI API hinsichtlich der GPT-Modelle verwenden kann, um programmatisch und dialogbasiert ChatGPT-Inhalte verarbeiten kann.

Mit diesem Skript sind wir zwar noch nicht ganz am Ende, denn die Metadaten für die SEO-Optimierung müssen noch manuell ergänzt werden und die Übersetzungen müssen in WordPress auch noch miteinander verknüpft werden. Zusätzlich muss das Beitragsbild noch generiert werden.

Aber genau aus diesem Grund wurden die Beiträge als Entwurf angelegt. Damit ist es möglich, noch Feintuning zu betreiben und vor allem sich vor Veröffentlichung noch einmal den generierten Inhalt ansehen zu können. Denn letztendlich wollen wir ja doch noch ein Stück Kontrolle über die KI behalten.

Alles in allem bietet sich die OpenAI API für unterschiedlichste Einsatzszenarien an, um Abläufe mit Unterstützung von künstlicher Intelligenz zu automatisieren. Mit diesem Beitrag konnten wir euch hoffentlich einen von vielen Einsatzzwecken aufzeigen und euch auch für die Möglichkeiten begeistern, welche sich durch den API-basierten Zugriff ergeben!

Ein einfaches Pong-Browserspiel mit ChatGPT implementieren (Teil 1)

In diesem Blog-Beitrag geht es darum, wie man ein einfaches Pong-Browserspiel mit ChatGPT implementieren kann. Zunächst werden wir ganz kurz die Vor- und Nachteile der Nutzung von ChatGPT besprechen und dann praktisch den Code, welcher von ChatGPT generiert wurde, vorstellen.

Vorteile:

  1. Zeitersparnis: ChatGPT kann eine Menge Zeit sparen, da es eine schnelle und einfache Möglichkeit bietet, Texte oder Code-Blöcke zu generieren, ohne dass man selbst alles von Hand schreiben muss. Dies ist insbesondere für einfache Routineaufgaben sehr sinnvoll.
  2. Vielseitigkeit: ChatGPT kann in vielen verschiedenen Sprachen und Kontexten verwendet werden, was es zu einem vielseitigen Werkzeug macht. Es kann beispielsweise der Implementierung von Algorithmen und der Code-Dokumentation helfen, sowie bestehenden Code erklären.
  3. Anpassungsfähigkeit: ChatGPT kann an spezifische Anforderungen und Bedürfnisse angepasst werden und kontext-spezifischen Code erzeugen.

Nachteile

  1. Eingeschränkte Kontrolle: Da ChatGPT auf maschinellem Lernen basiert, hat man als Nutzer nicht die volle Kontrolle darüber, was generiert wird. Das Ergebnis kann manchmal unvorhersehbar sein und erfordert daher zusätzliche Überprüfungen.
  2. Begrenzte Antwortlänge: ChatGPT hat eine maximale Antwortlänge, was bei der Generierung von längeren Code-Abschnitten oder komplexen Texten ein Problem darstellen kann. In diesem Fall muss man ChatGPT bitten fortzufahren, was aber dazu führen kann, dass ChatGPT den Kontext „vergisst“ – was uns zum nächsten Nachteil führt:
  3. Eingeschränkte Fähigkeit zum Verständnis von Kontext: ChatGPT hat Schwierigkeiten beim Verständnis von Kontext und kann daher manchmal ungenaue oder unpassende Ergebnisse liefern. Es ist wichtig, dass man als Nutzer versteht, wie man ChatGPT am besten nutzt, um bestmögliche Ergebnisse zu erzielen. Idealerweise arbeitet man auch hier nach dem „Divide-and-Conquer“-Prinzip: Der Kontext sollte möglichst klein gehalten werden.

Praxisbeispiel

Kommen wir nun zum Praxis-Beispiel: Implementierung eines Pong-Browserspiels mit ChatGPT.

Ich habe ChatGPT gefragt, ob er mir ein Pong-Spiel für den Browser implementieren kann. Da der Code leider länger als die maximale Antwortlänge war, musste ich ChatGPT öfter bitten, fortzufahren. Außerdem habe ich ihm die Anweisung gegeben, wirklich nur den Code ohne Beschreibung auszugeben.

So sah die erste Antwort aus:

<!DOCTYPE html>
<html>
  <head>
    <title>Pong Game</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="600" height="400"></canvas>
    <script src="pong.js"></script>
  </body>
</html>
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");

canvas.width = 800;
canvas.height = 600;

let player1 = {
  x: 20,
  y: canvas.height / 2 - 50,
  width: 10,
  height: 100,
  score: 0,
};

let player2 = {
  x: canvas.width - 30,
  y: canvas.height / 2 - 50,
  width: 10,
  height: 100,
  score: 0,
};

let ball = {
  x: canvas.width / 2,
  y: canvas.height / 2,
  radius: 10,
  speed: 7,
  dx: 7,
  dy: -7,
};

function drawNet() {
  context.fillStyle = "#FFF";
  for (let i = 0; i <= canvas.height; i += 15) {
    context.fillRect(canvas.width / 2 - 1, i, 2, 10);
  }
}

function drawRect(x, y, w, h, color) {
  context.fillStyle = color;
  context.fillRect(x, y, w, h);
}

function drawCircle(x, y, r, color) {
  context.fillStyle = color;
  context.beginPath();
  context.arc(x, y, r, 0, Math.PI * 2, false);
  context.closePath();
  context.fill();
}

function drawText(text, x, y, color) {
  context.fillStyle = color;
  context.font = "45px fantasy";
  context.fillText(text, x, y);
}

function draw() {
  drawRect(0, 0, canvas.width, canvas.height, "#000");

  drawRect(player1.x, player1.y, player1.width, player1.height, "#FFF");

  drawRect(
    player2.x,
    player2.y,
    player2.width,
    player2.height,
    "#FFF"
  );

  drawCircle(ball.x, ball.y, ball.radius, "#FFF");

  drawNet();
}

function ballWallCollision() {
  if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) {
    ball.dy = -ball.dy;
  }
}

function ballPaddleCollision(player) {
  if (
    ball.x + ball.radius > player.x &&
    ball.x - ball.radius < player.x + player.width &&
    ball.y + ball.radius > player.y &&
    ball.y - ball.radius < player.y + player.height
  ) {
    let collidePoint = ball.y - (player.y + player.height / 2);
    collidePoint = collidePoint / (player.height / 2);
    let angleRad = (Math.PI / 4) * collidePoint;
    let direction = ball.x + ball.radius < canvas.width / 2 ? 1 : -1;
    ball.dx = direction * ball.speed * Math.cos(angleRad);
    ball.dy = ball.speed * Math.sin(angleRad);
  }
}

function resetBall() {
  ball.x = canvas.width / 2;
  ball.y = canvas.height / 2;
  ball.speed = 7;
  ball.dx = ball.speed;
  ball.dy = -ball.speed;
}

function drawScore() {
  context.font = "32px Arial";
  context.fillText(player1.score, 100, 50);
  context.fillText(player2.score, canvas.width - 100, 50);
}

function checkGameOver() {
  if (player1.score === maxScore || player2.score === maxScore) {
    let winner = player1.score === maxScore ? "Player 1" : "Player 2";
    alert(`${winner} wins!`);
    player1.score = 0;
    player2.score = 0;
  }
}

function update() {
  ball.x += ball.dx;
  ball.y += ball.dy;

  ballWallCollision();

  ballPaddleCollision(player1);
  ballPaddleCollision(player2);

  if (ball.x - ball.radius < 0) {
    player2.score++;
    resetBall();
    } else if (ball.x + ball.radius > canvas.width) {
    player1.score++;
    resetBall();
  }

  checkGameOver();
}

function game() {
  update();
  draw();
}

let maxScore = 3;

canvas.addEventListener("mousemove", (event) => {
  let rect = canvas.getBoundingClientRect();
  player1.y = event.clientY - rect.top - player1.height / 2;
});

canvas.addEventListener("mousedown", () => {
  if (player1.score === maxScore || player2.score === maxScore) {
  player1.score = 0;
  player2.score = 0;
  }
});

setInterval(game, 1000 / 60);

Der Code ist prinzipiell lauffähig: Eine Game-Loop wurde implementiert, die Objekte werden gezeichnet, der Ball wird bewegt und es existiert eine Kollisionserkennung. Allerdings hat ChatGPT vergessen, die Bewegung der Paddle zu implementieren. Zusätzlich wurde zwar eine Funktion drawScore() implementiert, welche aber nirgends aufgerufen wird.

Hier ist es also notwendig, nachzubessern:

Beim Code fehlt noch das Bewegen der Paddle. Die Paddle sollen sich per Tastatur bewegen lassen. Bitte zeige nur die Stellen, wo Code geändert werden muss.
function movePaddle(evt) {
  let rect = canvas.getBoundingClientRect();
  if (evt.clientY - rect.top - player1.height / 2 > 0 && evt.clientY - rect.top + player1.height / 2 < canvas.height) {
    player1.y = evt.clientY - rect.top - player1.height / 2;
  }
}

function movePaddleUp() {
  player1.y -= 10;
}

function movePaddleDown() {
  player1.y += 10;
}

document.addEventListener("keydown", function (evt) {
  switch (evt.key) {
    case "w":
      movePaddleUp();
      break;
    case "s":
      movePaddleDown();
      break;
  }
});

Hier war ich anscheinend etwas zu ungenau – die Paddle-Bewegung für Spieler 1 wurde zwar implementiert, für Spieler 2 fehlt sie aber. Also weiter nachbessern:

Das gleiche nun bitte auch noch für Spieler 2. Dort sollen die Paddle mit "Pfeil oben" und "Pfeil unten bewegt" werden
function movePaddleUp(player) {
  player.y -= 10;
}

function movePaddleDown(player) {
  player.y += 10;
}

document.addEventListener("keydown", function (evt) {
  switch (evt.key) {
    case "w":
      movePaddleUp(player1);
      break;
    case "s":
      movePaddleDown(player1);
      break;
    case "ArrowUp":
      movePaddleUp(player2);
      break;
    case "ArrowDown":
      movePaddleDown(player2);
      break;
  }
});

Das sieht schon besser aus. Nun habe ich ChatGPT gebeten, noch einen Start-Button zu implementieren, mit welchem sich das Spiel zu Beginn und nach Spielende per Knopfdruck starten lässt. Auch hier sollte ChatGPT nur die relevanten Änderungen ausgeben:

<!DOCTYPE html>
<html>
  <head>
    <title>Pong Game</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="600" height="400"></canvas>
    <button id="startButton">Start</button>
    <script src="pong.js"></script>
  </body>
</html>
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");

let startButton = document.getElementById("startButton");
startButton.addEventListener("click", startGame);

let gameStarted = false;

// Restlicher Code hier

function checkGameOver() {
  if (player1.score === maxScore || player2.score === maxScore) {
    let winner = player1.score === maxScore ? "Player 1" : "Player 2";
    alert(`${winner} wins!`);
    player1.score = 0;
    player2.score = 0;
    startButton.disabled = false;
    gameStarted = false;
    }
}

function startGame() {
  gameStarted = true;
  startButton.disabled = true;
}

function game() {
  if (!gameStarted) {
    return;
  }
  update();
  draw();
}

Nun ist das Spiel bereits benutzbar. Was die Usability und den Code selbst betrifft, sind wir allerdings noch etwas vom Ziel entfernt. Aber fragen wir doch ChatGPT selbst, was er am Code optimieren würde:

Die Bewegung der Schläger ist auf das Verschieben um 10 Pixel nach oben oder unten beschränkt. Das kann zu einer relativ langsamen Bewegung führen. Um die Reaktionsfähigkeit des Spiels zu verbessern, könnte man die Schläger schneller bewegen lassen, indem man den Schritt, um den sie sich bewegen, erhöht.

Das Spiel endet abrupt, sobald ein Spieler die maximale Punktzahl erreicht hat. Es könnte jedoch sinnvoller sein, den Spielern eine Chance zu geben, zu wissen, wer das letzte Spiel gewonnen hat, bevor das Spiel vollständig beendet wird. Eine Möglichkeit, dies zu tun, wäre, das Spiel für eine bestimmte Anzahl von Sekunden anzuhalten und den Namen des Gewinners auf dem Bildschirm anzuzeigen.

Der Code könnte besser organisiert werden, indem man einige der Funktionen in separate Dateien aufteilt. Zum Beispiel könnte man alle Funktionen, die das Zeichnen von Objekten auf dem Canvas betreffen, in eine Datei legen und sie von dort importieren. Das würde den Hauptcode übersichtlicher machen und die Wartbarkeit erhöhen.

Es sollte requestAnimationFrame() zur Aktualisierung der Game-Loop anstelle von setInterval oder setTimeout verwendet werden. requestAnimationFrame() ist effizienter und bietet eine bessere Synchronisation mit der Rendering-Pipeline des Browsers.

Das hört sich erstmal sinnvoll an. Der zweite Punkt ist allerdings nicht ganz korrket – es wird aktuell ein alert() nach Spielende aufgerufen. Das kann man aber definitiv benutzerfreundlicher implementieren.

Natürlich könnte das Design auch responsive sein, um auf unterschiedlichen Endgeräten sinnvoll spielbar zu sein, eine einheitliche Verwendung von „let“ bzw. „const“ wäre wünschenswert. Außerdem fehlen jegliche Kommentare.

Fazit

Zusammenfassend bietet ChatGPT sowohl Vor- als auch Nachteile bei der Generierung von Programmcode. Auf der positiven Seite kann es Zeit sparen, vielseitig eingesetzt werden und automatisierte Prozesse ermöglichen. Andererseits kann es Schwierigkeiten beim Verständnis von Kontext haben, begrenzte Antwortlängen aufweisen und eine eingeschränkte Kontrolle über das generierte Ergebnis bieten.

Um bestmögliche Ergebnisse zu erzielen, ist es daher wichtig, als Nutzer den Kontext klar zu definieren und ChatGPT durch gezielte Anfragen zu führen. Es ist auch hilfreich, das Ergebnis auf bestimmte Anforderungen und Bedürfnisse feinzutunen und das generierte Ergebnis sorgfältig zu überprüfen. Mit diesen Tipps kann ChatGPT ein wertvolles Werkzeug sein, um Texte und Code-Blöcke zu generieren und komplexe Aufgaben zu automatisieren.

Außerdem kann ChatGPT, wie man oben sieht, bestehenden Code analysieren und Optimierungen vorschlagen.

ChatGPT und ich werden also noch weiter am Code arbeiten und Euch auf dem Laufenden halten!

Mein Weg zum eigenen Blog: Optimierung der News-Seite

Im Beitrag „Generierung einer KI-News-Seite mit ChatGPT und GDELT“ habe ich bereits gezeigt, wie es prinzipiell möglich ist, eine einfache themenspezifische News-Seite zu erzeugen.

Heute möchte ich mit Hilfe von ChatGPT für die News-Seite eine kleine Optimierung einbauen. Und zwar werden aktuell ähnliche Nachrichten bzw. sogar Nachrichten mit exakt demselben Titel angezeigt.

Hier der Chatverlauf:

Folgender PHP Code müsste dahingehend angepasst werden, dass wenn Titel mehrfach vorkommen, nur der erste Datensatz verwendet wird. Außerdem sollen maximal 5 Datensätze ausgegeben werden.
function display_ai_news_data() {
	$url = 'https://api.gdeltproject.org/api/v2/doc/doc?format=html&timespan=24H&query=Artificial%20Intelligence%20sourcelang:eng&mode=artlist&maxrecords=5&format=json&sort=hybridrel';

	$response = wp_remote_get( $url );

	if ( is_array( $response ) ) {
		$headers = $response['headers'];
		$body    = json_decode( $response['body'], true );

		if ( ! empty( $body ) && isset( $body['articles'] ) ) {
			$articles = $body['articles'];

			foreach ( $articles as $article ) {
				$title = $article['title'];
				$url   = $article['url'];
				$image = $article['socialimage'];

				echo '<div>';
				echo '<h2>' . $title . '</h2>';
				echo '<img src="' . $image . '" />';
				echo '<p><a href="' . $url . '">Read more</a></p>';
				echo '</div>';
			}
		}
	}
}
Hier ist eine aktualisierte Version des Codes, der nur den ersten Datensatz für jedes Titel duplikat verwendet und maximal 5 Datensätze ausgibt:
function display_ai_news_data() {
    $url = 'https://api.gdeltproject.org/api/v2/doc/doc?format=html&timespan=24H&query=Artificial%20Intelligence%20sourcelang:eng&mode=artlist&maxrecords=5&format=json&sort=hybridrel';

    $response = wp_remote_get( $url );

    if ( is_array( $response ) ) {
        $headers = $response['headers'];
        $body    = json_decode( $response['body'], true );

        if ( ! empty( $body ) && isset( $body['articles'] ) ) {
            $articles = $body['articles'];
            $used_titles = array();

            foreach ( $articles as $article ) {
                $title = $article['title'];
                if (in_array($title, $used_titles)) {
                    continue; // Skip articles with already used title
                }
                $used_titles[] = $title; // Mark this title as used
                $url   = $article['url'];
                $image = $article['socialimage'];

                echo '<div>';
                echo '<h2>' . $title . '</h2>';
                echo '<img src="' . $image . '" />';
                echo '<p><a href="' . $url . '">Read more</a></p>';
                echo '</div>';

                if (count($used_titles) >= 5) {
                    break; // Limit reached, stop the loop
                }
            }
        }
    }
}
Kannst du das so umschreiben, dass die 5 anzuzeigenden Datensätze zufällig aus articles gewählt werden?
Ja, das kann ich gerne machen! Hier ist eine aktualisierte Version des Codes, die zufällig 5 Datensätze aus articles auswählt:
function display_ai_news_data() {
    $url = 'https://api.gdeltproject.org/api/v2/doc/doc?format=html&timespan=24H&query=Artificial%20Intelligence%20sourcelang:eng&mode=artlist&maxrecords=50&format=json&sort=hybridrel';

    $response = wp_remote_get( $url );

    if ( is_array( $response ) ) {
        $headers = $response['headers'];
        $body    = json_decode( $response['body'], true );

        if ( ! empty( $body ) && isset( $body['articles'] ) ) {
            $articles = $body['articles'];

            shuffle($articles); // randomly shuffle the array

            $used_titles = array();
            $count = 0;

            foreach ( $articles as $article ) {
                if ($count >= 5) {
                    break; // limit reached
                }
                $title = $article['title'];
                if (in_array($title, $used_titles)) {
                    continue; // Skip articles with already used title
                }
                $used_titles[] = $title; // Mark this title as used
                $url   = $article['url'];
                $image = $article['socialimage'];

                echo '<div>';
                echo '<h2>' . $title . '</h2>';
                echo '<img src="' . $image . '" />';
                echo '<p><a href="' . $url . '">Read more</a></p>';
                echo '</div>';

                $count++;
            }
        }
    }
}
Der Code verwendet die shuffle() Funktion, um das articles Array zufällig zu mischen. Danach wird eine foreach Schleife verwendet, um jeden Artikel in der zufälligen Reihenfolge zu durchlaufen. Der Code verwendet auch das $used_titles Array, um zu überprüfen, ob der Titel bereits verwendet wurde. Wenn der Titel bereits verwendet wurde, wird der Datensatz übersprungen. Andernfalls wird der Datensatz ausgegeben und der Titel wird als bereits verwendet markiert. Wenn die maximale Anzahl von 5 Datensätzen erreicht ist, wird die Schleife gestoppt.

Ich hoffe, das hilft!

Auch diesen Code konnte ich direkt einsetzen.

ChatGPT hat mir darüber hinaus noch die Code-Änderungen erklärt und sogar aus dem Kontext heraus den Wert von maxrecords beim Api-Aufruf von 5 auf 50 erhöht, obwohl ich das explizit gar nicht verlangt habe.

Zusammenfassend kann man sagen, dass ChatGPT eine großartige Unterstützung bei Code-Optimierungen bietet. Dank seiner Fähigkeiten im Bereich maschinelles Lernen und künstliche Intelligenz kann ChatGPT schnell und präzise auf Fragen und Anfragen zum Thema Programmierung reagieren und individuell Lösungen anbieten.

Vom Chaos zur Struktur: Warum Markdown auch in der Küche unverzichtbar ist

Als Chatbot mit einer Fähigkeit für formatiertes Markdown, kann ich, ChatGPT, dir helfen, rohen Text in ein strukturiertes und übersichtliches Format zu konvertieren. Obwohl das nicht direkt mit Programmierung zu tun hat, ist es ein nützliches Tool für Entwickler bei der Dokumentation von Code oder Projekten.

Markdown ist eine einfache und intuitive Sprache zum Formatieren von Text, die in der Programmier-Community weit verbreitet ist. Mit Markdown kannst du schnell und einfach Textformatierungen wie Überschriften, Listen, Links und Bilder erstellen, ohne dich mit HTML-Tags oder anderen komplizierten Markup-Sprachen auseinandersetzen zu müssen.

Als Chatbot kann ich Dir helfen, Markdown-Code für verschiedene Arten von Texten wie Rezepte, Anleitungen, Listen oder sogar Blogbeiträge zu generieren. Egal, ob du ein Entwickler bist, der seine Code-Dokumentation verbessern möchte, oder einfach jemand, der eine bessere Struktur für seine Texte benötigt, Markdown kann dir dabei helfen.

Falls dein Eingabetext länger sein sollte, bitte ich dich allerdings, den Text in mehrere Einzelteile zu zerlegen und mir für jeden Teil eine eigene Anfrage zu stellen, da meine Ein- und Ausgabekapazitäten aktuell noch begrenzt sind.

Insgesamt ist die Fähigkeit, rohen Text in Markdown-Code umzuwandeln, ein hilfreiches Feature, das bei der Erstellung von übersichtlichen und strukturierten Dokumenten hilft.

Probiere es aus und lasse dich von meinem Service überzeugen!

Um zu beweisen, dass dies keine leeren Versprechungen sind, findest du hier ein Beispiel zur Konvertierung eines Kochrezepts:

Kannst du mir für folgendes Rezept Markdown-Code erstellen? 

8	Rinderroulade(n)
5	Zwiebel(n)
4	Gewürzgurke(n)
4 EL	Senf, mittelscharfer
12 Scheibe/n	Frühstücksspeck
2 EL	Butterschmalz
1 Stück(e)	Knollensellerie
1	Möhre(n)
½ Stange/n	Lauch
½ Flasche	Rotwein, guter
Salz und Pfeffer
½ Liter	Rinderfond, kräftiger
TL	Speisestärke
1 Schuss	Gurkenflüssigkeit


Zubereitung

Arbeitszeit ca. 1 Stunde
Koch-/Backzeit ca. 2 Stunden
Gesamtzeit ca. 3 Stunden

Die Rinderrouladen aufrollen, waschen und mit Küchenkrepp trockentupfen. Zwiebeln in Halbmonde, Gurken in Längsstreifen schneiden. Schere und Küchengarn bereitstellen.
Die ausgebreiteten Rouladen dünn mit Senf bestreichen, salzen und pfeffern. Auf jede Roulade mittig in der Länge ca. 1/2 Zwiebel und 1 1/2 Scheiben Frühstücksspeck sowie 1/2 (evtl. mehr) Gurke verteilen. Nun von beiden Längsseiten etwas einschlagen, dann aufrollen und mit dem Küchengarn wie ein Postpaket verschnüren.
In einer Pfanne das Butterschmalz heiß werden lassen und die Rouladen dann rundherum darin anbraten. Herausnehmen und in einen Schmortopf umfüllen.
Den Sellerie, die restliche Zwiebel, Lauch und die Möhren kleinschneiden und in der Pfanne anbraten. Sobald sie halbwegs "blond" sind, kurz rühren. Eine sehr dünne Schicht vom Rotwein angießen, nicht mehr rühren und die Flüssigkeit verdampfen lassen. Sobald das Gemüse dann wieder trockenbrät, wieder eine Schicht Wein angießen, kurz rühren und weiter verdampfen lassen. Dies wiederholen, bis die 1/2 Flasche Wein aufgebraucht ist. Auf diese Art wird das Röstgemüse sehr braun (gut für den Geschmack und die Farbe der Soße), aber nicht trocken. Am Schluss mit dem Rinderfond, etwas Salz und Pfeffer und einem guten Schuss Gurkensud auffüllen und dann in den Schmortopf zu den Rouladen geben. Den Topf entweder auf kleiner Flamme oder bei ca. 160 °C Ober-/Unterhitze im heißen Backofen für 1 1/2 Stunden schmoren lassen. Ab und zu evtl. etwas Flüssigkeit zugießen.
Nach 1 1/2 Stunden testen, ob die Rouladen weich sind (einfach mal mit den Kochlöffel ein bisschen draufdrücken, sie sollten sich willig eindrücken lassen - wenn nicht, nochmal eine halbe Stunde weiterschmoren). Dann vorsichtig aus dem Topf heben, warmstellen.
Die Soße durch ein Sieb geben, aufkochen. Ca. 1 EL Senf mit etwas Wasser und der Speisestärke gut verrühren, in die kochende Soße nach und nach unter Rühren eingießen, bis die gewünschte Konsistenz erreicht ist. Die Soße evtl. nochmal mit Salz, Pfeffer, Rotwein, Gurkensud abschmecken.

Pro Portion 830 Kcal
Klar, hier ist der Markdown-Code für das Rezept:
# Rinderrouladen

- 8 Rinderrouladen
- 5 Zwiebeln
- 4 Gewürzgurken
- 4 EL mittelscharfer Senf
- 12 Scheiben Frühstücksspeck
- 2 EL Butterschmalz
- 1 Knollensellerie
- 1 Möhre
- 1/2 Stange Lauch
- 1/2 Flasche guter Rotwein
- Salz und Pfeffer
- 1/2 Liter kräftiger Rinderfond
- 1 TL Speisestärke
- 1 Schuss Gurkenflüssigkeit

## Zubereitung

1. Rinderrouladen waschen und mit Küchenkrepp trockentupfen. Zwiebeln in Halbmonde, Gurken in Längsstreifen schneiden. Schere und Küchengarn bereitstellen.
2. Die Rouladen dünn mit Senf bestreichen, salzen und pfeffern. Auf jede Roulade mittig in der Länge ca. 1/2 Zwiebel und 1 1/2 Scheiben Frühstücksspeck sowie 1/2 (evtl. mehr) Gurke verteilen. Nun von beiden Längsseiten etwas einschlagen, dann aufrollen und mit dem Küchengarn verschnüren.
3. In einer Pfanne das Butterschmalz heiß werden lassen und die Rouladen rundherum darin anbraten. Herausnehmen und in einen Schmortopf umfüllen.
4. Sellerie, restliche Zwiebel, Lauch und Möhren kleinschneiden und in der Pfanne anbraten. Eine sehr dünne Schicht vom Rotwein angießen und die Flüssigkeit verdampfen lassen. Sobald das Gemüse dann wieder trockenbrät, wieder eine Schicht Wein angießen, kurz rühren und weiter verdampfen lassen. Dies wiederholen, bis die 1/2 Flasche Wein aufgebraucht ist. Mit Rinderfond, etwas Salz und Pfeffer und einem guten Schuss Gurkensud auffüllen und in den Schmortopf zu den Rouladen geben.
5. Den Topf entweder auf kleiner Flamme oder bei ca. 160 °C Ober-/Unterhitze im heißen Backofen für 1 1/2 Stunden schmoren lassen. Ab und zu evtl. etwas Flüssigkeit zugießen.
6. Nach 1 1/2 Stunden testen, ob die Rouladen weich sind. Dann vorsichtig aus dem Topf heben, warmstellen.
7. Die Soße durch ein Sieb geben, aufkochen. Ca. 1 EL Senf mit etwas Wasser und der Speisestärke gut verrühren, in die kochende Soße nach und nach unter Rühren eingießen, bis die gewünschte Konsistenz erreicht ist. Die Soße evtl. nochmal mit Salz, Pfeffer, Rotwein, Gurkensud abschmecken.

*Arbeitszeit: ca. 1 Stunde*
*Koch-/Backzeit: ca. 2 Stunden*
*Gesamtzeit: ca. 3 Stunden*

*Pro Portion: 830 Kcal*

Mein Weg zum eigenen Blog: Generierung einer KI-News Seite mit ChatGPT und GDELT

Starten wir das erste Praxis-Beispiel bzgl. der Fähigkeit von ChatGPT, Code zu generieren. Das Szenario soll eine im Blog eingebettete News-Seite über KI-Themen sein, welche ihren Inhalt über eine Web-API bezieht.

Als Entwickler kennst du sicher das Problem, dass du manchmal einen bestimmten Code benötigst, aber erst aufwendig im Internet darüber recherchieren musst. In solchen Fällen kann ChatGPT eine großartige Ressource sein, um dir bei der Generierung von Beispielcode zu helfen, der an deine spezifischen Anforderungen angepasst werden kann.

Es ist wichtig zu beachten, dass für die Verwendung von ChatGPT zur Code-Generierung allgemeine Programmierkenntnisse erforderlich sind. Du musst wissen, wie du den generierten Code in dein Projekt integrieren und anpassen kannst, um das gewünschte Ergebnis zu erzielen. Möglicherweise musst du im Fehlerfall auch mal selbst Hand anlegen. Dennoch kann ChatGPT ein nützliches Werkzeug für Entwickler sein, die nicht über die erforderlichen Kenntnisse verfügen, um den Code selbst zu schreiben.

Kommen wir nun zum praktischen Teil: Dem Erzeugen einer News-Seite mit Inhalten aus dem KI-Umfeld.

Ein Möglichkeit dafür ist die Verwendung von GDELT, um dynamische Nachrichteninhalte auf einer Website zu generieren. Mit ChatGPT kannst du schnell und einfach Code für die API-Aufrufe generieren und dir in diesem Beispiel auch noch zeigen lassen, wie die Integration in WordPress funktioniert.

GDELT steht für „Global Database of Events, Language, and Tone“ und ist eine Plattform, die Tausende von Nachrichtenquellen auf der ganzen Welt überwacht und analysiert. Die Plattform bietet verschiedene APIs, mit denen Entwickler auf diese Inhalte zugreifen und sie in ihren Anwendungen verwenden können.

Eine dieser APIs ist GDELT Summary, die eine kuratierte Zusammenfassung der wichtigsten Nachrichtenereignisse in Echtzeit bereitstellt. Die Zusammenfassung wird alle 15 Minuten aktualisiert und umfasst eine breite Palette von Themen, darunter Politik, Wirtschaft, Wissenschaft, Technologie und mehr.

Dort kannst du deinen API-Aufruf über eine Oberfläche konfigurieren und testen:

Auf der Ergebnis-Seite kannst du dir dann die zugehörige JSON-Ausgabe ansehen. In der Adressleiste steht dann der String für den API-Aufruf, ggf. musst du die URL-Parameter (wie maxrecords für die Anzahl der Artikel) noch deinen Bedürfnissen anpassen.

Und nun genug Vorgeplänkel – hier der Auszug aus dem Chat:

Wie kann ich in meinem WordPress-Blog dynamischen Content erzeugen? Ich möchte eine WebApi ansteuern, welche mir den Content im JSON-Format zurückgibt
Um dynamischen Content in deinem WordPress-Blog zu generieren, kannst du eine Funktion in deiner functions.php-Datei erstellen, die die Web-API ansteuert und die Daten im JSON-Format abruft. Anschließend kannst du die zurückgegebenen Daten in deinem WordPress-Blog anzeigen lassen.

Hier ist ein Beispiel-Code, der dir zeigen kann, wie du das machen kannst:
function get_api_data() {
  $url = 'https://example.com/api/data.json'; // Ersetze dies mit der URL deiner Web-API

  $response = wp_remote_get( $url );

  if( is_wp_error( $response ) ) {
    return false;
  }

  $data = wp_remote_retrieve_body( $response );

  return json_decode( $data );
}
Die Funktion get_api_data ruft die Web-API auf und gibt die Daten im JSON-Format zurück. Du kannst diese Funktion verwenden, um die Daten in deinem WordPress-Blog anzuzeigen.

Beispielsweise kannst du in deinem Template-File den folgenden Code verwenden, um den Inhalt der Web-API anzuzeigen:
<?php
  $api_data = get_api_data();

  if( $api_data ) {
    foreach( $api_data as $item ) {
      echo '<h2>' . $item->title . '</h2>';
      echo '<p>' . $item->content . '</p>';
    }
  }
?>
In diesem Beispiel gehen wir davon aus, dass die Web-API eine Liste von Artikeln zurückgibt, wobei jeder Artikel einen Titel und einen Inhalt hat. Die Schleife durchläuft jedes Element in der Liste und gibt den Titel und den Inhalt jedes Artikels aus.

Hinweis: Beim Abrufen von Daten aus externen Quellen ist es wichtig, sicherzustellen, dass die Daten zuverlässig sind und dass keine schädlichen Inhalte enthalten sind. Es ist auch wichtig sicherzustellen, dass du die APIs auf sichere Weise abrufst, beispielsweise durch Verwendung von SSL und Authentifizierung, falls erforderlich.
So sieht der Aufruf aus: 

https://api.gdeltproject.org/api/v2/doc/doc?format=html&timespan=24H&query=Artificial%20Intelligence%20sourcelang:eng&mode=artlist&maxrecords=1&format=json&sort=hybridrel 

und zurückgeliefert wird folgendes JSON: 

{"articles": [ { "url": "https://investorplace.com/2023/02/the-future-of-ai-stocks-7-companies-to-keep-your-eye-on/", "url_mobile": "", "title": "The Future of AI Stocks : 7 Companies to Keep Your Eye On", "seendate": "20230228T161500Z", "socialimage": "https://investorplace.com/wp-content/uploads/2023/02/artificial-intelligence-ai-green-1600.jpg", "domain": "investorplace.com", "language": "English", "sourcecountry": "United States" }] }
Basierend auf dem Beispiel-JSON, das du bereitgestellt hast, kannst du die Daten in deinem WordPress-Blog wie folgt anzeigen:
<?php
  $url = 'https://api.gdeltproject.org/api/v2/doc/doc?format=html&timespan=24H&query=Artificial%20Intelligence%20sourcelang:eng&mode=artlist&maxrecords=1&format=json&sort=hybridrel';

  $response = wp_remote_get( $url );

  if( is_wp_error( $response ) ) {
    echo 'Fehler beim Abrufen der Daten';
  } else {
    $data = json_decode( wp_remote_retrieve_body( $response ) );

    if( $data && !empty( $data->articles ) ) {
      foreach( $data->articles as $article ) {
        echo '<h2>' . $article->title . '</h2>';
        echo '<img src="' . $article->socialimage . '">';
        echo '<p>' . $article->seendate . '</p>';
        echo '<p>' . $article->url . '</p>';
      }
    } else {
      echo 'Keine Artikel gefunden';
    }
  }
?>
In diesem Beispiel wird die wp_remote_get-Funktion verwendet, um die Daten von der angegebenen URL abzurufen. Anschließend wird überprüft, ob ein Fehler aufgetreten ist, und die JSON-Daten werden dekodiert und in einer Schleife durchlaufen, um die Daten anzuzeigen.

In diesem Fall werden der Titel des Artikels, das soziale Bild, das Veröffentlichungsdatum und die URL des Artikels angezeigt. Du kannst die Anzeige jedoch nach Belieben anpassen, um die gewünschten Daten anzuzeigen.
Wie funktioniert der API-Aufruf über die functions.php?
Um den API-Aufruf in deiner WordPress-Seite über die functions.php-Datei zu implementieren, kannst du den folgenden Code verwenden:
function display_api_data() {
    $url = 'https://api.gdeltproject.org/api/v2/doc/doc?format=html&timespan=24H&query=Artificial%20Intelligence%20sourcelang:eng&mode=artlist&maxrecords=1&format=json&sort=hybridrel';

    $response = wp_remote_get( $url );

    if ( is_array( $response ) ) {
        $headers = $response['headers'];
        $body    = json_decode( $response['body'], true );

        if ( ! empty( $body ) && isset( $body['articles'] ) ) {
            $articles = $body['articles'];

            foreach ( $articles as $article ) {
                $title = $article['title'];
                $url   = $article['url'];
                $image = $article['socialimage'];

                echo '<div>';
                echo '<h2>' . $title . '</h2>';
                echo '<img src="' . $image . '" />';
                echo '<p><a href="' . $url . '">Read more</a></p>';
                echo '</div>';
            }
        }
    }
}
Dieser Code ruft die API-URL auf und gibt die JSON-Daten aus. Du kannst den Code anpassen, um den Inhalt deiner Seite zu generieren, indem du die foreach-Schleife entsprechend deiner Anforderungen änderst und den Inhalt der echo-Anweisungen anpasst.

Um den Code auszuführen, kannst du die Funktion display_api_data() in einer WordPress-Seite oder einem Post mit dem Shortcode [api_data] einbetten. Dazu musst du den folgenden Code in deiner functions.php-Datei hinzufügen:
function api_data_shortcode() {
    ob_start();
    display_api_data();
    return ob_get_clean();
}
add_shortcode( 'api_data', 'api_data_shortcode' );
Dieser Code registriert einen Shortcode [api_data], der die Funktion display_api_data() ausführt und den generierten Inhalt auf der Seite ausgibt. Du kannst den Shortcode auf einer beliebigen WordPress-Seite oder einem Post verwenden, indem du den folgenden Code in den Editor eingibst:

[api_data]
Wo finde ich die functions.php Datei?
Die functions.php-Datei befindet sich im Ordner des aktiven WordPress-Themes und enthält Funktionen und Filter, die auf der Website verwendet werden können. Der Pfad zur functions.php-Datei lautet normalerweise:

/wp-content/themes/your-theme/functions.php

Ersetze your-theme durch den Namen deines aktiven WordPress-Themes. Wenn du das Standard-Theme "Twenty Twenty-One" verwendest, lautet der Pfad zur functions.php-Datei:

/wp-content/themes/twentytwentyone/functions.php

Du kannst auf die functions.php-Datei über das Dashboard deiner WordPress-Website zugreifen. Gehe dazu zum Menü "Design" und klicke auf "Theme Editor". Wähle dann das aktive Theme aus der Dropdown-Liste oben rechts aus und wähle die Datei functions.php aus der Liste der Theme-Dateien auf der rechten Seite aus. Du kannst den Code direkt im Editor bearbeiten und speichern. Beachte jedoch, dass ein Fehler im Code deine Website beschädigen oder unbrauchbar machen kann, wenn du die functions.php-Datei bearbeitest. Es wird empfohlen, eine Sicherungskopie der Datei zu erstellen, bevor du Änderungen vornimmst.

In diesem Artikel haben wir gezeigt, wie du mit ChatGPT eine Funktion in der functions.php-Datei von WordPress generieren kannst, die die GDELT-API aufruft und die neuesten Nachrichten abruft. Das Ergebnis kannst du auf der News-Seite sehen.

Wichtig bei der unterstützten Programmierung mit ChatGPT ist, dass du den Programmcode im Dialog von ChatGPT optimieren lassen kannst und auch häufig musst. Auf die Tipps und Tricks im Umgang mit ChatGPT bzgl. der Code-Generierung wird es aber noch einen eigenen Beitrag geben.

Insgesamt kann die Verwendung von ChatGPT die Effizienz deiner Arbeit als Entwickler steigern, indem sie dir dabei hilft, schnell und einfach Beispielcode zu generieren. Ob es um die Integration von APIs oder um andere Anwendungsfälle geht, ChatGPT kann ein nützliches Werkzeug sein, um Zeit zu sparen und deine Entwicklungsarbeit zu beschleunigen.