Startseite / Artikel / Produktions-IA-Agenten mit FastAPI, LangGraph und sauberer Architektur

Produktions-IA-Agenten mit FastAPI, LangGraph und sauberer Architektur

Schichtgrenzen, typisierte Graphenzustände, testbare Dienste sowie eine Deployment-Struktur, die die Wartbarkeit der Agenten gewährleistet.

3005 Wörter

Dieser Leitfaden zeigt Schritt für Schritt den Weg von Rohstoffen bis zu einem funktionsfähigen System für: „Wie ich KI-Agenten für die Produktion mit FastAPI, LangGraph und Clean Architecture strukturiere“. Der Schwerpunkt liegt auf ausführbaren Schritten, expliziten Überprüfungen sowie Code, den man ohne Rätseln über die Absicht direkt in ein Repository einfügen kann. Zur Übersicht sollten Sie vor dem Ändern des Codes die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien definieren. Die Betreiber sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bewahren Sie Konfigurationen außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den die Betreiber überprüfen können, ohne den gesamten Ablauf durchlesen zu müssen.

@router.post("/suppliers")
async def create_supplier(request: SupplierRequest):
    policies = opensearch.search(
            index="supplier-policies",
            query=request.description,
        )
        response = bedrock.converse(
            modelId=MODEL_ID,
            messages=build_messages(request, policies),
        )
        supplier = Supplier(
            name=request.name,
            tax_id=request.tax_id,
        )
        db.add(supplier)
        db.commit()
        sqs.send_message(
            QueueUrl=SUPPLIER_QUEUE,
            MessageBody=serialize(supplier),
        )
        return {"status": "created"}

FastAPI ist eine Schnittstelle – nicht die Anwendung

Für FastAPI ist eine Schnittstelle – nicht die Anwendung – definieren Sie vor dem Ändern des Codes die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zustände schließen zu müssen. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholte Versuche, menschliche Überprüfungen und die Handhabung von Fehlnachrichten gehören zum Produkt selbst, nicht zu späteren Optimierungen. Verwenden Sie Einschränkungen und Indizes vor dem Masseneinlesen. Die Eindeutigkeit der Geschäftschlüssel sorgt dafür, dass spätere Zusammenführungen zu vorhersehbaren Upserts statt zu Doppelungsproblemen werden.

@router.post("/suppliers")
async def create_supplier(
    request: CreateSupplierRequest,
    use_case: CreateSupplierUseCase = Depends(
        get_create_supplier_use_case
    ),
):
    command = CreateSupplierCommand(
        name=request.name,
        tax_id=request.tax_id,
        country=request.country,
    )

    result = await use_case.execute(command)
    return CreateSupplierResponse.from_result(result)
HTTP Request
     ↓
   FastAPI
     ↓
 Application
     ↓
   Domain
     ↓
    Ports
     ↓
  Adapters

Die Anwendung kommuniziert mit Funktionalitäten, nicht mit Technologien

Für Anwendungen, die mit Funktionalitäten und nicht mit Technologien arbeiten, sollten Eingaben, der Verantwortliche für einen Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zuständen schließen zu müssen. Zur Vorzugsbehandlung sollten kleine, testbare Einheiten vor umfangreichen Skripten stehen. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Verwenden Sie Einschränkungen und Indizes vor der Masseneingabe. Die Eindeutigkeit von Geschäfts Schlüsseln sorgt dafür, dass spätere Zusammenführungen zu vorhersehbaren Aktualisierungen statt zu Doppelungsproblemen führen.

