콘텐츠로 이동

오케스트레이터 설정·API

이 페이지는 구현 중 필드와 API를 다시 찾는 빠른 참조입니다. 처음 구성한다면 오케스트레이터 시작하기, 실행 방식은 Agentic 또는 Deterministic 가이드부터 보세요.

build_orchestrator_app()의 최종 completed 응답에도 Agent·Flow와 같은 evaluator를 연결할 수 있습니다.

from llamon_agent.orchestrator.server import build_orchestrator_app
app = await build_orchestrator_app(
card=card,
run_turn=run_turn,
evaluators=[groundedness],
evaluator_timeout_seconds=120.0,
)
인자기본값계약
evaluatorsNoneorchestrator 최종 출력에 적용할 순서 있는 evaluator 목록
evaluator_timeout_seconds90.0evaluator별 제한 시간. None이면 제한 없음

input_required·실패 결과는 평가하지 않고 evaluator 오류는 기록한 뒤 원래 응답을 유지합니다. 종료된 child 자체를 평가하는 call_observed() 경로와 최종 응답 평가는 대상과 topology가 다릅니다. 자세한 규칙은 Runtime Evaluator Framework를 참고하세요.

SDK 소유 namespace는 알 수 없는 키와 잘못된 타입을 기동 단계에서 거부합니다. 애플리케이션 값은 [app.<namespace>]에 두고 composition root에서 직접 검증하세요.

[orchestrator]
id = "support-desk"
state_backend = "postgres"
[limits]
max_state_bytes = 524288
max_messages = 50
[agents]
search = "registry:support-search"
[agentic.support]
model = "59"
prompt = "support-supervisor"
max_controller_steps = 4
max_tool_calls = 3
context_turns = 10
context_roles = ["user", "assistant"]
work_memory_context = "relevant"
work_memory_context_max_items = 10
work_memory_context_max_bytes = 16384
public_emissions = true
[agentic.support.human_review]
# HumanReviewPort를 연결하기 전에는 대기를 만들지 않습니다.
mode = "disabled"
required_tools = []
[agentic.support.tools.search]
safety = "read_only"
input = "conversation"
response_data_schema = "support.search.result.v1"
table역할
[orchestrator]논리 ID와 in_memory·postgres state backend
[limits]max_state_bytes, max_messages
[agents]workflow에서 사용할 child alias와 target
[agentic.<name>]bounded controller model·prompt·상한·context
[verification.<workflow>]opt-in 결과 평가와 제한적 수정
`[guardrails.inputoutput]`
[work_memory]작업 결과의 bounded summary·facts 보관
[app.<namespace>]SDK가 해석하지 않는 앱 설정

[orchestrator].id는 프로젝트의 논리 ID이고, [orchestrator].state_backendin_memory 또는 postgres입니다. 개발은 in_memory, 재시작·multi-worker 운영은 postgres를 사용합니다.

PostgreSQL DSN은 TOML이 아니라 POSTGRES_ORCH_DSN을 사용하며, 없으면 POSTGRES_MEMORY_DSN을 읽습니다. [execution.*][finalization.*]은 지원하지 않습니다.

[agents] alias는 Python identifier 형식입니다. target은 registry:<id>, Registry ID, http(s):// URL 또는 로컬 포트입니다. child를 연결했다고 controller tool이 되는 것은 아니며 [agentic.<name>.tools.<alias>]에서 따로 허용합니다.

허용값·기본값
max_controller_steps1..4, 기본 4
max_tool_calls1..3, 기본 3
structured_output_retries0..1, 기본 1
public_emissionsboolean, 기본 false. controller가 선언한 공개 emission만 전달
context_turns0..50, 기본 10
context_rolesuser 필수, assistant 선택
work_memory_contextnone·relevant·latest·all
work_memory_context_max_items1..100, 기본 10
work_memory_context_max_bytes12..65536, 기본 16384
tools.<alias>.safetyread_only·side_effecting
tools.<alias>.inputrequest·context·conversation, 기본 context; conversationread_only 전용
request_data_schema·response_data_schemaschema가 없을 때만 붙이는 fallback

side_effecting tool은 durable input snapshot과 사용자 승인 없이 실행되지 않습니다. 최종 담당자 검수는 별도 경계입니다. [agentic.<name>.human_review].modedisabled·controller·always이고, required_tools로 고정 child 결과에도 검수를 요구할 수 있습니다.

