Agentic Loops
When to Use
The Core Pattern
from hypergraph import Graph, node, route, END, SyncRunner
@node(output_name="draft")
def generate(prompt: str, feedback: str = "") -> str:
"""Generate content, incorporating any feedback."""
full_prompt = f"{prompt}\n\nFeedback to address: {feedback}" if feedback else prompt
return llm.generate(full_prompt)
@node(output_name="score")
def evaluate(draft: str) -> float:
"""Score the draft quality (0-1)."""
return quality_model.score(draft)
@node(output_name="feedback")
def critique(draft: str, score: float) -> str:
"""Generate feedback for improvement."""
if score >= 0.8:
return "" # Good enough
return critic_model.generate(f"Critique this draft:\n{draft}")
@route(targets=["generate", END])
def should_continue(score: float, attempts: int) -> str:
"""Decide whether to continue refining."""
if score >= 0.8:
return END # Quality achieved
if attempts >= 5:
return END # Max attempts reached
return "generate" # Keep refining
@node(output_name="attempts")
def count_attempts(attempts: int = 0) -> int:
"""Track iteration count."""
return attempts + 1
# Build the loop
refinement_loop = Graph([
generate,
evaluate,
critique,
count_attempts,
should_continue,
])
# Run until done
runner = SyncRunner()
result = runner.run(refinement_loop, {"prompt": "Write a haiku about Python"})
print(f"Final draft: {result['draft']}")
print(f"Final score: {result['score']}")
print(f"Attempts: {result['attempts']}")How It Works
The END Sentinel
Multi-Turn Conversation
Shared State for Chat Loops
Tool-Using Agent
Quality Gate Pattern
Ordering with emit/wait_for
Entry Points
Tracking State Across Iterations
Shared Outputs in a Cycle
With emit/wait_for
With Explicit Edges
Situation
Use
Preventing Infinite Loops
What's Next?
Last updated