Home > EulerAgent > Tutorials > Graph > Graph 10. Complete Reference — Fields, Error Codes, Safe...

Graph 10. Complete Reference — Fields, Error Codes, Safe Design Checklist

This document is the complete reference for the euleragent graph module. Use it as a quick-reference guide for all concepts covered in the tutorials.


1. Graph YAML Complete Field Table

1.1 Top-Level Fields

Field Type Required Description
id string Y Graph identifier. Convention: graph.{name}
version integer Y Graph version number (starting from 1)
category string Y Category (research, engineering, marketing, etc.)
description string Y Graph description
checkpointer boolean/string Conditional Required when using interrupt_before/interrupt_after. One of true, "memory", "sqlite"
state_schema dict Conditional Required when using parallel_groups
parallel_groups list N List of parallel Fan-out/Fan-in groups
defaults dict Y Execution constraints (includes max_iterations)
nodes list Y List of nodes
edges list Y List of edges
finalize dict Y Final node configuration

1.2 state_schema Fields

state_schema:
  <key_name>:
    type: string | integer | float | list | dict
    merge: append_list | sum_int | concat_str | last_write | first_write
Field Type Required Description
type enum Y Data type of the state value
merge enum Y Conflict resolution strategy (Reducer) for parallel writes

1.3 parallel_groups Fields

parallel_groups:
  - id: <group_id>
    branches: [<node_id>, ...]
    join: <join_node_id>
Field Type Required Description
id string Y Group identifier
branches list[string] Y List of node IDs to execute in parallel (2 to 8)
join string Y Fan-in join node ID

1.4 defaults Fields

Field Type Required Description
max_iterations integer Required for loops Maximum execution count for the loop reference node
max_total_tool_calls integer N Total tool call budget
max_web_search_calls integer N Web search call budget

1.5 nodes Fields (Graph-Specific Additional Fields)

Graph-specific fields added on top of all Pattern node fields:

Field Type Required Description
id string Y Node identifier (unique within the graph)
kind enum Y llm, judge, finalize
runner dict When kind=llm Execution mode configuration
runner.mode enum Y plan, execute
runner.force_tool string N Forced tool (web.search, file.write, shell.exec)
runner.exclude_tools list N List of tools to exclude
runner.min_proposals integer N Minimum number of proposals in plan mode
runner.max_loops integer N Maximum internal retry count within a node
judge dict When kind=judge Judge configuration
judge.schema string Y Evaluation schema ID
judge.route_values list Y List of possible routing values
artifacts dict N Artifact configuration
artifacts.primary string N Primary artifact filename
guardrails dict N Tool usage constraints
guardrails.tool_call_budget dict N Per-tool call count limits
writes_state list Required for branches List of state_schema keys this node writes to. All keys must be declared in state_schema (raises STATE_UPDATE_OUTSIDE_DECLARED_WRITES if undeclared)
reads_state list N List of state_schema keys this node reads. Undeclared keys produce a READS_STATE_UNKNOWN_KEY warning
interrupt_before boolean N LangGraph Checkpoint pause before execution. Top-level checkpointer: required
interrupt_after boolean N LangGraph Checkpoint pause after execution. Top-level checkpointer: required

1.6 edges Fields

Field Type Required Description
from string Y Source node ID
to string Y Target node ID (including finalize)
when string Y Condition expression

when condition expressions: - "true" -- always proceed - "approvals_resolved" -- after the HITL approval queue is cleared - "judge.route == <value>" -- when the judge returns a specific value

1.7 finalize Fields

Field Type Required Description
artifact string Y Final artifact filename

2. Pattern vs Graph Comparison Table

Aspect Pattern Graph
YAML structure Identical Superset of Pattern
Execution engine euleragent sequential executor LangGraph StateGraph
state_schema None Added (required for parallel)
parallel_groups None Added (Fan-out/Fan-in)
interrupt_before/after None Added (Checkpoint-based)
Judge routing Runtime condition evaluation add_conditional_edges compilation
writes_state / reads_state None Added (parallel branch documentation)
graph_type (IR) "pattern" "graph"
CLI commands pattern validate/show graph validate/show/compile
Stability Stable Experimental
Parallel execution Not available Available
Intermediate state persistence Not available LangGraph Checkpointer

