오케스트레이터 설정·API
이 페이지는 구현 중 필드와 API를 다시 찾는 빠른 참조입니다. 처음 구성한다면 오케스트레이터 시작하기, 실행 방식은 Agentic 또는 Deterministic 가이드부터 보세요.
최종 출력 runtime evaluator
섹션 제목: “최종 출력 runtime evaluator”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,)| 인자 | 기본값 | 계약 |
|---|---|---|
evaluators | None | orchestrator 최종 출력에 적용할 순서 있는 evaluator 목록 |
evaluator_timeout_seconds | 90.0 | evaluator별 제한 시간. None이면 제한 없음 |
input_required·실패 결과는 평가하지 않고 evaluator 오류는 기록한 뒤 원래 응답을
유지합니다. 종료된 child 자체를 평가하는 call_observed() 경로와 최종 응답 평가는
대상과 topology가 다릅니다. 자세한 규칙은
Runtime Evaluator Framework를
참고하세요.
orchestrator.toml
섹션 제목: “orchestrator.toml”SDK 소유 namespace는 알 수 없는 키와 잘못된 타입을 기동 단계에서 거부합니다. 애플리케이션 값은 [app.<namespace>]에 두고 composition root에서 직접 검증하세요.
[orchestrator]id = "support-desk"state_backend = "postgres"
[limits]max_state_bytes = 524288max_messages = 50
[agents]search = "registry:support-search"
[agentic.support]model = "59"prompt = "support-supervisor"max_controller_steps = 4max_tool_calls = 3context_turns = 10context_roles = ["user", "assistant"]work_memory_context = "relevant"work_memory_context_max_items = 10work_memory_context_max_bytes = 16384public_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"Namespace
섹션 제목: “Namespace”| 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.input | output]` |
[work_memory] | 작업 결과의 bounded summary·facts 보관 |
[app.<namespace>] | SDK가 해석하지 않는 앱 설정 |
[orchestrator].id는 프로젝트의 논리 ID이고, [orchestrator].state_backend는 in_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>]에서 따로 허용합니다.
AgenticProgram과 tool
섹션 제목: “AgenticProgram과 tool”| 키 | 허용값·기본값 |
|---|---|
max_controller_steps | 1..4, 기본 4 |
max_tool_calls | 1..3, 기본 3 |
structured_output_retries | 0..1, 기본 1 |
public_emissions | boolean, 기본 false. controller가 선언한 공개 emission만 전달 |
context_turns | 0..50, 기본 10 |
context_roles | user 필수, assistant 선택 |
work_memory_context | none·relevant·latest·all |
work_memory_context_max_items | 1..100, 기본 10 |
work_memory_context_max_bytes | 12..65536, 기본 16384 |
tools.<alias>.safety | read_only·side_effecting |
tools.<alias>.input | request·context·conversation, 기본 context; conversation은 read_only 전용 |
request_data_schema·response_data_schema | schema가 없을 때만 붙이는 fallback |
side_effecting tool은 durable input snapshot과 사용자 승인 없이 실행되지 않습니다. 최종 담당자 검수는 별도 경계입니다. [agentic.<name>.human_review].mode는 disabled·controller·always이고, required_tools로 고정 child 결과에도 검수를 요구할 수 있습니다.
input = "request"는 현재 턴의 입력 snapshot을 그대로 전달하고, 기본 context는 현재 요청 text에 승인된 attachment DataPart·파일 참조·WorkMemory projection을 더합니다. conversation은 context와 같은 범위를 유지하면서 controller가 최근 bounded 대화의 지시 대상을 해소한 최대 4,000자의 독립 child text를 전달합니다. 직전 assistant 답변의 문서명·페이지가 필요하면 program의 context_roles에 assistant를 포함하세요. conversation은 read-only 도구에만 허용되며 TextPart 외 data·files·target 같은 일반 도구 인자는 controller가 바꿀 수 없습니다.
가드레일 전체 필드는 최종 응답과 안전 경계, 검증 설정은 결과 검증 루프, 기억 설정은 상태·기억·재개를 참고하세요.
결과 정책
섹션 제목: “결과 정책”child 결과를 바로 완료할지 controller가 합성할지는 호출 위치에 따라 다르게 선언합니다.
| 위치 | 정책 | 용도 |
|---|---|---|
| controller tool | completion + completion_when | 단일 성공 조건으로 text 통과 |
| controller tool | result_transitions | 여러 구조화 상태를 complete·continue로 분기 |
OKF then.call | result_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_transitions는completion·completion_when과 함께 쓸 수 없고side_effectingtool에는 허용되지 않습니다.- 중단 뒤 재개할 때 정책 digest가 바뀌면 저장된 child 결과는 재사용하되 새 정책으로 자동 완료하지 않습니다.
고정 첫 호출의 result_gate action은 complete·compose·retry·respond입니다. retry.max는 1..3, 조건은 exists·empty·non_empty·eq를 사용합니다. gate를 쓰면 agentic, call, response_data_schema, on_exhausted가 모두 필요하고 compose: always와 함께 선언할 수 없습니다.
OKF 라우팅 rule
섹션 제목: “OKF 라우팅 rule”okf/routing_rule__<name>.md의 type: routing_rule 문서는 모델 호출 없이 schema와 facts로 다음 실행을 고릅니다. 임의 Python이나 eval은 실행하지 않습니다.
---type: routing_ruletitle: work-comparisonpriority: 200enabled: 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---| 위치 | 필드 |
|---|---|
| root | priority, enabled, when, then |
when | schema 또는 schema_prefixes, facts_mode, facts |
facts[] | path, op, value, quantifier |
then | agentic, 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, quantifier는 any·all·none입니다. dotted path, items[], items[?status=ready] filter를 지원합니다.
then 선택자는 다음 root만 읽습니다.
| root | 범위 |
|---|---|
$user | 현재 턴의 text·data·files |
$input | workflow가 명시적으로 접은 입력 |
$context | context_turns로 허용한 대화 |
$facts | rule 판정 facts |
$data | 이전 child data 또는 현재 user data |
$prev | sequence 직전 결과의 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: applysequence 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 순으로 선택합니다.
llamon okf route preview \ --sample samples/work-request.json \ --rules okf \ --allowed-alias comparison \ --text "소득과 재산을 비교해 줘" \ --output jsonchild DataPart에서 라우팅 facts를 안전하게 뽑는 방법은 응답 계약을 참고하세요.
OrchestratorContext
섹션 제목: “OrchestratorContext”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_store | conversation 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_turn의 call()은 완료 결과를 durable 원장에서 복구하므로 state 저장 재시도만으로 child를 다시 호출하지 않습니다. 같은 alias를 여러 단계에서 쓰면 고유한 call_key가 필요합니다. call_stream()은 공개 가능한 최종 text에만 사용하세요.
상태·대화·기억
섹션 제목: “상태·대화·기억”| API | 역할 |
|---|---|
get, remember, reduce, accumulate | bounded workflow state 읽기·병합 |
prior_turns, fold_prior | 최근 text snapshot 읽기·접기 |
prior_files, fold_files | 과거 파일 참조 읽기·병합; bytes 복원 없음 |
prior_data, fold_data, has_new_data | DataPart 조회·식별값 기준 병합 |
work.remember, work.summarize_result, work.recall | 검토한 summary·facts의 bounded WorkHistory |
get_resume, set_resume, clear_resume | raw callback용 작은 진행 표식 |
수동 resume은 recipe의 checkpoint·target snapshot·relay artifact·중복 방지를 대신하지 않습니다. 원본 DataPart를 WorkHistory나 generator facts로 넘기지 말고 response contract로 투영하세요.
AgentCallResult
섹션 제목: “AgentCallResult”| 필드 | 의미 |
|---|---|
text, data, data_parts, files, raw | 정규화한 child 결과 |
task_state, is_input_required | A2A 제어 상태 |
is_unavailable | 아직 resolve되지 않은 _pending_agent sentinel |
is_error, error_code | application-level 오류 |
summary_part_for(schema) | WorkHistory summary DataPart 선택 |
_pending_agent는 네트워크 실패가 아닙니다. target resolve·전송·프로토콜 장애는 ChildUnresolvedError·ChildCallError 예외입니다. 제어 상태를 먼저 처리한 뒤 완료 결과만 합치세요.
응답 계약 snapshot
섹션 제목: “응답 계약 snapshot”ResponseContractCache는 이미지의 CONTRACT_ROOT를 immutable baseline으로 두고, 선택적으로 okf-syncer snapshot을 schema별 overlay합니다. CONTRACT_SNAPSHOT_URL이 비어 있으면 로컬 계약만 사용합니다. CONTRACT_CACHE_DIR을 설정하면 검증한 마지막 snapshot을 재시작 때 네트워크보다 먼저 복원합니다.
전체 환경변수와 운영 규칙은 응답 계약 — 원격 snapshot과 cache를 보세요.
Legacy Adaptive
섹션 제목: “Legacy Adaptive”Adaptive planning은 신규 --workflow agentic|deterministic 경로가 아닙니다. 기존 --recipe adaptive --preview 호환 프로젝트에서만 [planning.<name>]의 allowed_capabilities, max_steps, max_replans = 0을 사용합니다. 신규 구현은 rules-first Agentic 또는 Deterministic workflow로 옮기세요.