input = "request"는 현재 턴의 입력 snapshot을 그대로 전달하고, 기본 context는 현재 요청 text에 승인된 attachment DataPart·파일 참조·WorkMemory projection을 더합니다. conversationcontext와 같은 범위를 유지하면서 controller가 최근 bounded 대화의 지시 대상을 해소한 최대 4,000자의 독립 child text를 전달합니다. 직전 assistant 답변의 문서명·페이지가 필요하면 program의 context_rolesassistant를 포함하세요. conversation은 read-only 도구에만 허용되며 TextPart 외 data·files·target 같은 일반 도구 인자는 controller가 바꿀 수 없습니다.

가드레일 전체 필드는 최종 응답과 안전 경계, 검증 설정은 결과 검증 루프, 기억 설정은 상태·기억·재개를 참고하세요.

child 결과를 바로 완료할지 controller가 합성할지는 호출 위치에 따라 다르게 선언합니다.

위치정책용도
controller toolcompletion + completion_when단일 성공 조건으로 text 통과
controller toolresult_transitions여러 구조화 상태를 complete·continue로 분기
OKF then.callresult_gate + on_exhausted고정 첫 호출을 완료·합성·재시도·고정 응답으로 제한
[agentic.support.tools.search]
safety = "read_only"
response_data_schema = "support.search.result.v1"
[[agentic.support.tools.search.result_transitions]]
id = "answer_ready"
when = [
{ path = "status", op = "eq", value = "success" },
{ path = "answer", op = "non_empty" },
]
when_mode = "all"
action = "complete"
[[agentic.support.tools.search.result_transitions]]
id = "needs_reasoning"
when = [{ path = "status", op = "eq", value = "partial" }]
action = "continue"

핵심 제약은 다음과 같습니다.

  • 순서대로 평가하고 첫 일치만 적용합니다.
  • child가 직접 반환한 response_data_schema만 자동 완료의 근거입니다. 부모의 fallback schema는 증거가 아닙니다.
  • complete에는 사용자에게 보낼 non-empty TextPart가 필요합니다.
  • result_transitionscompletion·completion_when과 함께 쓸 수 없고 side_effecting tool에는 허용되지 않습니다.
  • 중단 뒤 재개할 때 정책 digest가 바뀌면 저장된 child 결과는 재사용하되 새 정책으로 자동 완료하지 않습니다.

고정 첫 호출의 result_gate action은 complete·compose·retry·respond입니다. retry.max1..3, 조건은 exists·empty·non_empty·eq를 사용합니다. gate를 쓰면 agentic, call, response_data_schema, on_exhausted가 모두 필요하고 compose: always와 함께 선언할 수 없습니다.

okf/routing_rule__<name>.mdtype: routing_rule 문서는 모델 호출 없이 schema와 facts로 다음 실행을 고릅니다. 임의 Python이나 eval은 실행하지 않습니다.

---
type: routing_rule
title: work-comparison
priority: 200
enabled: true
when:
facts_mode: all
facts:
- path: request.dataParts[].incomeItems[]
op: exists
- path: request.dataParts[].householdItems[]
op: exists
then:
agentic: support
call: comparison
text: "$user.text"
data: "$context.data"
files: "$context.files"
response_data_schema: support.comparison.result.v1
---
위치필드
rootpriority, enabled, when, then
whenschema 또는 schema_prefixes, facts_mode, facts
facts[]path, op, value, quantifier
thenagentic, call, compose, text, data, files, metadata, request_data_schema, response_data_schema, result_gate, on_exhausted, sequence, output

facts 연산자는 exists·eq·ne·lt·lte·gt·gte·in·contains, quantifierany·all·none입니다. dotted path, items[], items[?status=ready] filter를 지원합니다.

then 선택자는 다음 root만 읽습니다.

root범위
$user현재 턴의 text·data·files
$inputworkflow가 명시적으로 접은 입력
$contextcontext_turns로 허용한 대화
$factsrule 판정 facts
$data이전 child data 또는 현재 user data
$prevsequence 직전 결과의 text·data·data_parts·files

두 개 이상의 고정 호출은 then.sequence에 2~4개 step으로 선언합니다. step 필드는 id, call, text/data/files/metadata selector, request/response data schema이며 id는 rule 안에서 유일해야 합니다. output은 primary로 반환할 step id이고 기본값은 마지막 step입니다.

then:
sequence:
- id: review
call: document_review
response_data_schema: document-review.result.v1
- id: apply
call: benefit
text: "$prev.text"
data: "$prev.data_parts"
files: "$prev.files"
output: apply