3. Complete Error/Warning Code Table

3.1 Semantic Error Codes (New)

# Error Code Trigger Condition Resolution
L INTERRUPT_REQUIRES_CHECKPOINTER Using interrupt_before/after without top-level checkpointer: Add checkpointer: memory
M STATE_UPDATE_OUTSIDE_DECLARED_WRITES Node's writes_state key is not in state_schema Add the key to state_schema or remove from writes_state
P3b PARALLEL_JOIN_IN_BRANCHES join node is included in its own branches list Remove the join node from branches

3.2 Warning Codes (ok=True, Non-Blocking)

# Warning Code Trigger Condition Recommended Action
N READS_STATE_UNKNOWN_KEY reads_state key is not in state_schema Check for typos or add to state_schema
P14 PARALLEL_ORDER_DEPENDENT_MERGE Using append_list in a parallel group Add source/rank fields to items and sort in the join

3.3 Parallel Error Codes (14 Total)

# Error Code Trigger Condition Resolution
1 PARALLEL_JOIN_MISSING parallel_groups has no join Add join: <node_id>
2 PARALLEL_JOIN_MULTIPLE A single group has 2 join entries Reduce to a single join
3 PARALLEL_FANOUT_MISSING No Fan-out edge leading to a branch Add source -> branch edge
4 PARALLEL_JOIN_EDGE_MISSING No branch -> join edge Add branch -> join edge
5 PARALLEL_BRANCH_NOT_CONVERGING Branch does not converge to the join node Fix the Fan-in edges
6 PARALLEL_STATE_SCHEMA_MISSING parallel_groups exists but state_schema is missing Add state_schema at the top level
7 PARALLEL_STATE_KEY_MERGE_MISSING State key written by a branch has no merge strategy Add merge for the key in state_schema
8 PARALLEL_NONDETERMINISTIC_MERGE Multiple branches share a last_write or first_write key Change to append_list, sum_int, or concat_str
9 STATE_SCHEMA_MERGE_TYPE_MISMATCH Forbidden type+merge combination used Refer to the compatibility table and fix
10 PARALLEL_SIDE_EFFECT_FORBIDDEN shell.exec/file.write as force_tool in a branch Perform in a node after the join
11 PARALLEL_BRANCH_LIMIT_EXCEEDED 9 or more branches Reduce to 8 or fewer
12 PARALLEL_METADATA_DROPPED Branch node has no writes_state Explicitly add writes_state: []
13 PARALLEL_FINALIZE_BEFORE_JOIN Branch routes directly to finalize Change to route through join node -> finalize
14 LANGGRAPH_COMPILE_FAILED LangGraph version mismatch or IR error Install LangGraph 1.0.9+, run euleragent doctor

4. Type+Merge Compatibility Matrix

Cell symbols: O = Allowed, X = Forbidden (STATE_SCHEMA_MERGE_TYPE_MISMATCH), O = Recommended

Type \ Merge append_list sum_int concat_str last_write first_write
list O X X O O
string X X O O O
integer X O X O O
float X X X O O
dict X X X O O

Bold: Recommended merge strategy for the given type

4.1 Recommended Combination Summary

# 병렬 결과 수집 (리스트) → append_list
findings:
  type: list
  merge: append_list

# 숫자 합산 → sum_int
count:
  type: integer
  merge: sum_int

# 텍스트 연결 (병렬) → concat_str
notes:
  type: string
  merge: concat_str

# 단일 노드 쓰기 → last_write
summary:
  type: string  # 또는 float, dict
  merge: last_write

# 최초 쓰기 우선 → first_write
initial_value:
  type: string  # 또는 다른 타입
  merge: first_write

5. Safe Parallel Design Checklist (16 Items)

Design Phase

□ 1. 진정한 병렬 실행이 필요한지 확인
      순차로 충분하면 Pattern 사용 (더 단순하고 안정적)

□ 2. 브랜치 수 결정 (2~8개)
      처음에는 2~3개로 시작하고 필요 시 확장

□ 3. state_schema 설계 완료
      모든 브랜치의 writes_state 키 목록화
      각 키의 type과 merge 전략 결정

