{"id":2473,"date":"2025-09-17T15:02:58","date_gmt":"2025-09-17T13:02:58","guid":{"rendered":"https:\/\/davidka.net\/ru\/?p=2473"},"modified":"2025-09-22T02:14:05","modified_gmt":"2025-09-22T00:14:05","slug":"ai-agent-with-mcp","status":"publish","type":"post","link":"https:\/\/de.davidka.net\/de\/2025\/09\/17\/ai-agent-with-mcp\/","title":{"rendered":"Praktische Anleitung zum Erstellen von KI-Agenten mit LangGraph und MCP"},"content":{"rendered":"\n<p class=\"has-neve-link-color-color has-text-color has-link-color has-medium-font-size wp-elements-9d5270f00c31b26620bb86af6044fe10 wp-block-paragraph\">Dieser Artikel ist eine praktische Anleitung f\u00fcr Entwickler zur Erstellung autonomer KI-Agenten in Python. Wir werden die Theorie, was LangChain und LangGraph sind, nicht wiederholen. Stattdessen konzentrieren wir uns auf Code, Architektur und die L\u00f6sung realer Probleme.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Ziel:<\/strong> Zwei Projekte von Grund auf zu erstellen:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Ein Klassifizierungs-Agent:<\/strong> Ein mehrstufiger Agent mit verwaltetem Zustand, aber ohne externe Werkzeuge.<\/li>\n\n\n\n<li><strong>Ein Assistenz-Agent:<\/strong> Ein vollwertiger Agent mit Zugriff auf das Dateisystem und die Websuche \u00fcber das MCP-Protokoll, aufgebaut auf zyklischer Logik.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Wir werden Best Practices behandeln: Konfigurationsmanagement, Modellauswahl und Fehlerbehandlung, um robuste Systeme zu erstellen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Kurzer \u00dcberblick \u00fcber die Konzepte: Der Agent und die MCP-Br\u00fccke<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor wir in den Code eintauchen, lassen Sie uns zwei Konzepte festhalten:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>KI-Agent:<\/strong> Ein Programm, das um eine \u201eSchlussfolgerungs-Aktions-Schleife\u201c herum aufgebaut ist. Es erh\u00e4lt eine Aufgabe, entscheidet mit Hilfe eines LLM, was als n\u00e4chstes zu tun ist (z. B. ein Werkzeug aufrufen), f\u00fchrt die Aktion aus und wiederholt den Zyklus, bis die Aufgabe abgeschlossen ist.<\/li>\n\n\n\n<li><strong>MCP (Model Context Protocol):<\/strong> Ein Standard, der als <strong>Br\u00fccke<\/strong> zwischen der Logik des Agenten und externen Werkzeugen fungiert. Er erm\u00f6glicht es dem Agenten, auf einheitliche Weise mit Dateien, APIs oder der Suche zu arbeiten, ohne sich um deren Implementierungsdetails k\u00fcmmern zu m\u00fcssen.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Teil 1: Einrichtung einer robusten Umgebung<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 1: Virtuelle Umgebung und Abh\u00e4ngigkeiten<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Erstellen und aktivieren Sie eine virtuelle Umgebung. Erstellen Sie dann eine <code class=\"\" data-line=\"\">requirements.txt<\/code>-Datei:<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\"># Kern-Frameworks\nlangchain\nlanggraph\n\n# Modell-Adapter\nlangchain-openai\nlangchain-google-genai\nlangchain-mistralai\nlangchain-community # F\u00fcr Ollama\n\n# Werkzeuge und Protokolle\nlangchain-mcp-adapters\nmcp\nollama\n\n# Hilfsprogramme\npython-dotenv\ntenacity # F\u00fcr robuste Fehlerbehandlung<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Installieren Sie die Abh\u00e4ngigkeiten:<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">pip install -r requirements.txt```\n\n#### Schritt 2: Konfiguration der API-Schl\u00fcssel\n\nErstellen Sie eine `.env`-Datei, um Ihre Schl\u00fcssel zu speichern:<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">OPENAI_API_KEY=&#8220;sk-\u2026&#8220;<br>GOOGLE_API_KEY=&#8220;AIzaSy\u2026&#8220;<br>MISTRAL_API_KEY=&#8220;\u2026&#8220;<br>BRAVE_API_KEY=&#8220;\u2026&#8220; # F\u00fcr das Websuch-Werkzeug \u00fcber MCP<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">#### Schritt 3: Das \u201eModell-Factory\u201c-Muster\n\nUm flexibel zwischen Cloud- und lokalen Modellen wechseln zu k\u00f6nnen, ohne den Code des Agenten zu \u00e4ndern, verwenden wir das Factory-Muster.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">llm_factory.py<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">import os<br>from enum import Enum<br>from dotenv import load_dotenv<br>from langchain_openai import ChatOpenAI<br>from langchain_google_genai import ChatGoogleGenerativeAI<br>from langchain_mistralai import ChatMistralAI<br>from langchain_community.chat_models import ChatOllama<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">load_dotenv()<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">class ModelProvider(Enum):<br>OPENAI = &#8222;openai&#8220;<br>GEMINI = &#8222;gemini&#8220;<br>MISTRAL_API = &#8222;mistral_api&#8220;<br>OLLAMA = &#8222;ollama&#8220;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">def get_llm(provider: ModelProvider, model_name: str = None):<br>&#8222;&#8220;&#8220;Eine Factory zum Erstellen von LLM-Instanzen.&#8220;&#8220;&#8220;<br>if provider == ModelProvider.OPENAI:<br>return ChatOpenAI(model=model_name or &#8222;gpt-4o-mini&#8220;, temperature=0)<br>elif provider == ModelProvider.GEMINI:<br>return ChatGoogleGenerativeAI(model=model_name or &#8222;gemini-1.5-flash&#8220;, temperature=0)<br>elif provider == ModelProvider.MISTRAL_API:<br>return ChatMistralAI(model=model_name or &#8222;mistral-large-latest&#8220;, temperature=0)<br>elif provider == ModelProvider.OLLAMA:<br># Stellen Sie sicher, dass Ollama mit dem erforderlichen Modell l\u00e4uft<br># docker exec -it ollama ollama pull mistral<br>return ChatOllama(model=model_name or &#8222;mistral&#8220;, temperature=0)<br>raise ValueError(f&#8220;Unbekannter Modellanbieter: {provider}&#8220;)<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Anwendungsbeispiel<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">if <strong>name<\/strong> == &#8222;<strong>main<\/strong>&#8222;:<br># local_llm = get_llm(ModelProvider.OLLAMA)<br>openai_llm = get_llm(ModelProvider.OPENAI)<br>response = openai_llm.invoke(&#8222;Erkl\u00e4ren Sie das Konzept von RAG in drei S\u00e4tzen.&#8220;)<br>print(response.content)<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">### Teil 2: Projekt 1 \u2014 Agent zur Klassifizierung von Stellenanzeigen\n\nDieser Agent demonstriert, wie man LangGraph verwendet, um einen **linearen Graphen** mit verwaltetem Zustand zu erstellen. Er nimmt eine Stellenbeschreibung entgegen und klassifiziert sie sequenziell nach drei Parametern.\n\n#### Schritt 1: Definition des Zustands\n\nDer Zustand ist der \u201eSpeicher\u201c unseres Graphen, der von einem Knoten zum n\u00e4chsten weitergegeben wird.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">vacancy_classifier.py<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">from typing import TypedDict, Dict<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">class ClassificationState(TypedDict):<br>&#8222;&#8220;&#8220;Zustand f\u00fcr den Klassifizierungs-Agenten.&#8220;&#8220;&#8220;<br>description: str # Quelltext<br>job_type: str # Art der Anstellung (projektbasiert\/festangestellt)<br>category: str # Berufsbezeichnung<br>search_type: str # Ziel (sucht Job\/Auftragnehmer)<br>classification_log: list # Debug-Protokoll<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">#### Schritt 2: Implementierung der Graph-Knoten\n\nJeder Knoten ist eine Funktion, die den Zustand entgegennimmt, ihren Teil der Arbeit erledigt und den aktualisierten Zustand zur\u00fcckgibt.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<br>import asyncio<br>import json<br>from langchain_core.prompts import ChatPromptTemplate<br>from llm_factory import get_llm, ModelProvider<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">class VacancyClassifierAgent:<br>def <strong>init<\/strong>(self):<br>self.llm = get_llm(ModelProvider.OPENAI, model_name=&#8220;gpt-4o-mini&#8220;)<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">async def _classify_job_type(self, state: ClassificationState) -&gt; ClassificationState:\n    &quot;&quot;&quot;Knoten 1: Bestimmt die Art der Anstellung.&quot;&quot;&quot;\n    prompt = ChatPromptTemplate.from_messages(&#091;\n        (&quot;system&quot;, &quot;Bestimmen Sie die Art der Anstellung. Die Antwort muss &#039;projektbasiert&#039; oder &#039;festangestellt&#039; sein.&quot;),\n        (&quot;human&quot;, &quot;Stellenbeschreibung:\\n\\n{description}&quot;)\n    ])\n    chain = prompt | self.llm\n    result = await chain.ainvoke({&quot;description&quot;: state&#091;&quot;description&quot;]})\n\n    state&#091;&quot;job_type&quot;] = result.content.strip()\n    state&#091;&quot;classification_log&quot;].append(&quot;Art der Anstellung bestimmt.&quot;)\n    return state\n\nasync def _classify_category(self, state: ClassificationState) -&gt; ClassificationState:\n    &quot;&quot;&quot;Knoten 2: Bestimmt die Berufskategorie.&quot;&quot;&quot;\n    # Kategorien k\u00f6nnen aus einer Datei oder Datenbank geladen werden\n    categories = &#091;&quot;Python-Entwickler&quot;, &quot;Designer&quot;, &quot;Marketingspezialist&quot;, &quot;3D-Animator&quot;]\n    prompt = ChatPromptTemplate.from_messages(&#091;\n        (&quot;system&quot;, f&quot;W\u00e4hlen Sie die am besten geeignete Kategorie aus der Liste: {&#039;, &#039;.join(categories)}.&quot;),\n        (&quot;human&quot;, &quot;Stellenbeschreibung:\\n\\n{description}&quot;)\n    ])\n    chain = prompt | self.llm\n    result = await chain.ainvoke({&quot;description&quot;: state&#091;&quot;description&quot;]})\n\n    state&#091;&quot;category&quot;] = result.content.strip()\n    state&#091;&quot;classification_log&quot;].append(&quot;Kategorie bestimmt.&quot;)\n    return state\n\nasync def _classify_search_type(self, state: ClassificationState) -&gt; ClassificationState:\n    &quot;&quot;&quot;Knoten 3: Bestimmt das Suchziel.&quot;&quot;&quot;\n    prompt = ChatPromptTemplate.from_messages(&#091;\n        (&quot;system&quot;, &quot;Bestimmen Sie das Ziel des Autors. Die Antwort muss &#039;sucht Job&#039; oder &#039;sucht Auftragnehmer&#039; sein.&quot;),\n        (&quot;human&quot;, &quot;Stellenbeschreibung:\\n\\n{description}&quot;)\n    ])\n    chain = prompt | self.llm\n    result = await chain.ainvoke({&quot;description&quot;: state&#091;&quot;description&quot;]})\n\n    state&#091;&quot;search_type&quot;] = result.content.strip()\n    state&#091;&quot;classification_log&quot;].append(&quot;Suchziel bestimmt.&quot;)\n    return state<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">#### Schritt 3: Zusammenbau und Ausf\u00fchrung des Graphen\n\nWir bauen die Knoten zu einem einzigen Arbeitsablauf zusammen.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u2026 Fortsetzung der Klasse VacancyClassifierAgent \u2026<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">from langgraph.graph import StateGraph, END<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">def build_graph(self):\n    &quot;&quot;&quot;Baut den Zustandsgraphen zusammen.&quot;&quot;&quot;\n    workflow = StateGraph(ClassificationState)\n\n    workflow.add_node(&quot;job_type_classifier&quot;, self._classify_job_type)\n    workflow.add_node(&quot;category_classifier&quot;, self._classify_category)\n    workflow.add_node(&quot;search_type_classifier&quot;, self._classify_search_type)\n\n    workflow.set_entry_point(&quot;job_type_classifier&quot;)\n    workflow.add_edge(&quot;job_type_classifier&quot;, &quot;category_classifier&quot;)\n    workflow.add_edge(&quot;category_classifier&quot;, &quot;search_type_classifier&quot;)\n    workflow.add_edge(&quot;search_type_classifier&quot;, END)\n\n    return workflow.compile()<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">async def main():<br>agent = VacancyClassifierAgent()<br>graph = agent.build_graph()<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">description = &quot;Wir suchen einen erfahrenen Python-Entwickler, der unser Team in Vollzeit bei der Arbeit an einem Fintech-Projekt unterst\u00fctzt.&quot;\n\ninitial_state = ClassificationState(\n    description=description,\n    job_type=&quot;&quot;, category=&quot;&quot;, search_type=&quot;&quot;,\n    classification_log=&#091;]\n)\n\nfinal_state = await graph.ainvoke(initial_state)\n\nprint(&quot;--- Klassifizierungsergebnis ---&quot;)\nprint(json.dumps(final_state, indent=2, ensure_ascii=False))<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">if <strong>name<\/strong> == &#8222;<strong>main<\/strong>&#8222;:<br>asyncio.run(main())<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">### Teil 3: Projekt 2 \u2014 Assistenz-Agent mit Werkzeugen (MCP)\n\nDieser Agent demonstriert eine **zyklische Logik**, bei der er wiederholt Werkzeuge aufrufen kann, um eine Aufgabe zu l\u00f6sen.\n\n#### Schritt 1: Konfigurationsmanagement\n\nF\u00fcr Agenten, die mit der Au\u00dfenwelt interagieren, ist eine robuste Konfiguration unerl\u00e4sslich.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">mcp_agent_config.py<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">from dataclasses import dataclass, field<br>import os<br>from llm_factory import ModelProvider<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">@dataclass<br>class AgentConfig:<br>workdir: str = &#8222;.\/agent_workdir&#8220;<br>model_provider: ModelProvider = ModelProvider.OLLAMA<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">def __post_init__(self):\n    &quot;&quot;&quot;Validierung nach der Initialisierung.&quot;&quot;&quot;\n    os.makedirs(self.workdir, exist_ok=True)<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">#### Schritt 2: Definition des Zustands f\u00fcr den Dialog\n\nDer Zustand speichert nun den Nachrichtenverlauf.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">mcp_agent.py<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">from typing import TypedDict, Annotated, Sequence<br>from langchain_core.messages import BaseMessage<br>import operator<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">class AgentState(TypedDict):<br>messages: Annotated[Sequence[BaseMessage], operator.add]<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">#### Schritt 3: Implementierung des zyklischen Graphen\n\nDer Graph besteht aus zwei Hauptknoten und einer bedingten Kante, die die \u201eSchlussfolgerungs-Aktions-Schleife\u201c erzeugt.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<br>from langgraph.graph import StateGraph, END<br>from langgraph.prebuilt import ToolExecutor<br>from langchain_mcp_adapters.langchain import V1ToolExecutor<br>from langchain_mcp_adapters.clients import MultiServerMCPClient<br>from llm_factory import get_llm<br>from mcp_agent_config import AgentConfig<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">class MCPAgent:<br>def <strong>init<\/strong>(self, config: AgentConfig):<br>self.config = config<br>self.llm = get_llm(config.model_provider)<br>self.tools = []<br>self.tool_executor = None<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">async def setup_tools(self):\n    &quot;&quot;&quot;Initialisiert Werkzeuge \u00fcber MCP.&quot;&quot;&quot;\n    mcp_config = {\n        &quot;filesystem&quot;: {\n            &quot;command&quot;: &quot;npx&quot;, &quot;args&quot;: &#091;&quot;-y&quot;, &quot;@modelcontextprotocol\/server-filesystem&quot;, self.config.workdir],\n            &quot;transport&quot;: &quot;stdio&quot;\n        },\n        # F\u00fcgen Sie brave-search hinzu, wenn Sie einen BRAVE_API_KEY haben\n    }\n    mcp_client = MultiServerMCPClient(mcp_config)\n    self.tools = await mcp_client.get_tools()\n    self.tool_executor = ToolExecutor(&#091;V1ToolExecutor(tool) for tool in self.tools])\n\n    # Binden der Werkzeuge an das Modell\n    self.llm = self.llm.bind_tools(self.tools)\n\ndef _should_continue(self, state: AgentState):\n    &quot;&quot;&quot;Bedingte Kante: entscheidet, ob ein Werkzeug aufgerufen werden soll.&quot;&quot;&quot;\n    last_message = state&#091;&#039;messages&#039;]&#091;-1]\n    if not last_message.tool_calls:\n        return &quot;end&quot;\n    return &quot;continue&quot;\n\ndef _call_model(self, state: AgentState):\n    &quot;&quot;&quot;Knoten 1: Ruft das LLM auf, um eine Entscheidung zu treffen.&quot;&quot;&quot;\n    response = self.llm.invoke(state&#091;&#039;messages&#039;])\n    return {&quot;messages&quot;: &#091;response]}\n\ndef _call_tool(self, state: AgentState):\n    &quot;&quot;&quot;Knoten 2: F\u00fchrt den Werkzeugaufruf aus.&quot;&quot;&quot;\n    last_message = state&#091;&#039;messages&#039;]&#091;-1]\n    tool_call = last_message.tool_calls&#091;0]\n\n    action = {&quot;tool&quot;: tool_call&#091;&quot;name&quot;], &quot;tool_input&quot;: tool_call&#091;&quot;args&quot;], &quot;log&quot;: &quot;&quot;}\n    response = self.tool_executor.invoke(action)\n\n    return {&quot;messages&quot;: &#091;response]}\n\ndef build_graph(self):\n    workflow = StateGraph(AgentState)\n    workflow.add_node(&quot;agent&quot;, self._call_model)\n    workflow.add_node(&quot;action&quot;, self._call_tool)\n\n    workflow.set_entry_point(&quot;agent&quot;)\n    workflow.add_conditional_edges(\n        &quot;agent&quot;,\n        self._should_continue,\n        {&quot;continue&quot;: &quot;action&quot;, &quot;end&quot;: END}\n    )\n    workflow.add_edge(&quot;action&quot;, &quot;agent&quot;)\n\n    return workflow.compile()<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">#### Schritt 4: Ausf\u00fchrung und Interaktion<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u2026 Fortsetzung von mcp_agent.py \u2026<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">import asyncio<br>from langchain_core.messages import HumanMessage<br>from tenacity import retry, stop_after_attempt, wait_fixed<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))<br>async def run_agent_task(graph, task):<br>&#8222;&#8220;&#8220;F\u00fchrt eine Aufgabe mit Fehlerbehandlung aus.&#8220;&#8220;&#8220;<br>return await graph.ainvoke({&#8222;messages&#8220;: [HumanMessage(content=task)]})<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">async def main():<br>config = AgentConfig(model_provider=ModelProvider.OPENAI) # oder OLLAMA<br>agent = MCPAgent(config)<br>await agent.setup_tools()<br>graph = agent.build_graph()<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">task = &quot;Erstelle eine Datei namens &#039;hallo.txt&#039; im Arbeitsverzeichnis und schreibe &#039;Hallo, Welt!&#039; hinein.&quot;\nresult = await run_agent_task(graph, task)\n\nprint(&quot;\\n--- Endg\u00fcltige Antwort des Agenten ---&quot;)\nprint(result&#091;&#039;messages&#039;]&#091;-1].content)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">if <strong>name<\/strong> == &#8222;<strong>main<\/strong>&#8222;:<br>asyncio.run(main())<br><code class=\"\" data-line=\"\">`` Hier haben wir den<\/code>tenacity`-Dekorator f\u00fcr Robustheit hinzugef\u00fcgt \u2013 wenn der Agentenaufruf aufgrund eines vor\u00fcbergehenden Netzwerkfehlers fehlschl\u00e4gt, wird er automatisch wiederholt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fazit<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wir haben zwei Arten von Agenten unter Verwendung moderner Praktiken erstellt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ein <strong>linearer Graph<\/strong> eignet sich hervorragend f\u00fcr Aufgaben mit einer klaren Abfolge von Schritten, wie z. B. ETL-Prozesse oder mehrstufige Analysen.<\/li>\n\n\n\n<li>Ein <strong>zyklischer Graph<\/strong> ist die Grundlage f\u00fcr die Erstellung interaktiver Assistenten und autonomer Agenten, die in der Lage sind, komplexe Probleme mit Werkzeugen zu l\u00f6sen.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Die vorgestellten Architekturmuster \u2013 die Modell-Factory, das Konfigurationsmanagement, die Trennung der Logik in Knoten und die Verwendung von Zustandsgraphen \u2013 sind die Grundlagen f\u00fcr den Aufbau skalierbarer und robuster KI-Systeme.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dieser Artikel ist eine praktische Anleitung f\u00fcr Entwickler zur Erstellung autonomer KI-Agenten in Python. Wir werden die Theorie, was LangChain und LangGraph sind, nicht wiederholen. Stattdessen konzentrieren wir uns auf Code, Architektur und die L\u00f6sung realer Probleme.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_themeisle_gutenberg_block_has_review":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-2473","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/posts\/2473","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/comments?post=2473"}],"version-history":[{"count":0,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/posts\/2473\/revisions"}],"wp:attachment":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/media?parent=2473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/categories?post=2473"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/tags?post=2473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}