class CreateSupplierUseCase:
    def __init__(
        self,
        repository: SupplierRepository,
        policy_service: SupplierPolicyService,
        event_publisher: EventPublisher,
    ):
        self.repository = repository
        self.policy_service = policy_service
        self.event_publisher = event_publisher
    async def execute(
        self,
        command: CreateSupplierCommand,
    ) -> Supplier:
        existing = await self.repository.find_by_tax_id(
            command.tax_id
        )
        if existing:
            raise SupplierAlreadyExists(command.tax_id)
        policy = await self.policy_service.evaluate(
            country=command.country
        )
        supplier = Supplier.create(
            name=command.name,
            tax_id=command.tax_id,
            country=command.country,
            requires_approval=policy.requires_approval,
        )
        await self.repository.add(supplier)
        await self.event_publisher.publish(
            SupplierCreated(supplier.id)
        )
        return supplier

Ports bilden die Grenze

Für Ports sollte man zunächst die Grenzen festlegen, die Eingaben definieren, den Verantwortlichen für den Schritt sowie die Abbruchkriterien bestimmen, bevor der Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Verwenden Sie Einschränkungen und Indizes vor der Masseneingabe. Die Eindeutigkeit der Geschäfts Schlüssel sorgt dafür, dass spätere Zusammenführungen zu vorhersehbaren Upserts statt zu Doppelgängerproblemen werden. Für Ports sollte man zunächst die Grenzen festlegen, die Eingaben definieren, den Verantwortlichen für den Schritt sowie die Abbruchkriterien bestimmen, bevor der Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher und Feature Flags sollten an einem Ort gespeichert werden, den die Operator überprüfen können, ohne den gesamten Code durchlesen zu müssen.

ph.

from typing import Protocol

class SupplierRepository(Protocol):
    async def find_by_tax_id(
        self,
        tax_id: str,
    ) -> Supplier | None:
        ...
    async def add(
        self,
        supplier: Supplier,
    ) -> None:
        ...

class PolicyRetriever(Protocol):
    async def retrieve(
        self,
        query: str,
    ) -> list[PolicyDocument]:
        ...

class LLMProvider(Protocol):
    async def reason(
        self,
        context: AgentContext,
    ) -> AgentDecision:
        ...

class EventPublisher(Protocol):
    async def publish(
        self,
        event: DomainEvent,
    ) -> None:
        ...
SupplierRepository
PolicyRetriever
LLMProvider
EventPublisher
PostgreSQL
Amazon OpenSearch
Amazon Bedrock
AWS SQS

Wo Amazon Bedrock hingehört

Zur Bestimmung dessen, wohin Amazon Bedrock gehört, sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Notfallweg gemeinsam. Wiederholungsversuche, menschliche Überprüfungen sowie die Handhabung fehlerhafter Nachrichten gehören zum Produkt selbst und nicht zu späteren Optimierungen. Überprüfen Sie nach der ersten Batch-Verarbeitung ein Beispielumfeld. Cypher-Proben erkennen Label-Abweichungen und fehlende Eigenschaften kostengünstiger als End-to-End-Chat-Tests.

class BedrockLLMProvider(LLMProvider):
    def __init__(self, client, model_id: str):
        self.client = client
        self.model_id = model_id
    async def reason(
        self,
        context: AgentContext,
    ) -> AgentDecision:
        response = self.client.converse(
            modelId=self.model_id,
            messages=build_messages(context),
        )
        return map_bedrock_response(response)
Application
     ↓
LLMProvider
     ↑
BedrockLLMProvider

Wo RAG hingehört

Für die Zuordnung von RAG sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Vorzuziehen sind kleine, testbare Einheiten statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Überprüfen Sie nach der ersten Batch-Verarbeitung ein Stichprobenumfeld – Cypher-Proben erkennen Label-Abweichungen und fehlende Eigenschaften kostengünstiger als End-to-End-Chat-Tests.

FastAPI
   ↓
OpenSearch
   ↓
LLM
class OpenSearchPolicyRetriever(PolicyRetriever):
    def __init__(
        self,
        opensearch_client,
        embedding_provider,
    ):
        self.client = opensearch_client
        self.embedding_provider = embedding_provider
    async def retrieve(
        self,
        query: str,
    ) -> list[PolicyDocument]:
        vector = await self.embedding_provider.embed(query)
        results = self.client.search(
            index="supplier-policies",
            body=build_vector_query(vector),
        )
        return map_documents(results)

