콘텐츠로 이동

문제 해결

문제가 생기면 먼저 다음 세 줄로 범위를 좁히세요.

Terminal window
uv run llamon doctor .
LOG_LEVEL=DEBUG uv run llamon run . --no-detach
docker compose -f compose.yml logs -f agent
증상먼저 볼 곳
서버가 뜨지 않음실행 오류
graph·node 수정 뒤 실패코드 수정 후 오류
Registry model 호출 실패Registry LLM 오류
응답이 느리거나 <think>가 노출됨reasoning 모드
같은 대화가 이어지지 않음세션 메모리
prompt 변수가 그대로 출력됨Prompt binding
폐쇄망 package·build 실패폐쇄망 준비

LOG_LEVEL은 SDK와 app.* logger를, UVICORN_LOG_LEVEL은 서버·access log를 제어합니다.

설정권장값보이는 것
LOG_LEVEL평소 WARNING, 진단 DEBUGrouting, MCP, node, guardrail, 사용자 logger
UVICORN_LOG_LEVEL평소 info시작 로그와 모든 HTTP access log
TRACE_CONSOLE_ENABLED필요할 때만 true별도 trace console 채널

uvicorn access log는 응답 코드와 관계없이 INFO입니다. UVICORN_LOG_LEVEL=warning이면 404·500 access line도 숨고, 처리되지 않은 예외 traceback만 uvicorn.errorERROR로 남을 수 있습니다.

사용자 코드에서는 logging.getLogger(__name__)만 사용하고 basicConfig()를 다시 호출하지 마세요.

증상원인·해결
알 수 없는 templateuv run llamon scaffold list로 현재 SDK의 Agent·Flow·Orchestrator 공개 키 확인 (agent-structured-ollama 포함)
알 수 없는 --exampleobservability·rubric-judge·groundedness 중 하나 사용. outcome-evaluator에는 starter를 중첩하지 않음
outbound/memory/backends.py에서 DB 실패checkpointer 문제. POSTGRES_MEMORY_DSN 확인
app/nodes.py에서 asyncpg 실패비즈니스 DB 문제. POSTGRES_URL 확인
uv run python main.py에서 postgres host 실패compose 밖에서 실행 중. uv run llamon run . 사용 또는 외부 DSN 지정
compose 파일 없음프로젝트 root에서 실행하거나 --compose-file 지정
Address already in use사용 중인 port를 종료하거나 .envPORT 변경

메모리 DSN과 비즈니스 노드 DSN은 서로 독립입니다. traceback에서 처음 등장하는 프로젝트·SDK 파일을 기준으로 구분하세요.

코드 수정 후 오류 (그래프/노드)

섹션 제목: “코드 수정 후 오류 (그래프/노드)”
증상수정
keyword-only TypeErrorregistry_node를 closure로 감싸 필요한 URL·config를 전달
NoneType을 awaitnode를 async def로 선언
node 반환 뒤 AttributeErrorreturn {"output": ...} 같은 state update를 명시
시작 즉시 graph 오류build_graph().build() 결과를 반환하는지 확인
<YOUR_...> 또는 TODO 잔존uv run llamon doctor .로 scaffold placeholder 확인

LLM이 같은 tool을 반복하거나 잘못 고르는 문제는 graph 버그와 다릅니다. 호출 순서가 업무 규칙으로 확정돼 있다면 prompt를 늘리기보다 @deterministic_tool 또는 Deterministic workflow를 사용하세요.

증상확인
404 + loc=GATEWAYLLMConfig(id=...)의 Registry model ID와 model 연결
404 + loc=PROVIDERprovider protocol과 endpoint; vLLM은 보통 OpenAI 호환 /v1
Registry model이 Ollama adapter로 호출됨provider_type.code가 실제 PROVIDER_OLLAMA인지 확인
401·403Registry credential과 runtime secret 주입
timeoutendpoint reachability와 LLM_TIMEOUT 확인

확인 순서는 provider의 provider_type.code → model ID → endpoint protocol입니다. 모델 이름만 보고 provider 방식을 추정하지 마세요.

reasoning=None은 모델 기본값을 유지합니다. 느린 응답, 과도한 token, <think> 노출이 있으면 실제 endpoint 종류에 맞춰 설정합니다.

endpoint대표 설정
vLLM Qwen 계열provider_extra={"chat_template_kwargs":{"enable_thinking":False}}
DeepSeek·GLM·Kimi 공식 OpenAI 호환 APIprovider_extra={"thinking":{"type":"disabled"}}
Ollama /v1 또는 이를 감싼 OpenAI 호환 proxyprovider_extra={"reasoning_effort":"none"}
Direct Ollama adapterreasoning=False
OpenAI native reasoning modelreasoning="low" 또는 Reasoning(effort="low")
Anthropicreasoning=True 또는 Reasoning(budget_tokens=...)

provider_extra는 SDK 변환보다 우선하는 raw provider 옵션입니다. 같은 모델도 vLLM에 올렸는지, 공식 API인지, Ollama /v1인지에 따라 필드가 달라집니다. 지원하지 않는 reasoning parameter로 400이 나면 해당 값을 제거하세요. 전체 입력 형태는 에이전트 구성의 reasoning 필드를 참고하세요.

