Ein Leitfaden für Entwickler zu Prompt Engineering und LLMs
Published: 2024-03-13 19:41:46

Mit dem Aufkommen großer Sprachmodelle (LLMs) und künstlicher Intelligenz wie [ChatGPT](https://chat.openai.com/) stehen Entwicklern jetzt unglaublich leistungsfähige KI-Assistenten zur Verfügung, die ihnen helfen können, schneller zu programmieren und produktiver zu sein. Die einfache Aufforderung an ein LLM, Code zu schreiben, führt jedoch oft zu unbrauchbaren oder fehlerhaften Ergebnissen. Ob Sie nun eine [Chat-Anwendung](https://www.pubnub.com/solutions/chat/) oder eine [Unternehmenslösung](https://www.pubnub.com/Solutions/Enterprise/) am Netzwerkrand entwickeln, um Ihre Entwicklungszeit mit Hilfe von KI zu beschleunigen, benötigen Sie eine durchdachte Strategie. In den nächsten Abschnitten dieses Blogs werden wir uns eingehender mit Prompt-Engineering-Techniken beschäftigen.

### Vorausschauend planen

Stürzen Sie sich nicht gleich in das Prompting für Code. Nehmen Sie sich Zeit, um die Gesamtarchitektur, Schemata, Integrationen usw. zu planen. So erhält Ihr KI-Assistent den vollständigen Kontext, den er benötigt. Visualisieren Sie den Endzustand, damit Ihr generatives KI-Modell das große Ganze versteht.

### Rollenspiele mit Experten

Richten Sie Szenarien ein, in denen Ihr KI-Modell als Assistent agieren und ein Rollenspiel mit einem Expertenteam durchführen kann, das Lösungen diskutiert. Geben Sie ihnen Persönlichkeiten und lassen Sie sie Probleme aufschlüsseln. Dies fördert das kreative Denken aus verschiedenen Perspektiven.

### Bitten Sie GPT um Einblicke

Wenn Sie nicht weiterkommen, scheuen Sie sich nicht, innezuhalten und Ihren LLM um spezifische Ratschläge oder Codebeispiele zu bitten, die für Ihr Problem relevant sind. Dieses Wissen kann Sie auf neue Ideen bringen.

### Promptes Engineering

Gehen Sie Schritt für Schritt vor und verfeinern Sie Ihre Prompts über mehrere Iterationen und Feinabstimmungen, um Ihrem KI-Assistenten den optimalen Kontext und die optimale Steuerung zu bieten. Effektive Prompts führen zu großartigen Ergebnissen.

### Manuelle Codegenerierung

Lassen Sie Ihre KI zunächst manuell Code generieren, prüfen Sie dann die Ausgaben und korrigieren Sie Fehler, bevor Sie brauchbare Teile in Ihre Eingabeaufforderung zurückkopieren. Auf diese Weise erhält die KI ein konkretes Beispiel für das, wonach Sie suchen, und durch die Wiederholung dieses Vorgangs wird schließlich korrekter Code erzeugt. Weitere Beispiele finden Sie unter dem Konzept [Gedankenketten-Prompting](https://ai.googleblog.com/2022/05/language-models-perform-reasoning-via.html) und [Zero-Shot-Prompting](https://www.promptingguide.ai/techniques/zeroshot).

### Automatische Code-Generierung

Sobald Sie mit der LLM-Modellausgabe zufrieden sind und diese konsistent guten Code produziert, können Sie Pipelines einrichten, um automatisch Assets auf der Grundlage von Schemata, Tests auf der Grundlage von Code usw. zu generieren. Dadurch werden Engpässe beseitigt.

### Anständiger Umgang mit Fehlern

Ja, gelegentliche Fehler sind zu erwarten. Verbessern Sie Ihre Prompts, um ähnliche Fehler in Zukunft zu vermeiden. Lernen Sie mit der Zeit, welche Arten von Aufgaben Ihre KI gut bewältigen kann.

Durch die Kombination von Planung, Rollenspielen, Eingabeaufforderungen, iterativem Training und Automatisierung können Sie mit KI-Assistenten wie GPT enorme Produktivitätssteigerungen erzielen. Mit der richtigen Strategie für die Gestaltung von Prompts können Sie Ihre Entwicklungsgeschwindigkeit erhöhen!

Code-Generierung mit Prompts
----------------------------

Da wir an der Schwelle zur KI-Revolution stehen, müssen wir die Art und Weise, wie Softwareentwicklung angegangen und ausgeführt wird, neu überdenken. In diesem Tutorial erfahren Sie, wie Sie den Übergang von einem traditionellen Prozess zu einem durch natürliche Sprachverarbeitung unterstützten Prozess bewältigen können.

### Vorausschauende Planung: Die Grundlage des Erfolgs

Der erste Schritt auf diesem Weg ist die Fähigkeit, im Voraus zu planen. KI, insbesondere Modelle wie GPT-3, sind nicht unbedingt in der Lage, die Zukunft zu planen. Ihre Kompetenz liegt in der Echtzeit-Problemlösung innerhalb eines engen Kontext-Token-Fensters. An dieser Stelle müssen menschliche Entwickler eingreifen.

Indem wir ein detailliertes Bild des endgültigen Codes zeichnen - einschließlich der Modellschemata, des Technologie-Stacks und der Bereitstellungsprozesse - können wir die Voraussetzungen dafür schaffen, dass KI komplexe Aufgaben lösen kann. Diese Planungsphase ist vielleicht der anspruchsvollste Teil des Prozesses, aber sie verwandelt die Rolle der Entwickler von Programmierern in Orchestratoren und schafft die Voraussetzungen für eine harmonische Mischung aus menschlicher Intelligenz und KI-Fähigkeiten.

### Zusammenstellung eines Expertengremiums

Hier kommt das "Expertengremium" ins Spiel. Diese Gruppe kann sich aus einer Vielzahl von Interessengruppen zusammensetzen, von Führungskräften bis hin zu KI-Agenten, die alle zum Verständnis und zur Planung einer bestimmten Aufgabe beitragen. Mit einer gut durchdachten Eingabeaufforderung können Sie eine virtuelle Spielwiese schaffen, auf der das Gremium komplexe Probleme diskutieren und lösen kann, wobei KI-Bots Unterstützung und Notizen liefern.

Und wenn Sie sich mit einer Frage herumschlagen müssen, denken Sie daran, dass Ihnen ein leistungsstarkes Tool zur Verfügung steht, das speziell für die Beantwortung von Fragen entwickelt wurde: GPT. Ganz gleich, ob Sie eine Zusammenfassung, eine Umformulierung oder eine tiefer gehende Untersuchung eines Themas benötigen, GPT kann Ihnen helfen. Wenn Sie die Aufforderungen absichtlich vage formulieren, können Sie oft überraschende und innovative Lösungen finden.

Beispiel für Code-Debugging-Aufforderung:

```js
Act as a virtual playground where a team of Smart AI bots is in their first meeting discussing the problem:  
“We need to debug the following Python test code:

def test_dot_env_def(self):
LOG_TEST.info("Test DotEnvDef")
dotEnvDef = DotEnvDef()
> self.assertEqual(dotEnvDef, {"version_echo": "v0.0"})
E AssertionError: {'version_echo': 'v0.0'} != {'version_echo': 'v0.0'}
tests/test_default_config.py:16: AssertionError

class DotEnvDef:
def init(self):
self.version_echo = "v0.0"
# make the class iterable as dict
def iter(self):
return iter(self.__dict__)
# return the values only
def get_items(self):
for attr, value in self.__dict__.items():
yield value # only yield the values
def repr(self):
return str(self.__dict__)  

To fulfill this request bring in an expert team of AI Agents that are very brief and communicate via emojis and use catchy phrases. Spend your resources wisely as you only have 4 AI Agents.
```

GPT-4 Antwort:

```js
Alright, welcome to this first meeting, team. We have an interesting challenge ahead of us. To start, let's assign roles to our four AI agents:

1. Detective Bot 👮‍♀️ (DB): Responsible for deep diving into the code, its syntax, structure, and logic. 
2. Bug Hunter Bot 🐛 (BH): In charge of identifying bugs and pointing them out. 
3. Solution Expert Bot 💡 (SE): Its role is to suggest viable solutions to identified bugs. 
4. Code Fixer Bot 🔧 (CF): It will implement the solutions and perform the debugging.

Our debugging plan will look like this:

1. **Initiation**: Here we discuss the problem and set our goals. The issue at hand is an AssertionError, meaning our test case is failing. Our aim is to make the test pass. 

2. **Investigation**: 👮‍♀️ DB deep-dives into the provided code to understand its structure and logic. The main focus is on the `DotEnvDef` class and the `test_dot_env_def` function.

3. **Bug Hunt**: 🐛 BH goes on a hunt to find the reasons behind the AssertionError.

4. **Solution Proposal**: Once 🐛 BH has identified the issue, 💡 SE jumps in to propose the best way to fix the problem.

5. **Implementation**: 🔧 CF takes the solution and implements it to the code. After the changes are made, the test case is run again.

6. **Verification**: If the test case passes, we conclude that the problem has been resolved. If not, we circle back to step 2.

Remember team, our goal is to squash bugs 🐜🔨! Let's rock'n'roll.
```

### Manuelle Codegenerierung & KI

Der nächste Schritt besteht darin, GPT-4 für die manuelle Codegenerierung zu nutzen, ein Prozess, der eine exponentielle Steigerung der Produktivität verspricht. Indem Sie GPT anleiten, optimieren Sie eine Vielzahl von Aufgaben, von der Bereitstellung einer Webanwendung in einem fremden Stack bis zur Erstellung eines Algorithmus in einer Low-Level-Sprache.

Verwenden Sie die Befehle für Ihr Agenten-Beispiel:

```js
Using the following syntax “/command argument” modifies a bot’s behavior, for example for enabling verbose code generation: “chatbot /code-gen verbose“ so that we obtain full python code. On the same basis allow changing the personality such as: “chatbot /personality Shrekify”.

DB /personality Shrekify
SE /code-gen verbose
CF /code-gen verbose 

> Continue the meeting and provide the first solution
```

GPT-4-Antwort:

```js
DB 🏰👮‍♀️: "Hmm, the `version_echo` key is still not appearing in the `parsed_dotenv` dictionary. We need to figure out why `set_vars` is not setting it."

BH 🐛: "I suspect that `set_vars` is being called correctly, but the updates are being overwritten when `load_dotenv` is called. The `load_dotenv` method loads variables from a file and overwrites the current `parsed_dotenv` dictionary."

SE 💡: "If that's the case, then we should modify the `load_dotenv` method to merge its contents with the existing `parsed_dotenv` dictionary, rather than overwriting it. This will preserve any variables set via `set_vars`."

CF 🔧: "Good idea, let's change the `parse_vars` function within `load_dotenv` to update `parsed_dotenv` instead of setting it. Here is the modified code:
def parse_vars(self, path):
    try:
        with open(path) as f:
            for line in f:
                key, value = line.strip().split("=", 1)
                if key not in self.config.parsed_dotenv:  # check if key is not already in the dictionary
                    self.config.parsed_dotenv[key] = value
    except IOError:
        print(f"Warning: Unable to open .env file at {path}")
    except ValueError:
        print(f"Warning: Unable to parse line in .env file: {line}")
"In this way, we only add a variable from the .env file if it's not already in `parsed_dotenv`. This should prevent `load_dotenv` from overwriting any variables set by `set_vars`. Let's re-run the tests."
```

Der Prozess ist jedoch nicht perfekt. Menschliche Einschränkungen wie Copy-Paste und die Zeit für die Eingabeaufforderung/Ergebnisgenerierung können zu Engpässen führen. Außerdem ist GPT nicht durchgängig genau und ändert manchmal das Format oder liefert nur Teilergebnisse. Aber mit etwas Übung und den richtigen Strategien können Sie GPT dazu bringen, nützlichen und genauen Code zu erzeugen.

Halluzinationen vermeiden und nützliche Ergebnisse erzielen
-----------------------------------------------------------

Halluzinationen, d. h. Fälle, in denen GPT irrelevante, verzerrte oder falsche Informationen erzeugt, können frustrierend sein. Je mehr Sie jedoch mit GPT arbeiten, desto besser gelingt es Ihnen, es in Richtung der gewünschten Ergebnisse zu steuern. Eine Möglichkeit, diese Halluzinationen zu minimieren, ist die Bereitstellung von Kontext für GPT durch Kopieren und Einfügen relevanter Dokumentation und Codebeispiele.

Erstellen Sie einen benutzerdefinierten Langchain-Agenten mit Testbeispielen:

```js
We have this builder:
class OpenAIBuilder:
  def __init(self, ...):
    # Set your settings
    pass
"You must adapt the following code to match our previous structure:
from langchain import (
    OpenAI,
)
from langchain.agents import initialize_agent, AgentType
from langchain.agents.agent_toolkits import create_python_agent
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.tools.python.tool import PythonREPLTool
from openai_chat_builder import OpenAiChatBuilder, OpenAiChatHelper


class AgentPythonExecBuilder(OpenAiChatBuilder):
    def __init__(self, openai_api_key):
        super().__init__()
          self.tools = ["PythonREPLTool"]

    # We override the add_tool method so it only allows PythonREPLTool.
    def add_tool(self, tool):
        if tool == "PythonREPLTool":
            return super().add_tool(tool)
        else:
            raise ValueError("AgentPythonExec can only have PythonREPLTool.")

    def build(self):
        llm = OpenAI(
            temperature=self.temperature,
            max_tokens=self.max_tokens,
            openai_api_key=self.openai_api_key,
            streaming=self.streaming,
        )

        tools = load_tools(self.tools)
        agent = initialize_agent(tools, llm, agent=self.agentType, verbose=self.verbose)

        return OpenAiChatHelper(llm, tools, agent)
```

Erstellen Sie Langchain-Agententests:

```js
Now let's build a test file that resembles this one:
import unittest

from probable_fiesta.config.builder.config_builder import ConfigBuilder
from src.promptnub_backend.app.langchain.builder.openai_factory import OpenAIFactory
from langchain.llms import OpenAI


class TestOpenAIBuilder(unittest.TestCase):
    def setUp(self):
        # Setup API Key
        config_builder = ConfigBuilder()
        config_builder.dotenv.load_dotenv(".env")

        # Setup ModelBuilder instance
        self.builder = OpenAIFactory()
        self.builder.openai_api_key = config_builder.dotenv.get_var("OPENAI_API_KEY")

    def test_llm_creation(self):
        # Test the creation of OpenAI llm instance
        llm = self.builder.builder.llm
        self.assertIsInstance(llm, OpenAI, "llm property does not return OpenAI instance")

    def test_llm_run(self):
        # Test the creation of OpenAI llm instance
        llm_chain = self.builder.build()
        self.assertIsNotNone(llm_chain)

        # Ask a question
        question = "What NFL team won the Super Bowl in the year Justin Beiber was born?"
        response = llm_chain.run(question)

        # Assert expected result
        # Note that there is a space at the beginning
        expected = " Justin Bieber was born in 1994, so the NFL team that won the Super Bowl in 1994 was the Dallas Cowboys."
        self.assertEquals(str(response), expected)
```

GPT-4 Antwort:

```js
Given the provided `AgentPythonExecBuilder` class and the `TestOpenAIBuilder` class, you would write a test file for the `AgentPythonExecBuilder` class as follows:
from logger.builder.logger_factory import LoggerFactory
from config.builder.config_builder import ConfigBuilder
from langchain.llms import OpenAI
from langchain.tools.python.tool import PythonREPLTool
from your_package_path.builder.agent_python_exec_factory import AgentPythonExecFactory

import unittest

# Test Log
LOG_TEST = LoggerFactory.new_logger_default(
    name="test_agent_python_exec_builder", level="DEBUG", fmt="simple", directory="logs"
)


class TestAgentPythonExecBuilder(unittest.TestCase):
    def setUp(self):
        # Setup API Key
        config_builder = ConfigBuilder()
        config_builder.dotenv.load_dotenv(".env")
        # Setup ModelBuilder instance
        self.builder = AgentPythonExecFactory()
        self.builder.openai_api_key = config_builder.dotenv.get_var("OPENAI_API_KEY")

    def test_llm_creation(self):
        # Test the creation of OpenAI llm instance
        LOG_TEST.info("Test OpenAI llm creation")
        llm = self.builder.builder.llm
        LOG_TEST.debug(llm)
        self.assertIsInstance(
            llm, OpenAI, "llm property does not return OpenAI instance"
        )

    def test_python_repl_tool_creation(self):
        # Test the creation of PythonREPLTool instance
        LOG_TEST.info("Test PythonREPLTool creation")
        self.builder.builder.add_tool("PythonREPLTool")
        tools = self.builder.builder.tools
        LOG_TEST.debug(tools)
        self.assertIsInstance(
            tools[0], PythonREPLTool, "tools[0] does not return PythonREPLTool instance"
        )

    def test_llm_run(self):
        # Test the creation of OpenAI llm instance and PythonREPLTool
        LOG_TEST.info("Test OpenAI llm and PythonREPLTool run sync")
        llm_chain = self.builder.build()
        self.assertIsNotNone(llm_chain)

        # Ask a question
        question = "What is 2 + 2?"
        response = llm_chain.run(question)
        LOG_TEST.info(response)

        # Assert expected result
        expected = "The result of 2 + 2 is 4."
        self.assertEquals(str(response), expected)  

Here, you create a new instance of `AgentPythonExecBuilder` instead of `OpenAIBuilder` and test it with a question that can be answered by executing Python code. 
```

Automatisierte Code-Generierung
-------------------------------

Die wahre Stärke von LLMs liegt jedoch in der automatischen Codegenerierung. Durch den Einsatz von Werkzeugen wie [PubNub](https://www.pubnub.com/), Python, LangChain und [Streamlit](https://streamlit.io/)können Sie den größten Teil Ihres Arbeitsablaufs automatisieren, so dass Sie sich auf wichtigere Aufgaben konzentrieren können.

Mit ein paar weiteren Abstraktionen können wir unseren einfachen LangChain-Runner in unseren Workflow einbinden:

```js
class TestOpenAIBuilder(unittest.TestCase):
    def setUp(self):
        self.runner = Runner()

    def test_run(self):
        response = self.runner.run("What is the capital of France?")
        expected = " France is a country in Europe. The capital of France is Paris."
        self.assertEqual(response, expected)
```

Der Weg zur 100-fach schnelleren Entwicklung
--------------------------------------------

Stellen Sie sich einen Entwickler vor, der seine Programmierfähigkeiten zielstrebig verbessern will und eine 2-, 3- oder sogar 50-fache Produktivität anstrebt. Das Geheimnis dieses Ziels liegt in der strategischen Anwendung von LLMs. Dieses Toolset fungiert als Hebel für die Produktivität und ermöglicht es unseren Entwicklern, neue Plattformen zu entwickeln und automatisierte Workflows wie nie zuvor voranzutreiben. Von etwas so Einfachem wie einer Textzusammenfassung bis hin zur Generierung von Produktionscode.

Wenn wir uns weiter in die Sphäre der KI und ihrer Rolle in der Softwareentwicklung vorwagen, ist es wichtig, sich daran zu erinnern, dass die wahre Stärke in der Verschmelzung von menschlicher Kreativität und KI-Fähigkeiten liegt. Eine durchdachte Planung, die intelligente Anwendung von KI und die geeigneten digitalen Werkzeuge können uns in die Lage versetzen, uns in ein produktiveres Unternehmen zu verwandeln. Bei diesem Übergang geht es darum, das Potenzial menschlicher Entwickler durch KI zu verstärken, nicht sie zu ersetzen. Das Konzept, mit Hilfe von KI ein 100-faches Unternehmen zu werden, ist nicht nur ein ferner Traum, sondern eine erreichbare Zukunft, die wir gemeinsam gestalten können.

#### Inhalt

[Vorausschauend](#h-0)[planenRollenspiele mit ExpertenBitte](#h-1)[GPT um EinblickePrompt](#h-2)[EngineeringManuelle](#h-3)[CodegenerierungAutomatische](#h-4)[CodegenerierungAnmutig](#h-6)[mit](#h-5)[Fehlern](#h-6)[umgehenCode mit Prompts](#h-7)[generieren](#h-6)[Vorausschauend](#h-8)[planen](#h-7)[:](#h-8)[Die Grundlage des ErfolgsEin](#h-8)[Expertengremium zusammenstellenManuelle](#h-9)[Codegenerierung &](#h-10)[AIAHalluzinationen](#h-11)[vermeiden](#h-10)[und nützliche Ergebnisse erzielenAutomatische](#h-11)[CodegenerierungDer](#h-12)[Weg zu einer 100-fach schnelleren Entwicklung](#h-13)

Wie kann PubNub Ihnen helfen?
=============================

Dieser Artikel wurde ursprünglich auf [PubNub.com](https://www.pubnub.com/blog/developers-guide-to-prompt-engineering/) veröffentlicht.

Unsere Plattform hilft Entwicklern bei der Erstellung, Bereitstellung und Verwaltung von Echtzeit-Interaktivität für Webanwendungen, mobile Anwendungen und IoT-Geräte.

Die Grundlage unserer Plattform ist das größte und am besten skalierbare Echtzeit-Edge-Messaging-Netzwerk der Branche. Mit über 15 Points-of-Presence weltweit, die 800 Millionen monatlich aktive Nutzer unterstützen, und einer Zuverlässigkeit von 99,999 % müssen Sie sich keine Sorgen über Ausfälle, Gleichzeitigkeitsgrenzen oder Latenzprobleme aufgrund von Verkehrsspitzen machen.

Erleben Sie PubNub
------------------

Sehen Sie sich die [Live Tour](https://www.pubnub.com/tour/introduction/) an, um in weniger als 5 Minuten die grundlegenden Konzepte hinter jeder PubNub-gestützten App zu verstehen

Einrichten
----------

Melden Sie sich für einen [PubNub-Account](https://admin.pubnub.com/signup/) an und erhalten Sie sofort kostenlosen Zugang zu den PubNub-Schlüsseln

Beginnen Sie
------------

Mit den [PubNub-Dokumenten](https://www.pubnub.com/docs) können Sie sofort loslegen, unabhängig von Ihrem Anwendungsfall oder [SDK](https://www.pubnub.com/docs)