sequence step에는 조건을 둘 수 없으며 root call·agentic·compose·result_gate·on_exhausted·입력 selector와 상호 배타적입니다. 모든 alias는 부팅 시 검증하고, 실행 중에는 step별 durable child checkpoint를 사용합니다. input_required 재개는 이전 step을 반복하지 않고 기다리던 step의 저장된 입력과 target binding을 유지합니다. v1은 request source rule에만 허용됩니다.

선택자가 없거나 타입이 맞지 않으면 빈 값으로 조용히 바꾸지 않고 route를 포기합니다. 여러 rule이 맞으면 높은 priority, 더 구체적인 schema, 긴 prefix, rule ID 순으로 선택합니다.

Terminal window
llamon okf route preview \
--sample samples/work-request.json \
--rules okf \
--allowed-alias comparison \
--text "소득과 재산을 비교해 줘" \
--output json

child DataPart에서 라우팅 facts를 안전하게 뽑는 방법은 응답 계약을 참고하세요.

OrchestratorContext는 직접 @managed_run_turn 또는 custom hook을 작성할 때 쓰는 한 턴의 실행 문맥입니다. code-first child는 ctx.call()에 넘긴 값만 보며, 이전 대화나 WorkHistory가 자동으로 섞이지 않습니다.

속성·API역할
user_text, data, files현재 A2A 입력
conversation_id, turn_id, prior_messages식별자와 턴 시작 snapshot
state, execution_storeconversation state와 선택적 durable store
call(alias, ..., call_key=...)child를 호출하고 AgentCallResult 반환
call_stream()chunk와 최종 결과; durable 호출 원장 대상은 아님
call_observed()·call_stream_observed()child observation ref와 결과 반환
gather({...}, return_exceptions=...)최대 16개 병렬 호출
generate(name, **bindings)등록한 stateless generator 호출
result = await ctx.call(
"verification",
text=ctx.user_text,
data=ctx.data,
files=ctx.files,
# 같은 alias를 여러 단계에서 쓰면 durable key를 분리합니다.
call_key="verify-documents",
)

@managed_run_turncall()은 완료 결과를 durable 원장에서 복구하므로 state 저장 재시도만으로 child를 다시 호출하지 않습니다. 같은 alias를 여러 단계에서 쓰면 고유한 call_key가 필요합니다. call_stream()은 공개 가능한 최종 text에만 사용하세요.

API역할
get, remember, reduce, accumulatebounded workflow state 읽기·병합
prior_turns, fold_prior최근 text snapshot 읽기·접기
prior_files, fold_files과거 파일 참조 읽기·병합; bytes 복원 없음
prior_data, fold_data, has_new_dataDataPart 조회·식별값 기준 병합
work.remember, work.summarize_result, work.recall검토한 summary·facts의 bounded WorkHistory
get_resume, set_resume, clear_resumeraw callback용 작은 진행 표식

수동 resume은 recipe의 checkpoint·target snapshot·relay artifact·중복 방지를 대신하지 않습니다. 원본 DataPart를 WorkHistory나 generator facts로 넘기지 말고 response contract로 투영하세요.

필드의미
text, data, data_parts, files, raw정규화한 child 결과
task_state, is_input_requiredA2A 제어 상태
is_unavailable아직 resolve되지 않은 _pending_agent sentinel
is_error, error_codeapplication-level 오류
summary_part_for(schema)WorkHistory summary DataPart 선택

_pending_agent는 네트워크 실패가 아닙니다. target resolve·전송·프로토콜 장애는 ChildUnresolvedError·ChildCallError 예외입니다. 제어 상태를 먼저 처리한 뒤 완료 결과만 합치세요.

ResponseContractCache는 이미지의 CONTRACT_ROOT를 immutable baseline으로 두고, 선택적으로 okf-syncer snapshot을 schema별 overlay합니다. CONTRACT_SNAPSHOT_URL이 비어 있으면 로컬 계약만 사용합니다. CONTRACT_CACHE_DIR을 설정하면 검증한 마지막 snapshot을 재시작 때 네트워크보다 먼저 복원합니다.

전체 환경변수와 운영 규칙은 응답 계약 — 원격 snapshot과 cache를 보세요.

Adaptive planning은 신규 --workflow agentic|deterministic 경로가 아닙니다. 기존 --recipe adaptive --preview 호환 프로젝트에서만 [planning.<name>]allowed_capabilities, max_steps, max_replans = 0을 사용합니다. 신규 구현은 rules-first Agentic 또는 Deterministic workflow로 옮기세요.