RAG liefert Kontext – es trifft aber nicht die Entscheidung.

Da RAG Kontext liefert, aber nicht die Entscheidung trifft, sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf den versteckten Zustand schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Überprüfen Sie nach der ersten Batch-Verarbeitung ein Beispiel aus dem Umfeld. Cypher-Proben erkennen Label-Abweichungen und fehlende Eigenschaften kostengünstiger als End-to-End-Chat-Tests. Da RAG Kontext liefert, aber nicht die Entscheidung trifft, sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf den versteckten Zustand schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort für die Operator aufbewahrt werden.

Es ist möglich, eine Prüfung durchzuführen, ohne das gesamte Diagramm lesen zu müssen.

RAG
 ↓
LLM
 ↓
"Looks fine"
 ↓
Create Supplier
RAG
 ↓
Relevant Context
 ↓
Agent Reasoning
 ↓
Application
 ↓
Domain Rules
 ↓
Decision

Wo LangGraph hineinpasst

Zur Bestimmung dessen, wo LangGraph hineinpasst, sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholversuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen. Modellieren Sie Knoten und Beziehungen für die Fragen, die Sie stellen werden, und nicht für jedes Substantiv im Dokument. Spärliche, typisierte Kanten sind besser als dichte, unklare Graphen.

Understand Request
       ↓
Retrieve Policies
       ↓
Evaluate Information
       ↓
Need More Data?
   ↙          ↘
 Yes          No
  ↓            ↓
Ask User   Continue
               ↓
       Approval Required?
          ↙          ↘
        Yes           No
         ↓             ↓
   Human Approval   Continue
          ↘          ↙
        Request Action
graph = StateGraph(AgentState)
graph.add_node(
    "understand_intent",
    understand_intent,
)
graph.add_node(
    "retrieve_policies",
    retrieve_policies,
)
graph.add_node(
    "evaluate",
    evaluate_request,
)
graph.add_node(
    "human_approval",
    request_human_approval,
)
graph.add_node(
    "request_action",
    request_application_action,
)
graph.add_edge(
    "understand_intent",
    "retrieve_policies",
)
graph.add_edge(
    "retrieve_policies",
    "evaluate",
)
graph.add_conditional_edges(
    "evaluate",
    determine_next_step,
    {
        "approval": "human_approval",
        "execute": "request_action",
    },
)

LangGraph sollte nicht zum neuen Monolithen werden

Damit LangGraph nicht zum neuen Monolithen wird, sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Man sollte kleine, testbare Einheiten vor umfangreichen Skripten bevorzugen. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Pipeline-System. Modellieren Sie Knoten und Beziehungen für die Fragen, die Sie stellen möchten, und nicht für jedes Substantiv im Dokument. Spärliche, typisierte Kanten sind besser als dichte, unklare Graphen.

def evaluate_node(state):
    if state.amount > 100_000:
        state.requires_approval = True
    if state.country == "BR":
        ...
    if state.supplier_type == "CRITICAL":
        ...
decision = supplier_policy.evaluate(
    supplier=supplier,
    context=context,
)
LangGraph → orchestrates
Domain → decides

Wo MCP passt

Für die Bestimmung des Einsatzbereichs von MCP sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Modellieren Sie Knoten und Beziehungen für die Fragen, die Sie stellen werden – nicht für jedes Substantiv im Dokument. Spärliche, typisierte Kanten sind besser als dichte, rätselhafte Graphen. Für die Bestimmung des Einsatzbereichs von MCP sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Operator:innen überprüfen können, ohne den gesamten Graphen durchlesen zu müssen.

LLM
 ↓
PostgreSQL
LLM
 ↓
SAP
Agent
  ↓
MCP Tool
  ↓
Application API
  ↓
Use Case
  ↓
Domain
  ↓
Infrastructure
create_supplier
execute_sql

