Praktische Hinweise: Aufbau eines Zwei-Agenten-Code-Review-Zyklus mit A2A, LangGraph und
Schritt-für-Schritt-Anleitung zu den Praktischen Hinweisen: Aufbau eines Zwei-Agenten-Code-Review-Zyklus mit A2A, LangGraph sowie Verträgen, Überprüfungen und Code-Slots für Teams, die dieses Muster einsetzen.
Quellen: Building a Two-Agent Code Review Loop with A2A, LangGraph, and LM Studio
Die folgenden Notizen skizzieren einen praktischen Ansatz für „Aufbau eines Zwei-Agenten-Code-Review-Zyklus mit A2A, LangGraph und LM Studio“. Der Schwerpunkt liegt auf Verträgen, Überprüfungen sowie Ersatzcode-Platzhaltern statt auf motivierenden Formulierungen. Beim Durchgehen des Überblicks sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikator sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreiber ohne das Lesen des gesamten Graphen überprüfen können.
Was A2A tatsächlich ist (ein Absatz)
Was A2A eigentlich ist (ein Absatz) funktioniert am besten, wenn es als messbare Ebene betrachtet wird. Erfassen Sie einen gelungenen Ablauf, einen Fehlerfall sowie die Notizen zur Rücksetzung, bevor Sie den Umfang erweitern. Dokumentieren Sie gleichzeitig den erfolgreichen Ablauf und den Wiederherstellungsprozess. Versuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Trennen Sie die Strategie zur Aufteilung in Teile von der Strategie zum Abrufen. Ein Änderungsbedarf bei einer dieser Strategien sollte nicht dazu führen, dass die andere neu geschrieben werden muss, wenn sich die Qualitätsmetriken ändern.
Die Bestandteile
Die Komponenten funktionieren am besten, wenn sie als messbare Oberfläche betrachtet werden. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. 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 einen verworrenen Ablauf. Halten Sie den Zustand der Graphen einfach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Störungen beim Wiederaufnehmen nach Unterbrechungen.
a2a-coder-reviewer/
├── shared/
│ ├── config.py # tunables: system prompts, model, temperature, MAX_ROUNDS
│ ├── llm.py # LM Studio ChatOpenAI factory
│ ├── coder_graph.py # LangGraph graph: spec (+ feedback) -> code
│ └── reviewer_graph.py # LangGraph graph: spec + code -> verdict + feedback
├── coder_agent/
│ ├── agent_executor.py # A2A executor wrapping the coder graph
│ └── __main__.py # A2A server, port 9001
├── reviewer_agent/
│ ├── agent_executor.py # A2A executor wrapping the reviewer graph
│ └── __main__.py # A2A server, port 9002
├── orchestrator.py # A2A client driving the back-and-forth
└── requirements.txt
Die Konfigurationsdatei
Die Konfigurationsdatei funktioniert am besten, wenn sie als messbarer Referenzrahmen betrachtet wird. Erfassen Sie ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Halten Sie den Zustand des Graphen einfach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen bei der Fortsetzung der Verarbeitung. Die Konfigurationsdatei funktioniert am besten, wenn sie als messbarer Referenzrahmen betrachtet wird. Erfassen Sie ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort gespeichert werden, den Betreiber ohne Durchsicht des gesamten Graphen prüfen können.
from dataclasses import dataclass
@dataclass(frozen=True)
class AgentConfig:
model: str
temperature: float
system_prompt: str
CODER_CONFIG = AgentConfig(
model="local-model",
temperature=0.2,
system_prompt="""You are a careful Python engineer.
Write a single Python function that satisfies the spec.
If reviewer feedback is provided, revise your previous code to address it.
Return ONLY the code in a single ```python fenced block, no extra commentary.
""",
)
REVIEWER_CONFIG = AgentConfig(
model="local-model",
temperature=0.0,
system_prompt="""You are a strict senior Python code reviewer performing a
rigorous code review. Do not approve code that has any of these problems:
- Missing a docstring explaining parameters, return value, and behavior.
- Missing type hints on parameters and the return type.
- Failing to handle edge cases implied by the spec (empty input, None,
zero, negative numbers, single-element collections, etc.) unless the
spec explicitly says not to.
- Silently swallowing errors or returning a sentinel value (None, "", -1,
an error string) instead of raising, unless the spec asks for that.
- Using a data structure that visibly discards information the spec
requires (e.g. a `set` when order or duplicate counts must be kept).
If you see ANY of the above, or anything else that would fail a real code
review, you MUST respond with VERDICT: CHANGES_REQUESTED and list the
concrete problems as bullet points, even if the code "basically works."
Only respond with VERDICT: APPROVED if the code has none of these
problems. Never approve code and then list problems as "suggestions" or
"nice to haves" — if it's worth mentioning, it's worth requesting changes
for.
Start your reply with exactly one line:
VERDICT: APPROVED
or
VERDICT: CHANGES_REQUESTED
Then, on the following lines, give concise, actionable feedback
(bullet points). If APPROVED, feedback can just be brief praise/notes.
""",
)
# Max coder<->reviewer rounds before orchestrator.py gives up.
MAX_ROUNDS = 3
Die LLM-Fabrik
Für die LLM-Fabrik sollten 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. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholungsversuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen. Wählen Sie bei dem nächsten Schritt, der ein Code oder einen Toolaufruf ist, strukturierte Ausgaben mit Schema-Validierung vor.
import os
from langchain_openai import ChatOpenAI
LM_STUDIO_BASE_URL = os.environ.get(
"LM_STUDIO_BASE_URL", "http://localhost:7777/v1"
)
def get_llm(model: str = "local-model", temperature: float = 0.2) -> ChatOpenAI:
return ChatOpenAI(
base_url=LM_STUDIO_BASE_URL,
api_key="lm-studio", # placeholder, LM Studio ignores it
model=model,
temperature=temperature,
)
Der Coder-Graph
Für das The Coder-Diagramm sollten Eingaben, der Verantwortliche für einen 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 versteckte Zustände schließen zu müssen. Bevorzugen 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 Ablaufverfahren. Setzen Sie menschliche Freigabe für Kanten ein, die Geld ausgeben oder Produktionsdaten ändern. Eine Verkabelung zur Kompilierzeit bedeutet nicht automatisch vollständige Geschäftsabdeckung.
from typing import TypedDict, Optional
from langgraph.graph import StateGraph, END
from shared.config import CODER_CONFIG
from shared.llm import get_llm
class CoderState(TypedDict):
spec: str
previous_code: Optional[str]
feedback: Optional[str]
code: str
def _generate(state: CoderState) -> CoderState:
llm = get_llm(model=CODER_CONFIG.model, temperature=CODER_CONFIG.temperature)
user_msg = f"Spec:\n{state['spec']}\n"
if state.get("previous_code"):
user_msg += f"\nPrevious code:\n{state['previous_code']}\n"
if state.get("feedback"):
user_msg += f"\nReviewer feedback to address:\n{state['feedback']}\n"
response = llm.invoke(
[
{"role": "system", "content": CODER_CONFIG.system_prompt},
{"role": "user", "content": user_msg},
]
)
state["code"] = response.content
return state
def build_coder_graph():
graph = StateGraph(CoderState)
graph.add_node("generate", _generate)
graph.set_entry_point("generate")
graph.add_edge("generate", END)
return graph.compile()
coder_graph = build_coder_graph()
import re
from typing import TypedDict, Optional
from langgraph.graph import StateGraph, END
from shared.config import REVIEWER_CONFIG
from shared.llm import get_llm
class ReviewerState(TypedDict):
spec: str
code: str
verdict: str
feedback: str
def _review(state: ReviewerState) -> ReviewerState:
llm = get_llm(model=REVIEWER_CONFIG.model, temperature=REVIEWER_CONFIG.temperature)
user_msg = f"Spec:\n{state['spec']}\n\nCode to review:\n{state['code']}\n"
response = llm.invoke(
[
{"role": "system", "content": REVIEWER_CONFIG.system_prompt},
{"role": "user", "content": user_msg},
]
)
text = response.content
match = re.search(r"VERDICT:\s*(APPROVED|CHANGES_REQUESTED)", text, re.IGNORECASE)
verdict = match.group(1).upper() if match else "CHANGES_REQUESTED"
feedback = text[match.end():].strip() if match else text.strip()
state["verdict"] = verdict
state["feedback"] = feedback
return state
def build_reviewer_graph():
graph = StateGraph(ReviewerState)
graph.add_node("review", _review)
graph.set_entry_point("review")
graph.add_edge("review", END)
return graph.compile()
reviewer_graph = build_reviewer_graph()
Ein Diagramm als A2A-Executor verpacken
Um einen Graphen als A2A-Executor zu verpacken, 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. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, teilweise abgeschlossene Vorgänge ab. Setzen Sie menschliche Freigabe für Kanten voraus, die Geld ausgeben oder Produktionsdaten ändern. Eine Verkabelung zur Kompilierzeit bedeutet nicht automatisch Geschäftsabschluss. Um einen Graphen als A2A-Executor zu verpacken, 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. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. 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.
aph.from a2a.server.agent_execution.agent_executor import AgentExecutor
from a2a.server.agent_execution.context import RequestContext
from a2a.server.events.event_queue import EventQueue
from a2a.server.tasks.task_updater import TaskUpdater
from a2a.types import Part, Task, TaskState, TaskStatus
from shared.coder_graph import coder_graph
class CoderAgentExecutor(AgentExecutor):
async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
user_message = context.message
task_id = context.task_id
context_id = context.context_id
await event_queue.enqueue_event(
Task(
id=task_id,
context_id=context_id,
status=TaskStatus(state=TaskState.TASK_STATE_SUBMITTED),
history=[user_message] if user_message else [],
)
)
updater = TaskUpdater(
event_queue=event_queue, task_id=task_id, context_id=context_id
)
working_message = updater.new_agent_message(
parts=[Part(text="Generating code...")]
)
await updater.start_work(message=working_message)
query = context.get_user_input()
spec, previous_code, feedback = _parse_input(query)
try:
result = coder_graph.invoke(
{
"spec": spec,
"previous_code": previous_code,
"feedback": feedback,
"code": "",
}
)
except Exception as exc:
error_message = updater.new_agent_message(
parts=[Part(text=f"❌ Code generation failed: {exc}")]
)
await updater.failed(message=error_message)
return
await updater.add_artifact(
parts=[Part(text=result["code"])], name="code", last_chunk=True
)
await updater.complete()
...
Bereitstellung für jeden Agenten
Beim Arbeiten an der Bereitstellung für jeden Agenten sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Notfallweg gemeinsam. Wiederholte Versuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Legen Sie nach teuren Schritten einen Checkpoint an. Das Wiederaufnehmen des Vorgangs sollte keine erneute Abrechnung für denselben LLM-Aufruf veranlassen, wenn ein Operator einen späteren Knoten erneut versucht.
import uvicorn
from starlette.applications import Starlette
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
from a2a.server.tasks.inmemory_task_store import InMemoryTaskStore
from a2a.types import AgentCapabilities, AgentCard, AgentInterface, AgentSkill
from coder_agent.agent_executor import CoderAgentExecutor
HOST = "127.0.0.1"
PORT = 9001
RPC_URL = "/a2a/jsonrpc"
def build_agent_card() -> AgentCard:
skill = AgentSkill(
id="write_code",
name="Write / revise Python code",
description="Writes a Python function from a spec, or revises "
"previous code given reviewer feedback.",
tags=["coding", "python"],
examples=["SPEC: write a function that reverses a linked list"],
input_modes=["text"],
output_modes=["text", "task-status"],
)
return AgentCard(
name="Coder Agent",
description="Generates and revises Python code based on a spec "
"and optional reviewer feedback.",
version="0.1.0",
capabilities=AgentCapabilities(streaming=True, push_notifications=False),
default_input_modes=["text"],
default_output_modes=["text", "task-status"],
skills=[skill],
supported_interfaces=[
AgentInterface(
protocol_binding="JSONRPC",
protocol_version="1.0",
url=f"http://{HOST}:{PORT}{RPC_URL}",
),
],
)
def main():
agent_card = build_agent_card()
request_handler = DefaultRequestHandler(
agent_executor=CoderAgentExecutor(),
task_store=InMemoryTaskStore(),
agent_card=agent_card,
)
routes = []
routes.extend(create_agent_card_routes(agent_card=agent_card))
routes.extend(create_jsonrpc_routes(request_handler=request_handler, rpc_url=RPC_URL))
app = Starlette(routes=routes)
uvicorn.run(app, host=HOST, port=PORT)
if __name__ == "__main__":
main()
Der Orchestrierer
Beim Arbeiten mit The Orchestrator sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Ziehen Sie kleine, testbare Einheiten vor großen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema. Legen Sie nach teuren Schritten Checkpoints an. Das Resume sollte bei einem Neversuch eines Operators für einen späteren Knoten nicht denselben LLM-Aufruf erneut berechnen.
import asyncio
import sys
import uuid
import httpx
from a2a.client import A2ACardResolver, ClientConfig, create_client
from a2a.helpers import get_artifact_text, get_message_text
from a2a.types import Message, Part, Role, SendMessageRequest
from shared.config import MAX_ROUNDS
CODER_URL = "http://127.0.0.1:9001"
REVIEWER_URL = "http://127.0.0.1:9002"
async def get_client_for(httpx_client: httpx.AsyncClient, base_url: str):
resolver = A2ACardResolver(httpx_client, base_url)
card = await resolver.get_agent_card()
return await create_client(card, client_config=ClientConfig(httpx_client=httpx_client))
async def send_and_collect(client, text: str) -> str:
message = Message(
role=Role.ROLE_USER,
message_id=str(uuid.uuid4()),
parts=[Part(text=text)],
context_id=str(uuid.uuid4()),
)
request = SendMessageRequest(message=message)
result_text = ""
async for event in client.send_message(request):
if event.HasField("message"):
result_text = get_message_text(event.message, delimiter="\n")
elif event.HasField("artifact_update"):
result_text += get_artifact_text(
event.artifact_update.artifact, delimiter="\n"
)
elif event.HasField("status_update"):
status = event.status_update.status
if status.state == TaskState.TASK_STATE_FAILED:
error_text = (
get_message_text(status.message, delimiter="\n")
if status.HasField("message")
else "Task failed with no error message."
)
raise RuntimeError(error_text)
return result_text
async def run(spec: str) -> dict:
"""
Runs the coder<->reviewer loop for `spec`. Returns a result dict:
{"approved": bool, "rounds": int, "code": str, "review": str}
or, if a task failed, {"approved": False, "error": str, "code": str | None}.
"""
async with httpx.AsyncClient(timeout=120) as httpx_client:
coder = await get_client_for(httpx_client, CODER_URL)
reviewer = await get_client_for(httpx_client, REVIEWER_URL)
code = None
feedback = None
review_text = ""
try:
for round_num in range(1, MAX_ROUNDS + 1):
print(f"\n=== Round {round_num}: Coder ===")
coder_prompt = f"SPEC: {spec}\n"
if code:
coder_prompt += f"PREVIOUS_CODE: {code}\nFEEDBACK: {feedback}\n"
code = await send_and_collect(coder, coder_prompt)
print(code)
print(f"\n=== Round {round_num}: Reviewer ===")
reviewer_prompt = f"SPEC: {spec}\nCODE: {code}"
review_text = await send_and_collect(reviewer, reviewer_prompt)
print(review_text)
if review_text.startswith("VERDICT: APPROVED"):
print("\n✅ Approved. Final code:\n")
print(code)
return {
"approved": True,
"rounds": round_num,
"code": code,
"review": review_text,
}
feedback = review_text.split("\n", 1)[-1]
print(f"\n⚠️ Max rounds ({MAX_ROUNDS}) reached without approval. Last code:\n")
print(code)
return {
"approved": False,
"rounds": MAX_ROUNDS,
"code": code,
"review": review_text,
}
except RuntimeError as exc:
print(f"\n{exc}")
return {"approved": False, "error": str(exc), "code": code}
finally:
await coder.close()
await reviewer.close()
Ausführen
Beim Arbeiten an „Running it“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgszeichen sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgsprüfungen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab. Legen Sie nach aufwändigen Schritten einen Checkpoint an. Die Wiederaufnahme sollte keine doppelte Abrechnung für denselben LLM-Aufruf vornehmen, wenn ein Operator einen späteren Knoten erneut ausführt. Beim Arbeiten an „Running it“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgszeichen sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert werden, den Operator ohne das Lesen des gesamten Graphen überprüfen können.
pip install -r requirements.txt
# terminal 1
python -m coder_agent
# terminal 2
python -m reviewer_agent
# terminal 3
python orchestrator.py "write a function that checks if a string is a palindrome"
curl http://127.0.0.1:9001/.well-known/agent-card.json
Ein Beispiel für einen tatsächlichen Ausführungsablauf
Ein Beispiel für einen tatsächlichen Ablauf funktioniert am besten, wenn es als messbare Struktur betrachtet wird. Erfassen Sie einen erfolgreichen Ablauf, einen Fehlerfall sowie die Notizen zur Rücksetzung, bevor Sie den Umfang erweitern. Dokumentieren Sie gemeinsam den erfolgreichen Ablaufpfad und den Wiederherstellungsablauf. Wiederholversuche, menschliche Kontrollen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Halten Sie den Zustand der Graphen strukturiert und typisiert – verschachtelte Datenstrukturen verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen des Ablaufs.
Dinge, die kaputtgegangen sind, und wie man sie wieder in Ordnung bringt
Dinge, die kaputtgegangen sind, und wie man sie wieder repariert, funktionieren am besten, wenn sie als messbare Struktur betrachtet werden. Erfassen Sie eine „goldene Transkription“, einen Fehlerfall sowie die Notizen zur Rücksetzung, bevor Sie den Umfang erweitern. Ziehen Sie kleine, testbare Einheiten vor umfangreichen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren. Halten Sie den Zustand der Graphen einfach und typisiert – verschachtelte Datenstrukturen verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Störungen beim Wiederaufnehmen nach Unterbrechungen.
ModuleNotFoundError: No module named 'a2a.server.apps'
ModuleNotFoundError: No module named 'a2a.server.apps' lässt sich am besten als messbare Größe betrachten. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung.
Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.
Halten Sie den Zustand des Graphen flach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen bei der Fortsetzung.
ModuleNotFoundError: No module named 'a2a.server.apps' lässt sich am besten als messbare Größe betrachten. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung.
Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert sein, den Betreuer ohne Durchsicht des gesamten Graphen prüfen können.
ModuleNotFoundError: No module named 'sse_starlette'
Für den Fehler ModuleNotFoundError: No module named 'sse_starlette' 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 versteckten Zuständen schließen zu müssen.
Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Notfallweg gemeinsam. Wiederholungsversuche, menschliche Überprüfungen sowie die Handhabung von Fehlnachrichten gehören zum Produkt selbst und nicht zu späteren Optimierungen.
Setzen Sie menschliche Freigabe für Schritte voraus, die Geld ausgeben oder Produktionsdaten ändern. Eine Verkabelung zur Kompilierzeit bedeutet noch nicht vollständige Funktionalität für das Geschäft.
Rätselhafte Zeitüberschreitungen von etwa 5 Sekunden
Für rätselhafte Zeitüberschreitungen von etwa 5 Sekunden sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden, 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 versteckte Zustände schließen zu müssen. Bevorzugen 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 Ablaufverfahren. Setzen Sie menschliche Freigabe bei Vorgängen ein, die Geld kosten oder Produktionsdaten ändern. Kompilierzeitbezogene Verbindungen bedeuten noch nicht vollständige Geschäftsabläufe.
Reasoning models eat the round
Für Reasoning-Modelle 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 versteckte 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. Wählen Sie bei dem nächsten Schritt Code oder einen Toolaufruf strukturierte Ausgaben mit Schema-Validierung statt freier Prosa vor. Für Reasoning-Modelle 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 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 Operator:innen überprüfen können, ohne den gesamten Ablauf durchzulesen.
Protobuf-Enum-Namen
Beim Arbeiten mit Protobuf-Enum-Namen sollte man zunächst den Vertrag festhalten: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Wiederherstellungsprozess gemeinsam. Wiederholte Versuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Legen Sie nach aufwändigen Schritten einen Checkpoint an. Das Resume sollte bei erneuten Versuchen eines Operators keine doppelten Abrechnungen für denselben LLM-Aufruf vornehmen.
Part umschließt nicht mehr TextPart
Wenn Sie mit Part arbeiten, der nicht mehr TextPart umschließt, notieren Sie zunächst den Vertrag: erforderliche Eingaben, Erfolgsignal sowie was bei einem teilweisen Versagen geschieht. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben.
Ziehen Sie kleine, testbare Einheiten vor großen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema.
Erstellen Sie Zwischenkontrollpunkte nach aufwändigen Schritten. Das Wiederaufnehmen des Vorgangs sollte keine erneute Abrechnung für denselben LLM-Aufruf verursachen, wenn ein Operator einen späteren Knoten erneut ausführt.
Möglichkeiten zur Erweiterung
Wenn Sie Room zur Erweiterung nutzen, schreiben Sie zunächst den Vertrag auf: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgsprüfungen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab. Legen Sie nach aufwändigen Schritten einen Checkpoint an. Die Wiederaufnahme sollte keine doppelte Abrechnung für denselben LLM-Aufruf vornehmen, wenn ein Operator einen späteren Knoten erneut versucht. Wenn Sie Room zur Erweiterung nutzen, schreiben Sie zunächst den Vertrag auf: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert sein, den Operator ohne das Lesen des gesamten Graphen überprüfen können.
Referenzen
References funktioniert am besten, wenn es als messbare Struktur behandelt wird. Erfassen Sie einen erfolgreichen Fall, einen Fehlerfall sowie die Notizen zum Rollback, bevor Sie den Umfang erweitern. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Wiederherstellungsprozess gemeinsam. Wiederholversuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Halten Sie den Zustand der Graphen strukturiert und typisiert – verschachtelte Datenstrukturen verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Problemen bei Unterbrechungen.
Operative Checkliste
Für die operative Checkliste sollten vor dem Ändern des Codes Eingabedaten, Verantwortliche für die einzelnen Schritte sowie Abbruchkriterien 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.
Erhalten Sie neben den funktionalen Ergebnissen auch Aufzeichnungen zu Laufzeiten sowie Kosten für Token oder Abfragen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Ablauf von Demonstrationsumgebungen in gemeinsam genutzte Umgebungen wechselt.
Setzen Sie menschliche Freigabe für那些, die Geld ausgeben oder Produktionsdaten ändern. Kompilierzeitbasierte Verbindungen bedeuten noch nicht vollständige Geschäftsabdeckung.
Schreiben Sie ein kurzes Handbuch: Wie man Schlüssel rotiert, wie man die Warteschlange leert und wie man den letzten Eingriff rückgängig macht.
Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimnisdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Betreuer ohne Lesen des gesamten Systems überprüfen können.
Setzen Sie menschliche Freigabe für那些, die Geld ausgeben oder Produktionsdaten ändern. Kompilierzeitbasierte Verbindungen bedeuten noch nicht vollständige Geschäftsabdeckung.
Vor der Einführung des Stack sollten Versionen eingefroren werden, ein „goldener Transkript“ für den kritischen Weg erstellt und die Schritte zum Rückschritt bestätigt werden. Gemeinsame Umgebungen benötigen Geschwindigkeitsbeschränkungen, Überprüfungen der Zuordnung sowie einen klaren Verantwortlichen für die Rotation von Geheimnissen. Wählen Sie langweilige Zuverlässigkeit statt cleverer, einmaliger Demonstrationen.
Batch-Hinweis für 684455491963: Halten Sie die Anbieter-Schlüssel außerhalb des Repositories, legen Sie eine Obergrenze für Tokens pro Sitzung fest und speichern Sie die Transkripte neben den Evaluierungs-Dateien, damit spätere Modellwechsel vergleichbar bleiben.
Beim Arbeiten an der Sicherheitshinweisnummer 0 sollten Sie zunächst den Ablauf beschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Betreiber ohne das Durchlesen des gesamten Systems überprüfen können.
Sicherheitshinweis Detail 0/640: Messen Sie für diesen Hinweis die Ausführungsdauer, die Fehlerklasse sowie den Tokenverbrauch und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragekatalogs statt aufgrund von Einzelfällen, ob die Änderung beibehalten werden soll.
Hinweis zur Verstärkung 1 funktioniert am besten, wenn er als messbare Oberfläche betrachtet wird. Erfassen Sie vor Erweiterung des Umfangs ein „goldenes“ Transkript, einen Fehlerfall sowie die Notiz zur Rücksetzung. Ziehen Sie kleine, testbare Einheiten vor umfangreichen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablaufprozess.
Detail zur Verstärkung 1/640: Messen Sie für diesen Hinweis die Ausführungszeit, die Fehlerklasse sowie den Tokenverbrauch und entscheiden Sie anschließend auf der Grundlage eines festgelegten Fragebogens statt von Anekdoten, ob die Änderung beibehalten werden soll.
Für Hinweis zur Verstärkung 2 sollten Sie vor dem Ändern des Codes die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien 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. Erhalten Sie neben den funktionalen Ergebnissen auch Aufzeichnungen über Zeiten sowie Kosten für Tokens oder Abfragen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt.
Verstärkungsmaßnahme Detail 2/640: Messen Sie die Wall-Time, die Fehlerklasse sowie den Tokenverbrauch für diese Notiz und entscheiden Sie anschließend, ob die Änderung auf der Grundlage eines festgelegten Fragekatalogs statt aufgrund von Einzelfällen beibehalten werden soll.