설정 상세 안내
WeKnora 설정은 네 계층으로 구성되며, 우선순위가 낮은 것부터 높은 순서는 다음과 같습니다.
| 계층 | 위치 | 용도 |
|---|---|---|
| 주 설정 파일 | config/config.yaml | 구조화된 기본값, 이미지와 함께 배포 |
| 템플릿 / 프리셋 | config/prompt_templates/*.yaml, builtin_agents.yaml, agent_type_presets.yaml, builtin_models.yaml | 프롬프트, 내장 Agent, 내장 모델 |
| 환경 변수 | .env / 컨테이너 environment | 배포 단위 재정의, 변경 후 재시작 필요 |
| 런타임 시스템 설정 | 데이터베이스 system_settings 테이블, 화면의 '설정 → 시스템' | 지원되는 설정은 온라인으로 변경할 수 있으며, 환경 변수보다 우선하고 대부분 즉시 적용됩니다 |
가입 모드, 공간 정책과 할당량, SSRF 허용 목록, 작업 동시 실행 수, 모델 동시 실행 상한은 런타임 설정을 지원합니다. 콘솔에서 변경하면 데이터베이스 값이 환경 변수보다 우선합니다. 설정 항목을 초기화해야(DELETE /api/v1/system/admin/settings/:key) 환경 변수 또는 내장 기본값을 다시 사용합니다. 환경 변수가 적용되지 않는 문제를 조사할 때는 해당 항목에 런타임 설정이 있는지 먼저 확인해야 합니다. 전체 설정은 플랫폼 관리와 시스템 관리자를 참고하세요.
주 설정 구조는 internal/config/config.go에 정의되어 있습니다. 각 설정과 환경 변수의 의미, 기본값, 적용 조건은 다음과 같습니다.
설정 로드 방식
internal/config/config.go의 LoadConfig() 흐름:
- viper가
config.yaml을 순서대로 찾습니다. 현재 디렉터리 →./config→$HOME/.appname→/etc/appname/. - 환경 변수 확장: 파일 내용을 정규식으로 치환하여
${ENV_VAR}를 같은 이름의 환경 변수 값으로 바꿉니다. 변수가 설정되지 않으면 설정 오류를 드러내기 위해 리터럴${ENV_VAR}를 그대로 유지합니다. - viper에서
AutomaticEnv()를 활성화하고 key 구분자.을_로 매핑합니다(즉, 환경 변수SERVER_PORT로server.port를 재정의할 수 있습니다). config/prompt_templates/*.yaml에서 프롬프트 템플릿을 로드하고xxx_prompt_id필드에 따라 conversation 설정을 보충합니다(backfillConversationDefaults).builtin_agents.yaml(내장 Agent)과agent_type_presets.yaml(Agent 유형 프리셋)을 로드하고 내부의system_prompt_id참조를 해석합니다.- 환경 변수 재정의를 적용하고(OIDC, Agent, KnowledgeBase, Auth/Tenant, Audit 그룹)
ValidateConfig로 검증합니다.
config/config.yaml 섹션별 설명
server(ServerConfig)
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
server.port | int | 8080 | HTTP 수신 포트, 유효 범위 1–65535 |
server.host | string | "0.0.0.0" | 수신 주소 |
server.log_path | string | 비어 있음 | 로그 파일 경로(환경 변수 LOG_PATH도 사용 가능) |
server.shutdown_timeout | duration | 30s | 정상 종료 타임아웃 |
conversation(ConversationConfig) — 검색 질의응답 파이프라인
| 이름 | 타입 | 기본값(config.yaml) | 설명 |
|---|---|---|---|
max_rounds | int | 5 | 포함할 이전 대화 턴 수 |
keyword_threshold | float | 0.3 | 키워드 검색 최소 점수 |
embedding_top_k | int | 30 | 벡터 검색 후보 수(>=0) |
vector_threshold | float | 0.2 | 벡터 유사도 임계값(0–1) |
rerank_top_k | int | 30 | 리랭킹 후 유지할 결과 수 |
rerank_threshold | float | 0.3 | 리랭킹 최소 점수(-10–10) |
fallback_strategy | string | "model" | 검색 결과가 없을 때의 전략: model(모델로 대체 답변) 또는 고정 응답 |
fallback_response | string | "Sorry, I am unable to answer this question." | 고정 대체 응답 문구 |
enable_rewrite | bool | true | 다중 턴 지시어 해소 / 쿼리 재작성 |
enable_query_expansion | bool | true | 쿼리 확장 |
enable_rerank | bool | true | Rerank 활성화 |
fallback_prompt_id | string | "default_fallback_prompt" | 대체 prompt 템플릿 ID(prompt_templates/fallback.yaml, mode:"model") |
rewrite_prompt_id | string | "default_rewrite" | 재작성 템플릿 ID(시스템 측 content + 사용자 측 user 포함) |
generate_summary_prompt_id | string | "default_summary" | 문서 요약 템플릿 ID |
generate_session_title_prompt_id | string | "default_session_title" | 세션 제목 생성 템플릿 ID |
extract_entities_prompt_id / extract_relationships_prompt_id | string | "default_extract_entities" / "default_extract_relationships" | 그래프 추출 템플릿 ID(graph_extraction.yaml) |
generate_questions_prompt_id | string | "default_generate_questions" | 사전 질문 생성 템플릿 ID |
conversation.summary(SummaryConfig, 답변 생성 매개변수):
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
max_input_chars | int | 16384 | LLM에 전달할 최대 문자 수 |
temperature | float | 0.3 | 생성 온도 |
repeat_penalty | float | 1.0 | 반복 페널티 |
max_completion_tokens | int | 2048 | 최대 생성 토큰 수 |
no_match_prefix | string | <think>\n</think>\nNO_MATCH | 모델 출력이 이 접두사로 시작하면 '일치 없음'으로 판단하여 fallback 실행 |
prompt_id | string | "default_kb" | 시스템 Prompt 템플릿 ID(system_prompt.yaml) |
context_template_id | string | "default_context" | 문맥 구성 템플릿 ID(context_template.yaml) |
max_tokens / top_k / top_p / frequency_penalty / presence_penalty / seed / thinking | 여러 타입 | 설정되지 않음 | 모델에 그대로 전달하는 선택적 샘플링 매개변수. thinking은 사고 모드를 제어하는 *bool |
knowledge_base(KnowledgeBaseConfig) — 전역 기본 청크 설정
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
chunk_size | int | 512 | 기본 청크 크기(>0이며 > overlap) |
chunk_overlap | int | 50 | 청크 겹침 |
split_markers | []string | ["\n\n", "\n", "。"] | 분할 구분자 |
keep_separator | bool | false | 구분자 유지 |
document_process_timeout | duration | 2h | 단일 문서 처리 작업의 전체 타임아웃(env WEKNORA_DOCUMENT_PROCESS_TIMEOUT으로 재정의 가능) |
docreader_call_timeout | duration | 30m | 단일 DocReader RPC 타임아웃(env WEKNORA_DOCREADER_CALL_TIMEOUT), 위 항목보다 작아야 함 |
image_processing.enable_multimodal | bool | true | 업로드 시 이미지 멀티모달 처리(OCR/Caption) 활성화 |
각 지식 베이스의
ChunkingConfig가 이 전역 기본값을 재정의합니다.
extract(ExtractManagerConfig) — 지식 그래프 추출 템플릿
extract.extract_graph / extract.extract_entity / extract.fabri_text는 그래프 추출 설명문(description), 허용 관계 태그(tags, 기본값 Author, Alias), few-shot 예제(examples: text + node + relation)를 정의합니다. 초기 설정 마법사의 '시험 추출 / 예제 텍스트 생성'이 이 설정을 사용합니다(fabri_text.with_tag / with_no_tag의 %s는 태그 목록으로 바뀝니다).
tenant(TenantConfig)
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
enable_cross_tenant_access | bool | false | CanAccessAllTenants를 가진 사용자의 공간 간 접근 허용(내부망에서 활성화 가능) |
enable_rbac | *bool | true | 공간 역할 권한 검증 강제. 명시적 false이면 차단하지 않고 기록만 하는 점진적 적용 모드로 전환(env WEKNORA_TENANT_ENABLE_RBAC) |
max_owned_per_user | int | 0(handler 기본값 사용) | 슈퍼 관리자가 아닌 사용자 한 명이 직접 만들 수 있는 공간 수 상한. <0이면 제한 해제(env WEKNORA_TENANT_MAX_OWNED_PER_USER) |
self_service_creation_enabled | *bool | true | 일반 사용자의 공간 직접 생성 허용 여부(env WEKNORA_TENANT_SELF_SERVICE_CREATION_ENABLED) |
default_session_name / default_session_title / default_session_description | string | 비어 있음 | 새 세션의 기본 문구 |
구조체에서는 지원하지만 기본 파일에 없는 섹션
다음 섹션은 Config 구조체에 있으며 필요에 따라 config.yaml에 추가할 수 있습니다(대부분 환경 변수도 지원).
| 섹션 | 구조체 | 주요 필드 및 기본값 |
|---|---|---|
auth | AuthConfig | registration_mode: self_serve(기본값) / invite_only(DISABLE_REGISTRATION=true일 때 강제). default_tenant_mode: create_personal(기본값) / tenantless |
audit | AuditConfig | retention_days: 감사 로그 보관 일수, 섹션 생략 시 기본 90. 0이면 정리 비활성화, <0이면 검증 오류(env WEKNORA_AUDIT_RETENTION_DAYS) |
oidc_auth | OIDCAuthConfig | enable, issuer_url, jwks_uri, discovery_url(생략 시 issuer에 /.well-known/openid-configuration을 붙여 구성), client_id, client_secret, authorization_endpoint, token_endpoint, user_info_endpoint, scopes(기본 openid profile email), user_info_mapping.username(기본 name)/email(기본 email). 모두 OIDC_AUTH_* 환경 변수로 재정의 가능 |
agent | AgentConfig | llm_call_timeout: 단일 LLM 호출 타임아웃 초(기본 120, env WEKNORA_AGENT_LLM_TIMEOUT). tool_approval_timeout_seconds: MCP 도구 수동 승인 대기(기본 600, env WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT) |
im | IMConfig | IM 채널 QA 동시 실행: workers(5), global_max_workers(0=무제한, Redis 필요), max_queue_size(50), max_per_user(3), rate_limit_window(60s), rate_limit_max(10) |
docreader | DocReaderConfig | addr(docreader:50051 같은 gRPC 주소 또는 HTTP base URL), transport: grpc(기본값) / http. 보통 env DOCREADER_ADDR / DOCREADER_TRANSPORT 사용 |
vector_database | VectorDatabaseConfig | driver(보통 env RETRIEVE_DRIVER 사용) |
stream_manager | StreamManagerConfig | type: memory / redis. redis.address/username/password/db/prefix/ttl, cleanup_timeout(보통 env STREAM_MANAGER_TYPE, REDIS_* 사용) |
web_search | WebSearchConfig | timeout: 웹 검색 타임아웃 초 |
models | []ModelConfig | 이전 방식의 정적 모델 목록(type/source/model_name/parameters). 현재는 builtin_models.yaml 또는 화면 설정 권장 |
frontend_base_url | string | 비어 있음 |
주요 환경 변수
다음 변수는 docker-compose.yml의 app/docreader environment 섹션, .env.example, 코드의 os.Getenv에서 가져왔습니다. 프로덕션 배포 시 최소한 DB_USER/DB_PASSWORD/DB_NAME, REDIS_PASSWORD, JWT_SECRET, SYSTEM_AES_KEY를 변경해야 합니다.
런타임 기본 설정
| 이름 | 기본값 | 설명 |
|---|---|---|
GIN_MODE | release | debug 개발 모드(Swagger 활성화) / release 프로덕션 |
LOG_LEVEL / LOG_PATH / LOG_FORMAT | debug / 비어 있음 / 비어 있음 | 로그 수준, 파일 경로(비어 있으면 stdout만 사용), 사용자 정의 형식 |
LLM_DEBUG_LOG | false | true이면 LOG_PATH와 같은 디렉터리에 llm_debug.log 기록 |
TZ | Asia/Shanghai | 시간대 |
WEKNORA_LANGUAGE | 비어 있음 | 문서 처리 언어(질문/요약 생성). 우선순위: 이 변수 > 요청의 Accept-Language > 내장 zh-CN. 문서 처리 언어는 화면 언어와 별도로 설정할 수 있습니다. 예를 들어 영어 화면에서 한국어 문서를 처리할 수 있습니다 |
AUTO_MIGRATE | true | 시작 시 데이터베이스 마이그레이션 자동 실행 |
AUTO_RECOVER_DIRTY | true | golang-migrate의 dirty 상태(이전 마이그레이션 중단으로 남은 상태) 자동 복구. 마이그레이션 문제를 수동 조사할 때는 일시적으로 false로 설정해야 합니다. 그렇지 않으면 시작 시 마이그레이션 버전 기록을 자동으로 수정합니다. 데이터베이스와 마이그레이션 참고 |
WEKNORA_TRUSTED_PROXIES | 비어 있음 | gin의 신뢰 프록시 CIDR(쉼표로 구분) |
MAX_SKILL_BUNDLE_SIZE_MB | 256 MiB(기본값은 MAX_FILE_SIZE_MB 이상, 상한 512 MiB) | 스킬 ZIP 업로드 및 소스 다운로드 상한. 리버스 프록시 요청 본문 제한도 충분히 커야 합니다 |
MAX_FILE_SIZE_MB | 50 | 업로드 파일 크기 제한(app/frontend/docreader 세 곳에서 공용) |
CONCURRENCY_POOL_SIZE | 5 | 공용 동시 실행 풀 |
APP_EXTERNAL_URL / FRONTEND_BASE_URL | 비어 있음 | IM 채널 이미지/파일 외부 링크에 사용할 외부 접근 가능 URL / 프런트엔드 외부 origin |
RESOURCE_URL_MODE | handle | API 응답의 기본 파일 참조 형식. handle은 내부 resource://, public은 직접 로드 가능한 기간 제한 외부 링크를 반환합니다. 개별 요청에서 ?resource_urls=로 재정의할 수 있습니다. API 개요 참고 |
APP_EXTERNAL_URL은 IM 채널에서 지식 베이스 이미지를 렌더링할 수 있는지에 영향을 줍니다. IM 플랫폼에는 공개 http(s) URL이 필요하며, 다음 중 하나를 선택합니다.
- 스토리지 백엔드 자체가 인터넷에서 접근 가능합니다(객체 스토리지에 공개 endpoint를 사용하거나
MINIO_ENDPOINT를 공개 host로 설정). 이 경우resource://는 백엔드의 사전 서명 URL로 대체되므로 이 변수가 필요하지 않습니다. APP_EXTERNAL_URL을 설정하면resource://이미지가<APP_EXTERNAL_URL>/r/<token>으로 바뀌어 WeKnora 자체를 거칩니다(nginx가/r/를 프록시해야 하며, 공식 프런트엔드 이미지에는 이 location이 내장되어 있습니다).
기본 MinIO 내부망 배포와 local 백엔드는 두 번째 방법만 사용할 수 있습니다. IM 채널이 활성화되었는데 이 변수가 비어 있으면 서비스 시작 시 WARN을 한 번 출력합니다. 변환 결과가 http(s) URL이 아니면 IM에서 접근할 수 없는 링크를 보내는 대신 원래 참조를 유지하고 조치 방법이 담긴 경고를 기록합니다.
네 가지 URL 형식과 채널별 사용 방법은 이미지와 파일의 외부 접근을 참고하세요.
데이터베이스와 큐
| 이름 | 기본값 | 설명 |
|---|---|---|
DB_DRIVER | postgres | postgres / sqlite(Lite) |
DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_NAME | postgres / 5432 / 비어 있음 / 비어 있음 / 비어 있음 | PostgreSQL 연결(필수) |
DB_PATH | — | DB_DRIVER=sqlite일 때의 데이터베이스 파일 경로 |
STREAM_MANAGER_TYPE | 비어 있음(compose에서는 실제로 redis 사용) | redis / memory |
REDIS_ADDR / REDIS_USERNAME / REDIS_PASSWORD / REDIS_DB / REDIS_PREFIX | redis:6379 / … | Redis 연결 |
REDIS_USE_TLS | false | TLS 활성화 마스터 스위치. 관리형 Redis(예: AWS ElastiCache)에서는 켜야 합니다. REDIS_TLS_SERVER_NAME은 검증과 SNI에 사용할 서버 이름을 지정합니다(주소가 IP일 때 유용). REDIS_TLS_INSECURE_SKIP_VERIFY는 인증서 검증을 건너뜁니다(안전하지 않으며 자체 서명 인증서를 쓰는 개발 환경 전용) |
WEKNORA_REDIS_NAMESPACE | 비어 있음 | 여러 배포가 Redis를 공유할 때의 채널 네임스페이스 접미사 |
WEKNORA_ASYNQ_CORE_CONCURRENCY 등 | 8 / 2 / 12 / 4 / 6 | Asynq 각 큐의 동시 실행 수(core/postprocess/enrichment/maintenance/shared). WEKNORA_WIKI_ASYNQ_CONCURRENCY=8, WEKNORA_MODEL_MAX_CONCURRENCY=32도 제공 |
검색 엔진과 벡터 데이터베이스
| 이름 | 기본값 | 설명 |
|---|---|---|
RETRIEVE_DRIVER | postgres | 검색 엔진: postgres / elasticsearch_v7 / elasticsearch_v8 / qdrant / milvus / weaviate / opensearch / doris / tencent_vectordb / sqlite(Lite). 쉼표로 구분하여 여러 엔진을 병렬로 사용 가능 |
ELASTICSEARCH_ADDR/USERNAME/PASSWORD/INDEX | 비어 있음 | Elasticsearch |
QDRANT_HOST/PORT/COLLECTION/API_KEY/USE_TLS | qdrant / 6334 / weknora_embeddings / 비어 있음 / false | Qdrant |
MILVUS_ADDRESS/COLLECTION/METRIC_TYPE/... | milvus:19530 / weknora_embeddings / IP | Milvus |
OPENSEARCH_ADDR/USERNAME/PASSWORD/INDEX/INSECURE_SKIP_VERIFY | 비어 있음 | OpenSearch |
WEAVIATE_HOST/GRPC_ADDRESS/SCHEME/AUTH_ENABLED/API_KEY | 비어 있음 | Weaviate |
DORIS_ADDR/HTTP_PORT/DATABASE/USERNAME/PASSWORD/TABLE_PREFIX/COMPAT_MODE | 비어 있음 | Apache Doris 4.1+ |
TENCENT_VECTORDB_ADDR/USERNAME/API_KEY/DATABASE/COLLECTION/REPLICA_NUMBER | 비어 있음 | Tencent Cloud VectorDB |
MULTI_STORE_RETRIEVE_TIMEOUT_SEC | 비어 있음 | 여러 엔진 병렬 검색 타임아웃 |
NEO4J_ENABLE / NEO4J_URI / NEO4J_USERNAME / NEO4J_PASSWORD | 비어 있음 / bolt://neo4j:7687 / neo4j / password | 지식 그래프의 유일한 활성화 스위치(ENABLE_GRAPH_RAG는 v0.1.6부터 폐기) |
파일 저장소
| 이름 | 기본값 | 설명 |
|---|---|---|
STORAGE_TYPE | local | local / minio / cos / tos / s3 / obs / oss |
STORAGE_ALLOW_LIST | 비어 있음 | 사용자가 선택할 수 있는 저장소 유형 허용 목록(쉼표로 구분) |
LOCAL_STORAGE_BASE_DIR | /data/files | 로컬 저장소 루트 디렉터리 |
MINIO_ENDPOINT/ACCESS_KEY_ID/SECRET_ACCESS_KEY/BUCKET_NAME/USE_SSL | minio:9000 / minioadmin / minioadmin / 비어 있음 / false | MinIO |
COS_SECRET_ID/SECRET_KEY/REGION/BUCKET_NAME/APP_ID/PATH_PREFIX | 비어 있음 | Tencent Cloud COS(TEMP_BUCKET/TEMP_REGION도 제공) |
S3_* / OBS_* / OSS_* / TOS_* | .env.example B4 섹션 참고 | AWS S3 / Huawei OBS / Alibaba OSS / Volcengine TOS. 모두 ENDPOINT/REGION/KEY/BUCKET/PATH_PREFIX 등을 포함 |
AWS S3의 S3_ACCESS_KEY / S3_SECRET_KEY는 둘 다 비워 둘 수 있습니다. 이 경우 AWS SDK 기본 자격 증명 체인을 사용하며 EC2/ECS/EKS IAM Role, IRSA/Web Identity, 환경 변수, 공유 설정 파일을 지원합니다. AWS 배포 시 환경 변수에 장기 키를 별도로 넣을 필요가 없습니다. 두 값은 함께 입력하거나 함께 비워야 합니다. S3_ENDPOINT가 비어 있으면 Region에 해당하는 표준 엔드포인트를 사용합니다.
모델과 추론
| 이름 | 기본값 | 설명 |
|---|---|---|
OLLAMA_BASE_URL | http://host.docker.internal:11434 | Ollama 주소 |
OLLAMA_OPTIONAL | true | Ollama를 사용할 수 없으면 경고만 표시하고 시작을 차단하지 않음 |
BATCH_EMBED_SIZE | 비어 있음 | embedding 배치 크기 |
VLM_HTTP_TIMEOUT_SECONDS | 180 | VLM 단일 요청 타임아웃 |
BUILTIN_MODELS_CONFIG | config/builtin_models.yaml | 내장 모델 선언 파일 경로(아래 참고) |
WEKNORA_LLM_STREAM_RAW_DUMP / _DIR | 비어 있음 | LLM 스트림 원본 덤프(문제 해결용) |
인증, 테넌트, 보안
| 이름 | 기본값 | 설명 |
|---|---|---|
JWT_SECRET | 비어 있음 | JWT 서명 키(필수) |
SYSTEM_AES_KEY | 비어 있음 | 민감 필드를 디스크에 암호화하여 저장하는 AES-256 마스터 키. 반드시 32바이트여야 합니다. 분실하면 암호화된 데이터(테넌트 API Key, 모델 key, 벡터 데이터베이스 자격 증명 등)를 복구할 수 없습니다. v0.4.0부터 TENANT_AES_KEY/CRYPTO_MASTER_KEY/CRYPTO_SALT를 대체합니다 |
DISABLE_REGISTRATION | false | true이면 registration_mode=invite_only 강제 |
WEKNORA_AUTH_DEFAULT_TENANT_MODE | create_personal | 가입 후 공간 생성 정책(create_personal / tenantless) |
WEKNORA_TENANT_ENABLE_RBAC | (기본 true) | 공간 역할 권한 검증 강제 스위치 |
WEKNORA_TENANT_ENABLE_CROSS_TENANT_ACCESS | false | 공간 간 접근 |
WEKNORA_TENANT_SELF_SERVICE_CREATION_ENABLED | true | 일반 사용자의 공간 직접 생성 |
WEKNORA_TENANT_MAX_OWNED_PER_USER | 비어 있음 | 직접 생성할 공간 수 상한 |
WEKNORA_TENANT_AUTO_CREATE_API_KEY | false | 공간 생성 시 full_access API Key 자동 발급(이전 동작 호환) |
WEKNORA_TENANT_DEFAULT_STORAGE_QUOTA_GB | 10 | 새 공간의 기본 저장 용량 할당량 |
WEKNORA_AUTH_COMPLEX_PASSWORD_ENABLED | false | 복잡한 비밀번호 정책: 대문자, 소문자, 숫자, 특수 문자. 시스템 설정 auth.complex_password_enabled가 우선 |
WEKNORA_TENANT_AUTO_ACCEPT_INVITATION | false | 이메일로 초대받은 기존 계정이 바로 참여. 시스템 설정 tenant.auto_accept_invitation이 우선 |
OIDC_AUTH_JWKS_URI | 비어 있음 | id_token 서명 검증용 공개 키 집합. discovery로 보충 가능하며 issuer/audience/유효 기간과 함께 검증 |
WEKNORA_INVITATION_TTL | 168h | 초대 링크 유효 기간 |
WEKNORA_AUDIT_RETENTION_DAYS | 90 | 감사 로그 보관 일수 |
WEKNORA_BOOTSTRAP_SYSTEM_ADMIN_EMAIL | 비어 있음 | 첫 시스템 관리자를 지정합니다. 사용자를 생성하지 않습니다. 해당 이메일로 먼저 가입해야 하며, 다음 시작 시 배포에 시스템 관리자가 없을 때만 승격합니다. 관리자가 이미 있으면 이 변수는 더 이상 적용되지 않습니다. 테넌트, 사용자, 인증 및 권한 참고 |
OIDC_AUTH_ENABLE 및 OIDC_AUTH_* / OIDC_USER_INFO_MAPPING_* | false / 비어 있음 | OIDC 통합 로그인 전체 설정 |
SSRF_WHITELIST / SSRF_WHITELIST_EXTRA | 비어 있음 / searxng,qdrant,milvus,weaviate,doris-fe,doris-be | 아웃바운드 요청 SSRF 허용 목록(app과 docreader 공용) |
IMAGE_HOST_KEEP_URL | 비어 있음 | 원본 URL을 유지할 이미지 도메인 허용 목록 |
Docreader 파싱(docreader 컨테이너)
| 이름 | 기본값 | 설명 |
|---|---|---|
DOCREADER_ADDR / DOCREADER_TRANSPORT | docreader:50051 / grpc | app 측 연결 주소와 전송 방식(grpc/http) |
DOCREADER_GRPC_MAX_WORKERS / DOCREADER_GRPC_PORT / DOCREADER_GRPC_MAX_FILE_SIZE_MB | 4 / 50051 / MAX_FILE_SIZE_MB를 따름 | gRPC 서비스 매개변수 |
GRPC_TLS_ENABLED/CERT/KEY/CA/SERVER_NAME, GRPC_MTLS_REQUIRE_CLIENT_CERT, GRPC_AUTH_TOKEN | false / 비어 있음 | app↔docreader 연결의 TLS/mTLS 및 token 인증 |
DOCREADER_PDF_RENDER_DPI / DOCREADER_PDF_JPEG_QUALITY / DOCREADER_PDF_RENDER_MAX_EDGE | 200 / 85 / 2000 | PDF 렌더링 |
DOCREADER_PDF_FORCE_SCANNED / DOCREADER_PDF_SCAN_IMAGE_RATIO / DOCREADER_PDF_SCAN_MIN_CHARS | false / 코드 기본값 | 스캔본 판별 |
DOCREADER_ODL_HYBRID / DOCREADER_ODL_HYBRID_URL / DOCREADER_ODL_HYBRID_MODE / DOCREADER_ODL_HYBRID_FALLBACK | off / http://odl-hybrid:5002 / auto / false | OpenDataLoader 하이브리드 파싱 |
기타 DOCREADER_PDF_*(단어 간격/사이드바/숨겨진 텍스트/삽입 이미지/차트 영역 등 20개 이상) | docker-compose.yml docreader 섹션 주석 참고 | PDF 레이아웃 및 추출 세부 조정 |
DOCREADER_EXTERNAL_HTTP_PROXY / _HTTPS_PROXY | 비어 있음 | docreader 아웃바운드 수집 프록시 |
Agent, Skills, 첨부 파일
| 이름 | 기본값 | 설명 |
|---|---|---|
| Sandbox 설정 | 설정 페이지에서 공간별 관리 | 백엔드, 자격 증명, 템플릿, 타임아웃, 사설망 접근 정책을 공간별로 저장 |
WEKNORA_SANDBOX_DOCKER_ENABLED | false | Docker 샌드박스 백엔드 대체 사용 스위치. 시스템 관리자가 '설정 → 시스템 설정'에서도 켤 수 있습니다(DB 우선, 즉시 적용). 로컬 docker.sock이 호스트 root와 동등한 권한이므로 기본적으로 꺼져 있습니다 |
WEKNORA_AGENT_LLM_TIMEOUT | 120s | Agent 단일 LLM 호출 타임아웃(Go duration 또는 숫자만 입력한 초) |
WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT / _FAIL_OPEN | 600s / fail-close | MCP 도구 수동 승인 대기 및 실패 정책 |
WEKNORA_CHAT_ATTACHMENT_TTL_HOURS / _WAIT_TIMEOUT_SEC / _OCR_CONCURRENCY / _OCR_MAX_PAGES | 24 / 60 / 8 / 8 | 채팅 첨부 파일 파싱 보관 시간, 대기 타임아웃, OCR 동시 실행/페이지 수 상한 |
WEKNORA_HOUSEKEEPING_ENABLED | 활성화 | processing에 멈춘 비정상 데이터 정리 |
WEKNORA_DOCUMENT_PROCESS_TIMEOUT / WEKNORA_DOCREADER_CALL_TIMEOUT | 2h / 30m | 문서 처리 작업 및 단일 RPC 타임아웃 |
샌드박스 백엔드, 네트워크 정책, 스크립트 스위치, 개인 환경 변수는 공간 설정/API로 관리합니다. 스킬과 샌드박스를 참고하세요. 장기 기억과 자동 태그는 모두 기본적으로 꺼져 있으며, 각각 테넌트 memory_config와 지식 베이스 auto_tag_config를 사용합니다. 전역 환경 변수로 각 공간 설정을 대체하지 않습니다.
관측 가능성(Langfuse)
LANGFUSE_PUBLIC_KEY + LANGFUSE_SECRET_KEY를 모두 설정하면 자동으로 활성화됩니다. LANGFUSE_HOST(기본 https://cloud.langfuse.com, 자체 호스팅 스택은 http://langfuse-web:3000), LANGFUSE_ENABLED, LANGFUSE_RELEASE, LANGFUSE_ENVIRONMENT, LANGFUSE_SAMPLE_RATE, LANGFUSE_FLUSH_AT/FLUSH_INTERVAL/QUEUE_SIZE/REQUEST_TIMEOUT/DEBUG는 튜닝 항목입니다. --profile langfuse 자체 호스팅 스택에는 LANGFUSE_SALT, LANGFUSE_ENCRYPTION_KEY, LANGFUSE_NEXTAUTH_SECRET, LANGFUSE_INIT_*(첫 시작 시 조직/프로젝트/관리자 자동 생성) 등이 추가로 있습니다. .env.example I1/I2 섹션을 참고하세요.
선택 서비스: SearXNG와 MCP Server
이 두 변수 그룹은 해당 compose profile을 활성화할 때만 필요하며, 주 서비스와 독립적입니다.
SearXNG(자체 호스팅 메타 검색, --profile searxng / full):
| 이름 | 기본값 | 설명 |
|---|---|---|
SEARXNG_PORT | 8888 | 호스트 포트 |
SEARXNG_BIND | 127.0.0.1 | 기본적으로 로컬에서만 수신합니다. WeKnora에 포함된 설정은 SearXNG 자체의 속도 제한을 끕니다(켜면 백엔드 요청이 제한됨). 따라서 LAN에 직접 노출하면 안 됩니다. 꼭 공개해야 한다면 명시적으로 0.0.0.0으로 바꾸고 직접 보안을 강화하세요 |
SEARXNG_SECRET | 비어 있음 | 진입점 스크립트가 이 값으로 settings.yml의 secret_key를 교체합니다. 외부 공개 시 반드시 설정해야 합니다 |
SearXNG를 자체 호스팅할 때는 127.0.0.1을 SSRF_WHITELIST에 추가해야 합니다. 그렇지 않으면 백엔드의 SSRF 방어가 로컬 주소를 차단합니다. 사용법은 인터넷 검색과 웹페이지 수집을 참고하세요.
MCP Server(WeKnora를 Claude Desktop 등의 MCP 클라이언트에 노출, --profile full):
| 이름 | 기본값 | 설명 |
|---|---|---|
WEKNORA_API_KEY | 비어 있음 | mcp-server가 WeKnora REST를 호출할 때 사용하는 Key. '설정 → API Keys'에서 생성 |
MCP_SERVER_AUTH_TOKEN | 비어 있음 | HTTP/SSE 전송에서 필수. 없으면 프로세스가 시작을 거부합니다. 클라이언트는 Authorization: Bearer로 전달합니다 |
WEKNORA_CHAT_TIMEOUT | 300 | WeKnora REST 호출의 읽기 타임아웃(초) |
WEKNORA_VERIFY_SSL | true | 백엔드 TLS 인증서 검증 여부. 자체 서명 인증서는 false 설정 가능 |
MCP_ALLOWED_UPLOAD_DIRS | 비어 있음 | 업로드를 허용할 디렉터리 목록(쉼표로 구분). 비어 있으면 파일 업로드 도구 비활성화 |
전체 설명은 MCP 연동을 참고하세요.
config/prompt_templates/: 프롬프트 템플릿
Prompt 종류마다 YAML 파일 하나를 사용하며, 공통 구조는 templates: 목록입니다. 개별 템플릿 필드(PromptTemplate 구조체, internal/config/config.go):
| 필드 | 설명 |
|---|---|
id | 고유 ID. config.yaml의 *_prompt_id, 내장 Agent의 system_prompt_id, 유형 프리셋에서 참조 |
name / description | 표시 이름과 설명 |
content | 시스템 측 Prompt 본문(모든 템플릿에 필수) |
user | 사용자 측 Prompt(system+user 쌍 템플릿에서만 사용, 예: rewrite, keywords_extraction) |
default | 해당 종류의 기본 템플릿 여부 |
mode | 하위 유형 구분(예: fallback의 model은 모델 대체 답변 prompt를 의미) |
has_knowledge_base / has_web_search | 템플릿 적용 시나리오 표시 |
i18n | 다국어 name/description(키는 zh-CN 같은 locale) |
파일별 용도와 포함된 템플릿 ID:
| 파일 | 용도 | 템플릿 ID |
|---|---|---|
system_prompt.yaml | 질의응답 시스템 Prompt(quick-answer / RAG) | default_kb(기본값), expert_assistant, customer_service, technical_support, pure_chat, web_search_assistant |
context_template.yaml | 검색 결과를 문맥으로 구성하는 템플릿 | default_context, detailed_context, simple_context, qa_context |
rewrite.yaml | 다중 턴 쿼리 재작성(content+user 쌍) | default_rewrite, standard_rewrite, strict_rewrite |
fallback.yaml | 일치 결과가 없을 때 대체 답변(고정 응답 + mode:"model" 모델 대체 답변) | default_fallback, polite_fallback, brief_fallback, model_fallback, default_fallback_prompt |
generate_session_title.yaml | 세션 제목 생성 | default_session_title |
generate_summary.yaml | 문서 요약 생성 | default_summary |
generate_questions.yaml | 문서 사전 질문 생성 | default_generate_questions |
keywords_extraction.yaml | 키워드 추출 | default_keywords_extraction |
graph_extraction.yaml | 그래프 엔터티/관계 추출 | default_extract_entities, default_extract_relationships |
agent_system_prompt.yaml | Agent(smart-reasoning) 시스템 Prompt | pure_agent, progressive_rag_agent, data_analyst, wiki_researcher, wiki_fixer, hybrid_rag_wiki_agent |
intent_prompts.yaml | 의도 라우팅용 의도별 시스템 Prompt(템플릿 ID = 의도 값) | greeting, chitchat, follow_up, image_only, summarize, web_search, doc_only |
사용자 정의 방법: 템플릿의 content를 직접 편집하거나 새 템플릿 항목을 추가한 뒤 config.yaml의 해당 *_prompt_id를 새 ID로 바꿉니다. 재시작하면 적용됩니다(compose는 ./config/config.yaml을 마운트하며, 템플릿 디렉터리는 이미지/마운트에 포함됩니다). ID를 찾을 수 없으면 시작 로그에 Warning: xxx_prompt_id not found가 출력됩니다.
config/agent_type_presets.yaml: Agent 유형 프리셋
smart-reasoning 모드의 사용자 정의 Agent에 한 번에 값을 미리 채우는 기능을 제공합니다. 각 프리셋(AgentTypePresetEntry, internal/types/agent_type_preset.go)은 id, i18n(다국어 label/description), config(미리 채울 값, 제로 값은 적용되지 않음), 선택적 kb_filter(선택 가능한 지식 베이스를 제한하는 기능 조건 any_of / all_of / none_of, 기능 이름: vector, keyword, wiki, graph, faq)를 포함합니다. 프런트엔드는 GET /agents/type-presets로 읽습니다.
다섯 가지 내장 프리셋:
| id | 시스템 Prompt | 도구 허용 목록 | 비고 |
|---|---|---|---|
rag-qa | progressive_rag_agent | knowledge_search, grep_chunks, list_knowledge_chunks, get_document_info | temperature 0.7, max_iterations 30, FAQ 우선 |
wiki-qa | wiki_researcher | wiki_search, wiki_read_page, wiki_read_source_doc, wiki_flag_issue | Wiki가 활성화된 지식 베이스 필요 |
hybrid-rag-wiki | hybrid_rag_wiki_agent | Wiki + RAG 도구 전체 | max_iterations 40, 가장 유연한 프리셋 |
data-analysis | data_analyst | data_schema, data_analysis | temperature 0.3, kb_filter: none_of: [faq], csv/xlsx 지원 |
custom | 없음 | 미리 채우지 않음 | 전체 수동 설정 |
config/builtin_agents.yaml: 내장 Agent
시스템과 함께 배포되고 모든 테넌트에 표시되는 Agent를 정의합니다(BuiltinAgentEntry, internal/types/builtin_agent_config.go). 각 항목은 id, avatar, is_builtin: true, i18n(default/zh-CN/zh-TW/ja-JP/ko-KR의 이름과 설명), 전체 config(CustomAgentConfig)를 포함합니다. 파일에는 다섯 개의 Agent가 내장되어 있습니다.
builtin-quick-answer:agent_mode: quick-answer,system_prompt_id: default_kb와context_template_id: default_context를 참조하며, 전체 검색 매개변수(embedding_top_k: 10,vector_threshold: 0.5,rerank_threshold: 0.3, FAQ 직접 답변 임계값 0.9 등)를 포함합니다.builtin-smart-reasoning:agent_mode: smart-reasoning,agent_type: rag-qa,max_iterations: 50.builtin-data-analyst,builtin-wiki-researcher,builtin-wiki-fixer: 각각 표 분석과 Wiki 시나리오를 위한 에이전트입니다.
config의 system_prompt_id는 시작 시 resolveBuiltinAgentPromptIDs가 agent_system_prompt.yaml의 실제 내용으로 해석합니다. 이 파일을 수정하고 재시작하면 내장 Agent 동작을 조정할 수 있습니다.
config/builtin_models.yaml.example: 선언형 내장 모델
config/builtin_models.yaml로 복사하거나 BUILTIN_MODELS_CONFIG로 경로를 지정하면, 내부 항목이 매번 시작할 때 models 테이블에 기록되고 is_builtin=true로 표시되어 모든 테넌트에 보입니다(compose에서 - ./config/builtin_models.yaml:/app/config/builtin_models.yaml:ro 마운트 행의 주석을 해제). 형식:
builtin_models:
- id: builtin-llm-default # 고정 ID, 반복 시작 시 ID를 기준으로 멱등 업데이트
type: KnowledgeQA # KnowledgeQA | Embedding | Rerank | VLLM | ASR
source: remote # remote(기본값) | local
is_default: true # 해당 유형의 기본 모델로 설정할지 여부
name: ${LLM_MODEL_NAME} # 문자열 필드는 모두 ${ENV} 참조 지원(.env는 env_file을 통해 컨테이너에 주입)
parameters:
base_url: ${LLM_BASE_URL}
api_key: ${LLM_API_KEY}
provider: ${LLM_PROVIDER} # openai | generic | aliyun | moonshot | ...
embedding_parameters: # Embedding 유형 전용
dimension: 1536
truncate_prompt_tokens: 0참고: 설정되지 않은 ${ENV}는 설정 오류를 드러내기 위해 리터럴로 유지됩니다. 문자열이 아닌 필드(type, source, is_default, dimension 등)는 리터럴 값으로 작성해야 합니다. 파일에서 항목을 삭제해도 데이터베이스에서 자동 삭제되지 않으므로 수동으로 정리해야 합니다.
설정 우선순위 요약
같은 의미의 설정에 대한 적용 우선순위는 데이터베이스 system_settings(테이블에 등록된 키만) > 환경 변수 > config.yaml > 코드 내장 기본값입니다. 테넌트/지식 베이스 수준의 설정(RetrievalConfig, ChunkingConfig 등, 데이터베이스에 저장)은 런타임에 전역 기본값을 재정의합니다. .env를 수정한 뒤에는 컨테이너를 재시작해야 합니다(docker compose up -d app). 개발 모드의 air 핫 리로드는 .env를 다시 읽지 않으므로 dev 스크립트를 재시작해야 합니다.