□ 4. 공유 키(여러 브랜치가 씀) 식별
      공유 list 키 → append_list
      공유 integer 키 → sum_int
      공유 string 키 → concat_str 또는 last_write(비결정론적 허용 시)

□ 5. 단일 브랜치 키 식별
      단일 브랜치 키 → last_write (안전)

Declaration Phase

□ 6. state_schema 최상위에 선언

□ 7. parallel_groups 선언 (id, branches, join)

□ 8. 모든 브랜치 노드에 writes_state 선언
      상태를 쓰지 않아도 writes_state: [] 명시

□ 9. 조인 노드에 reads_state 선언 (문서화)

□ 10. 팬아웃 엣지 선언 (소스 → 모든 브랜치)

□ 11. 팬인 엣지 선언 (모든 브랜치 → 조인 노드)
       HITL 브랜치는 when: "approvals_resolved"
       자율 브랜치는 when: "true"

□ 12. interrupt_before/after 사용 시 최상위 checkpointer: 선언
       미선언 시 INTERRUPT_REQUIRES_CHECKPOINTER 에러 (정적 검증 실패)
       최소: checkpointer: memory

Validation Phase

□ 13. euleragent graph validate 실행 및 통과 확인

□ 14. PARALLEL_NONDETERMINISTIC_MERGE / PARALLEL_ORDER_DEPENDENT_MERGE 경고 검토
       비결정론적 결과 허용 여부 확인; append_list 시 source/rank 필드 고려

□ 15. euleragent graph compile로 IR 생성 및 검토
       langgraph_builder 섹션에서 add_edges 확인

□ 16. 실험적 기능 사용 주의사항 재확인
       00_disclaimer.md 참조

6. LangGraph StateGraph Compilation Details

This shows how each element of the Graph YAML maps to LangGraph methods.

6.1 Mapping Table

Graph YAML Element LangGraph API
state_schema (entire) StateGraph(TypedDict) type definition
state_schema.*.merge: append_list Annotated[list, operator.add]
state_schema.*.merge: sum_int Annotated[int, operator.add]
state_schema.*.merge: concat_str Annotated[str, operator.add]
state_schema.*.merge: last_write Default type (no annotation)
state_schema.*.merge: first_write Custom first_write Reducer
nodes[*] graph.add_node(id, fn)
First node graph.set_entry_point(id)
finalize node graph.set_finish_point(id)
edges[*] (when="true") graph.add_edge(from, to)
edges[*] (when="judge.route==X") graph.add_conditional_edges(...)
parallel_groups[*] Fan-out/Fan-in edges (multiple add_edge)
interrupt_before: [...] graph.compile(interrupt_before=[...])
interrupt_after: [...] graph.compile(interrupt_after=[...])
defaults.max_iterations Runtime guard (outside LangGraph)

6.2 Full Compilation Example (Conceptual Python Code)

The following shows how parallel_research_with_quality.yaml is transformed into LangGraph code.

from langgraph.graph import StateGraph, END
from typing import Annotated, TypedDict
import operator

# state_schema → TypedDict
class GraphState(TypedDict):
    findings: Annotated[list, operator.add]   # append_list
    source_count: Annotated[int, operator.add]  # sum_int
    final_summary: str                         # last_write (기본)
    route: str                                 # judge 라우팅용 내부 키

# StateGraph 초기화
graph = StateGraph(GraphState)

# 노드 추가
graph.add_node("plan", plan_fn)
graph.add_node("web_search", web_search_fn)
graph.add_node("local_search", local_search_fn)
graph.add_node("doc_search", doc_search_fn)
graph.add_node("merge_findings", merge_findings_fn)
graph.add_node("evaluate", evaluate_fn)
graph.add_node("revise", revise_fn)

# 진입점
graph.set_entry_point("plan")

# 팬아웃 엣지 (plan → 브랜치들)
graph.add_edge("plan", "web_search")
graph.add_edge("plan", "local_search")
graph.add_edge("plan", "doc_search")

# 팬인 엣지 (브랜치들 → 조인)
graph.add_edge("web_search", "merge_findings")
graph.add_edge("local_search", "merge_findings")
graph.add_edge("doc_search", "merge_findings")

# 하류 엣지
graph.add_edge("merge_findings", "evaluate")
graph.add_edge("revise", "evaluate")