PostgreSQL Ist Auch Ein Adapter

Für „PostgreSQL Ist Auch Ein Adapter“ sollten die Eingaben, der Eigentümer des Schritts sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zustände schließen zu müssen. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholte Versuche, menschliche Überprüfungen und die Handhabung von Fehlnachrichten gehören zum Produkt selbst, nicht zu späteren Optimierungen. Verwenden Sie Einschränkungen und Indizes vor dem Masseneinlesen. Die Eindeutigkeit der Geschäfts Schlüssel sorgt dafür, dass spätere Zusammenführungen zu vorhersehbaren Upserts statt zu Doppelungsproblemen führen.

class SupplierRepository(Protocol):
    async def add(
        self,
        supplier: Supplier,
    ) -> None:
        ...
class PostgresSupplierRepository(
    SupplierRepository
):
    def __init__(self, session):
        self.session = session
    async def add(
        self,
        supplier: Supplier,
    ) -> None:
        entity = SupplierModel.from_domain(
            supplier
        )
        self.session.add(entity)
FastAPI      → doesn't know PostgreSQL exists
Application  → doesn't know PostgreSQL existsDomain       → doesn't know PostgreSQL existsInfrastructure → does

SAP Sollte Hinter Einer Weitere Grenze Liegen

Für SAP sollte eine weitere Grenze vorhanden sein; definieren Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor großen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Verwenden Sie Einschränkungen und Indizes vor der Masseneingabe. Die Eindeutigkeit der Geschäftschlüssel sorgt dafür, dass spätere Zusammenführungen zu vorhersehbaren Upserts statt zu Doppelungsproblemen führen.

CreateSupplierUseCase
        ↓
Persist State
        ↓
SupplierCreated
        ↓
AWS SQS
        ↓
Integration Worker
        ↓
SAP

Die Architektur zusammenstellen

Zur Zusammenstellung der Architektur sollten die Eingaben, der Verantwortliche für den jeweiligen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Verwenden Sie Einschränkungen und Indizes vor der Masseneingabe. Die Eindeutigkeit der Geschäfts Schlüssel sorgt dafür, dass spätere Zusammenführungen zu vorhersehbaren Upserts statt zu Doppelungsproblemen werden. Zur Zusammenstellung der Architektur sollten die Eingaben, der Verantwortliche für den jeweiligen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert werden, den die Operator ohne Probleme überprüfen können.

den gesamten Graphen.

USER
                           │
                           ▼
                       FastAPI
                           │
                           ▼
                       LangGraph
                           │
              ┌────────────┼────────────┐
              │            │            │
              ▼            ▼            ▼
             RAG          LLM          MCP
              │            │            │
              ▼            ▼            │
         OpenSearch     Bedrock         │
                                        ▼
                                  Application
                                        │
                                        ▼
                                     Domain
                                        │
                              ┌─────────┴─────────┐
                              │                   │
                              ▼                   ▼
                         PostgreSQL            AWS SQS
                                                  │
                                                  ▼
                                               Worker
                                                  │
                                                  ▼
                                                 SAP

Zwei Welten

Für „Zwei Welten“ sollten die Eingaben, der Eigentümer des Schritts sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholungsversuche, menschliche Überprüfungen und die Handhabung fehlerhafter Nachrichten gehören zum Produkt selbst, nicht zu späteren Optimierungen. Überprüfen Sie nach der ersten Charge ein Beispiel aus dem Umfeld. Cypher-Proben erkennen Label-Abweichungen und fehlende Eigenschaften kostengünstiger als End-to-End-Chat-Tests.

PROBABILISTICLLM
RAG
Natural Language
Intent Understanding
Agent Reasoning
Tool Selection
DETERMINISTIC
Authorization
Business Rules
Transactions
Persistence
Idempotency
Integration
Auditability

Ein praktischer Test für die Architektur