Registry의 provider_type.codePROVIDER_VLLM이어도 endpoint가 Ollama /v1로 전달하는 proxy라면 Ollama 행을 사용합니다. 예를 들어 이런 경로의 Kimi K2.6에 chat_template_kwargs.thinking=False를 보내거나 Moonshot 공식 API용 thinking.type="disabled"를 보내면 proxy가 값을 무시해 thinking이 계속될 수 있습니다. Moonshot 직결과 Ollama proxy는 각각 Kimi K2.6 공식 API, Ollama OpenAI 호환 API의 요청 필드를 따릅니다.

응답에 reasoning_content가 없다는 사실만으로 thinking 종료를 판단하지 마세요. gateway가 추론 내용을 숨겨도 token 사용량에는 포함될 수 있습니다. 짧은 고정 답변으로 전후를 비교해 final content보다 output_tokens가 과도하게 크거나 지연 시간이 긴지 확인합니다.

빈 final content가 반복되면 max_tokens를 늘리거나 reasoning 강도를 낮춥니다. 호출이 끝없이 대기하는 문제는 reasoning이 아니라 LLM_TIMEOUT으로 제한합니다.

REACT_MAX_ITERATIONS=N은 직접 ReAct Agent와 Flow의 registry_llm node 기본값입니다. 내부 LangGraph 상한은 N * 2 + 1입니다. 한 cycle이 LLM과 tool 두 전이를 쓰고 마지막 응답 LLM 호출이 한 번 더 필요하기 때문입니다.

범위규칙
직접 AgentExtensionConfig(max_retry=N) 또는 env 값
Flow 바깥 graphLangGraph 기본 재귀 한계; max_retry와 별개
Flow registry_llmnode 값 > Flow 값 > 기본 3
원격 registry_node부모의 반복 상한을 전달하지 않음

기본 3recursion_limit=7입니다. Agent Card의 urn:llamon:agent-config에는 외부 계약인 maxRetry로 노출됩니다. 반복 호출이 업무상 불필요하다면 상한을 늘리기 전에 deterministic 경계로 옮기세요.

증상원인·해결
같은 사용자인데 대화가 끊김모든 요청의 message.contextId를 같은 값으로 유지
params.metadata.thread_id를 보냈는데 미동작세션 키는 message.contextId
send는 되지만 stream에서 끊김message/stream에도 같은 contextId 전달
저장 메시지는 많은데 모델이 모름window_size, summarize, fact recall 설정 확인

PgBouncer는 session 모드가 기본 권장입니다. transaction 모드가 필요하면 MEMORY_PG_STATEMENT_CACHE_SIZE=0으로 prepared statement cache를 끄고 검증하세요.

증상해결
prepared statement ... does not existPOOL_MODE=session 또는 statement cache 비활성화
약 1시간 뒤 dead connectionSDK와 PgBouncer의 connection lifetime을 PgBouncer SERVER_LIFETIME보다 짧게 설정
cl_waiting > 0활성 컨테이너 수 기준으로 pool 크기 재산정
대량 thread 삭제 timeoutthread ID를 batch로 나눠 삭제

연결 수와 세부 설정은 멀티턴 메모리 — PgBouncer을 보세요.

증상해결
{{job}}가 그대로 출력PromptConfig.bindings의 source 지정
env.X가 비어 있음LLAMON_, PROMPT_, TMPL_ prefix 사용
단독 Agent에서 node.x.output이 비어 있음node.*는 Flow 전용; input·context.* 사용
metadata가 prompt에 없음context.userId처럼 명시적으로 binding
PromptConfig(
id="<PROMPT_ID>",
bindings={
"user": {"source": "context.userId"},
"job": {"source": "input"},
},
)

자동화는 메시지 문자열이 아니라 안정된 진단 필드를 사용합니다.

명령·응답사용할 값
llamon doctor --output jsondiagnostics[].code, repair_id, fix_safety
llamon graph inspect --output jsondiagnostics, summary.passed
Studio save 409detail.diagnostics, expected_sha, actual_sha

fix_safety="safe"만 자동 적용하고 manual은 검토 뒤 처리하세요.

증상해결
uv.lock 없음uv lockprepare-offline 재실행
wheelhouse/가 비었음대상 OS·Python·ABI를 지정하고 --clean으로 다시 수집
SDK wheel checksum 실패./update_sdk_wheel.sh .로 wheel과 SHA 갱신
wheelhouse.sha256 없음vendor-deps를 먼저 실행하거나 prepare-offline 사용
base image pull 실패--python-base-image로 내부 Registry image 지정
Nexus에 lock 버전 없음Nexus 기준으로 relock한 뒤 package 재생성

배포 단계 문제는 SSH 원격 배포, profile 적용은 인프라 프로필을 참고하세요.

증상해결
uv: command not foundshell을 다시 열거나 source $HOME/.local/bin/env
llamon: command not found프로젝트에서 uv run llamon 사용 또는 uv tool install
uv sync --frozen에서 wheel 없음배포 bundle의 wheel과 .sha256 파일 확인
OPENAI_API_KEY 누락.env.example.env로 복사하고 key 설정

문제를 재현할 때는 secret을 지운 doctor --output json, 처음 실패한 traceback, 사용한 contextId, Registry model ID만 함께 남기면 대부분의 원인을 좁힐 수 있습니다.