# Judge 조건부 엣지
def route_evaluate(state: GraphState) -> str:
    return state.get("route", "finalize")

graph.add_conditional_edges(
    "evaluate",
    route_evaluate,
    {"finalize": END, "revise": "revise"}
)

# 컴파일 (interrupt 없는 경우)
compiled = graph.compile()

# 또는 interrupt 있는 경우
compiled = graph.compile(
    checkpointer=checkpointer,
    interrupt_before=["publish"],   # interrupt_before 노드 목록
    interrupt_after=["draft"]       # interrupt_after 노드 목록
)

6.3 first_write Reducer Implementation (Conceptual)

first_write is not a built-in LangGraph annotation, so it is implemented as a custom Reducer.

def first_write_reducer(old_value, new_value):
    """첫 번째 쓰기 값을 유지. None이면 new_value 사용."""
    if old_value is None:
        return new_value
    return old_value  # 이미 값이 있으면 새 값 무시

# TypedDict에서의 선언
class GraphState(TypedDict):
    primary_result: Annotated[str, first_write_reducer]

7. Experimental Feature Usage Precautions Summary

Refer to 00_disclaimer.md for the full disclaimer.

7.1 Safety Level Classification

Feature Safety Level Description
Linear Graph (no parallel) Stable Equivalent to Pattern
Judge routing Stable Equivalent behavior to Pattern
interrupt_before/after Experimental Depends on LangGraph version
2-branch parallel_groups Experimental Basic validation complete
3-8 branch parallel_groups Experimental Thorough testing required
graph run command Experimental Some scenarios unverified

7.2 Required Steps After Version Upgrades

# euleragent 또는 langgraph 업그레이드 후
pip install --upgrade euleragent langgraph

# 모든 Graph YAML 재검증
for yaml_file in examples/graphs/**/*.yaml; do
    echo "검증: $yaml_file"
    euleragent graph validate "$yaml_file"
done

# 컴파일된 IR 재생성
euleragent graph compile my_graph.yaml --out my_graph_compiled.json

7.3 Pre-Production Deployment Checklist

□ euleragent doctor 실행 → 모든 항목 통과 확인
□ graph validate 통과 (오류 0개)
□ graph validate --format json 출력에서 경고 검토
□ graph compile 성공
□ 스테이징 환경에서 10회 이상 반복 실행 테스트
□ 병렬 결과의 비결정론적 변동 허용 범위 확인
□ HITL 승인 워크플로우 테스트
□ interrupt hooks 재개 시나리오 테스트
□ 감사 로그 (approvals.jsonl, tool_calls.jsonl) 검토
□ 최대 비용 시나리오 계산 (max_iterations × max_total_tool_calls)

Quick Reference Card

CLI Commands

euleragent graph list                              # 그래프 목록
euleragent graph show <path>                       # 구조 보기
euleragent graph validate <path>                   # 검증
euleragent graph validate <path> --format json     # JSON 형식 검증
euleragent graph compile <path>                    # IR 컴파일
euleragent graph compile <path> --out file.json    # IR 파일로 저장

Minimal Parallel Graph Template

id: graph.template
version: 1
category: demo
description: 최소 병렬 그래프 템플릿

state_schema:
  results:
    type: list
    merge: append_list

defaults:
  max_iterations: 2
  max_total_tool_calls: 30

parallel_groups:
  - id: my_group
    branches: [branch_a, branch_b]
    join: join_node

nodes:
  - id: source
    kind: llm
    runner: {mode: execute}

  - id: branch_a
    kind: llm
    runner: {mode: execute}
    writes_state: [results]

  - id: branch_b
    kind: llm
    runner: {mode: execute}
    writes_state: [results]

  - id: join_node
    kind: llm
    runner: {mode: execute}
    reads_state: [results]
    artifacts:
      primary: output.md

edges:
  - {from: source, to: branch_a, when: "true"}
  - {from: source, to: branch_b, when: "true"}
  - {from: branch_a, to: join_node, when: "true"}
  - {from: branch_b, to: join_node, when: "true"}
  - {from: join_node, to: finalize, when: "true"}

finalize:
  artifact: output.md

Previous: 09_parallel_with_quality.md | Table of Contents: README.md

← Prev Back to List