Zur praktischen Überprüfung der Architektur sollten Eingaben, Verantwortliche für die einzelnen Schritte sowie Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Vorzuziehen sind kleine, testbare Einheiten statt umfangreicher Skripte. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Überprüfen Sie nach der ersten Batch-Verarbeitung ein Beispielgebiet – Cypher-Proben erkennen Abweichungen bei Labels sowie fehlende Eigenschaften kostengünstiger als End-to-End-Chat-Tests.

async def test_supplier_requires_approval():
    repository = FakeSupplierRepository()
    policies = FakePolicyService(
        requires_approval=True
    )
    events = FakeEventPublisher()
    use_case = CreateSupplierUseCase(
        repository=repository,
        policy_service=policies,
        event_publisher=events,
    )
    supplier = await use_case.execute(
        CreateSupplierCommand(
            name="ACME",
            tax_id="123",
            country="BR",
        )
    )
    assert supplier.requires_approval is True

Das Ändern des Modells sollte langweilig sein

Für „Das Ändern des Modells sollte langweilig sein“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Überprüfen Sie nach der ersten Batch-Verarbeitung ein Beispiel aus dem Umfeld. Cypher-Proben erkennen Label-Abweichungen und fehlende Eigenschaften kostengünstiger als End-to-End-Chat-Tests. Für „Das Ändern des Modells sollte langweilig sein“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert werden, den die Operator ohne Leserechte überprüfen können.

den gesamten Graphen.

LLMProvider
             ▲
             │
   ┌─────────┴─────────┐
   │                   │
BedrockProvider   AnotherProvider
FastAPI
Application
Domain
Business Rules

Clean Architecture ist keine Ordnerstruktur

In „Clean Architecture ist keine Ordnerstruktur“ sollten Eingaben, der Verantwortliche für einen Schritt sowie die Abbruchkriterien vor dem Codeändern definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zustände schließen zu müssen. Dokumentieren Sie den erfolgreichen Ablauf sowie den Notfallweg gemeinsam. Wiederholungsversuche, menschliche Kontrollen und die Handhabung von Fehlnachrichten gehören zum Produkt selbst, nicht zu späteren Optimierungen. Modellieren Sie Knoten und Beziehungen für die Fragen, die Sie stellen werden, und nicht für jedes Substantiv im Dokument. Spärliche, typisierte Kanten sind besser als dichte, unklare Graphen.

src/
├── api/
├── application/
├── domain/
├── agents/
├── ports/
└── infrastructure/

KI macht diese Grenzen noch wichtiger

Weil KI diese Grenzen wichtiger macht, sollten Eingaben, der Verantwortliche für einen Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Ziehen Sie kleine, testbare Einheiten vor umfangreichen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Pipeline-System. Modellieren Sie Knoten und Beziehungen für die Fragen, die Sie stellen möchten, und nicht für jedes Substantiv im Dokument. Spärliche, typisierte Verbindungen sind besser als dichte, unklare Graphen.

Die Architektur in einem Satz

Für „Die Architektur in einem Satz“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Modellieren Sie Knoten und Beziehungen für die Fragen, die Sie stellen werden – nicht für jedes Substantiv im Dokument. Spärliche, typisierte Kanten sind besser als dichte, rätselhafte Graphen. Für „Die Architektur in einem Satz“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf verborgene Zustände schließen zu müssen. Bewahren Sie Konfigurationen außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Operator:innen ohne Lesen überprüfen können.

das gesamte Diagramm.

Fazit

Zum Fazit sollten Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definieren. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Dokumentieren Sie den erfolgreichen Ablauf sowie den Notfallweg gemeinsam. Wiederholungsversuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen. Verwenden Sie Einschränkungen und Indizes vor dem Masseneinlesen. Die Eindeutigkeit der Geschäftschlüssel sorgt dafür, dass spätere Zusammenführungen zu vorhersehbaren Aktualisierungen statt zu Doppelungsproblemen führen.

Prompt
  ↓
 LLM
  ↓
 Tool
  ↓
Database

Operative Checkliste