--- id: wiki-2026-0508-e-component-execution-loop title: E-component (Execution Loop) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Execution Loop, E-Loop, Agent Runtime Loop] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [agent, runtime, llm, architecture] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: Python framework: anthropic-sdk --- # E-component (Execution Loop) ## 매 한 줄 > **"매 LLM agent 의 heartbeat"**. 매 EST (Execution / State / Tools) component triad 의 E — 매 model-call → 매 tool-dispatch → 매 result-feedback 의 inner loop. 매 Claude Agent SDK / OpenAI Assistants / LangGraph 매 same primitive. ## 매 핵심 ### 매 mechanism 1. Send messages + tool definitions to LLM. 2. LLM 매 returns text + (optional) tool_use blocks. 3. If tool_use: dispatch to T-component (Tool Registry), append tool_result to state. 4. Loop until 매 stop_reason == "end_turn" or max_iterations. ### 매 components - **E (this)**: orchestrator — message-pump. - **S** (State Store): conversation history, scratch state. - **T** (Tool Registry): handler dispatch, schema validation. ### 매 응용 1. Code agents (Claude Code, Cursor, Devin). 2. Research agents (Perplexity, Deep Research). 3. Workflow automation. ## 💻 패턴 ### Minimal execution loop (Anthropic SDK 2026) ```python from anthropic import Anthropic client = Anthropic() def run(messages, tools, dispatch, max_iters=20): for _ in range(max_iters): resp = client.messages.create( model="claude-opus-4-7", max_tokens=4096, tools=tools, messages=messages, ) messages.append({"role": "assistant", "content": resp.content}) if resp.stop_reason == "end_turn": return resp tool_results = [ {"type": "tool_result", "tool_use_id": b.id, "content": dispatch(b.name, b.input)} for b in resp.content if b.type == "tool_use" ] messages.append({"role": "user", "content": tool_results}) raise RuntimeError("max iterations exceeded") ``` ### Streaming variant ```python with client.messages.stream(model="claude-opus-4-7", messages=messages, tools=tools) as stream: for event in stream: if event.type == "content_block_delta": print(event.delta.text, end="", flush=True) final = stream.get_final_message() ``` ### Tool dispatch (T-component plug-in) ```python TOOLS = { "read_file": lambda input: open(input["path"]).read(), "list_dir": lambda input: os.listdir(input["path"]), } def dispatch(name, input): try: return TOOLS[name](input) except Exception as e: return f"Error: {e}" ``` ### Stop conditions ```python STOP = {"end_turn", "stop_sequence", "max_tokens"} if resp.stop_reason in STOP: break ``` ### Prompt caching the system + tools ```python resp = client.messages.create( model="claude-opus-4-7", system=[{"type": "text", "text": SYSTEM, "cache_control": {"type": "ephemeral"}}], tools=[{**t, "cache_control": {"type": "ephemeral"}} for t in tools], messages=messages, ) ``` ### Budget guard ```python total_tokens = 0 while True: resp = client.messages.create(...) total_tokens += resp.usage.input_tokens + resp.usage.output_tokens if total_tokens > BUDGET: raise BudgetExceeded() ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Single-turn task | Direct API call | | Multi-tool task | E-loop | | Long-running workflow | E-loop + checkpointing (S) | **기본값**: E-loop + prompt caching + budget guard + max-iter clamp. ## 🔗 Graph - 부모: [[Agent-Architecture]] - 변형: [[ReAct]] - 응용: [[LangGraph]] - Adjacent: [[S-component-State-Store]] · [[T-component-Tool-Registry]] ## 🤖 LLM 활용 **언제**: building agent runtime, multi-step tool-use task. **언제 X**: pure single-shot prompt (no tools, no state). ## ❌ 안티패턴 - **No max-iter cap**: 매 infinite-loop 의 risk. - **No budget guard**: 매 unbounded cost. - **Recreating system prompt per turn**: cache miss → 매 5-10x cost. ## 🧪 검증 / 중복 - Verified (Anthropic Messages API docs, Claude Agent SDK). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — E-component FULL with SDK 2026 loop patterns |