카드 카탈로그(negodata)가 Q-table action space 를 정의하는 정본이 되고, 카드 변경이
config 수정·학습 손실 없이 agent 에 자동 반영되는 고리를 완성.
- action space 정리: 카탈로그 전체(NGC-001~011, 11장) 고정, 견적별 선택은 축소가 아니라
available_mask(_selection_mask) 로 처리 — action_id↔카드 대응을 견적마다 일정하게 유지해
Q-table 학습 일관성 보장. 구 인덱스 방식(selected[action_id]) 폐기.
- ① 카탈로그 DB 정본화: action_mapping.type=db 면 registry 가 card.nego_cards(user_id NULL,
number 순) 조회로 action_to_card 동적 구성(파일은 폴백). port/adapter(card_catalog_*).
_base=type:db. → negodata 카드 추가/삭제 시 config 수정 불필요.
- ② 차원 변경 학습 보존 마이그레이션: migrate_active_version_dim — 겹치는 셀 복사
(append/truncate 안전) + 새 카드 fresh. model_store.load 가 차원 불일치 시 호출.
- ③ reload 엔드포인트: /v1/catalog-refresh(테넌트) · /v1/catalog-refresh-all(전역, 화이트리스트).
- ④ 브랜드: company_profile_repo — 자동 온보딩 고객사(company_id UUID)는
company.companies.name 으로 {company_name} 채움. 데모 테넌트는 파일 유지.
- 크로스서비스: negodata card_service 가 공용 nego 카드 변경 시 agent_notify 로 전역 리로드 알림
(best-effort, is_test skip). config 에 agent_base_url.
- 하니스 episodes 400→600(action 11 수렴). 테스트 갱신·추가로 agent 98/98.
알려진 갭(후속): per-company 카탈로그 스코프(회사 카드도 action space 포함), 카탈로그 중간
삭제 시 카드번호 기반 마이그레이션.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
86 lines
3.1 KiB
YAML
86 lines
3.1 KiB
YAML
# 공유 베이스 정책 (계획서 D). 신규 테넌트 cold-start 의 기준값.
|
||
# 모든 값은 우리 플랫폼의 중립 기본값이다(CLEANROOM.md). 특정 고객 운영값 복제 아님.
|
||
# 실제 운영값은 각 테넌트 YAML/DB 에서 주입한다. 차원 개수만 기능적 설계, 값/라벨은 우리 선택.
|
||
tenant_id: _base
|
||
inherits_base: false # 베이스는 자기 자신을 상속하지 않음
|
||
name: "Shared Base Policy"
|
||
|
||
state:
|
||
revenue:
|
||
thresholds: [10000000, 50000000] # 플랫폼 중립 기본 구간
|
||
weights: [0.3, 0.6, 1.0]
|
||
descriptions: ["low", "mid", "high"]
|
||
distribution:
|
||
code_map: {A: 0, B: 1, C: 2} # 중립 예시 코드(테넌트가 자사 코드로 오버라이드)
|
||
weights: [0.3, 0.6, 1.0]
|
||
descriptions: ["channel_a", "channel_b", "channel_c"]
|
||
partner:
|
||
weights: [0.5, 1.0, 0.3] # single, multiple, none
|
||
descriptions: ["single", "multiple", "none"]
|
||
acceptance:
|
||
thresholds: [0.03, 0.09]
|
||
weights: [0.3, 0.6, 1.0]
|
||
descriptions: ["low", "mid", "high"]
|
||
price_zone:
|
||
weights: [1.0, 0.5] # at_or_below_anchor(우선협상), above_anchor(협상지속)
|
||
descriptions: ["at_or_below_anchor", "above_anchor"]
|
||
# state_space_size 는 차원 곱으로 자동 산출: 3×3×3×3×2 = 162
|
||
|
||
reward:
|
||
beta: 0.2
|
||
success_reward: 1.0
|
||
ongoing_reward: 0.0
|
||
failure_penalty: -0.5
|
||
penalty_lambda: 0.02
|
||
w1: 0.2
|
||
w2: 0.2
|
||
w3: 0.2
|
||
w4: 0.2
|
||
w5: 0.2
|
||
min_weight: 0.2
|
||
max_weight: 0.8
|
||
|
||
policy:
|
||
type: ucb
|
||
learning_rate: 0.1 # 표준 기본값
|
||
gamma: 0.95
|
||
params:
|
||
exploration_constant: 1.4142135623730951 # sqrt(2) — 표준 UCB 상수
|
||
epsilon: 1.0e-6
|
||
|
||
action_mapping:
|
||
# db: action_to_card 를 card.nego_cards 카탈로그(user_id NULL, number 순)에서 동적 구성 — 정본.
|
||
# 카드가 negodata 에서 추가/삭제되면 action space 가 자동 반영된다(config 수정 불필요).
|
||
# 아래 action_to_card 는 DB 카탈로그가 비어있을 때만 쓰는 폴백(정합용 스냅샷)이다.
|
||
# file: 아래 action_to_card 를 그대로 사용(데모/오프라인).
|
||
type: db
|
||
# [폴백] 카탈로그 11장(카드_기획문서 일반카드) 스냅샷 — action_id 0~10 ↔ NGC-001~NGC-011.
|
||
# Q-table action 차원 = 카탈로그 크기. 견적별 선택은 action space 축소가 아니라 available_mask 로 처리
|
||
# (선택 카드만 pickable) — action_id↔카드 대응을 견적마다 일정하게 유지해 학습 일관성 보장.
|
||
action_to_card:
|
||
"0": "NGC-001"
|
||
"1": "NGC-002"
|
||
"2": "NGC-003"
|
||
"3": "NGC-004"
|
||
"4": "NGC-005"
|
||
"5": "NGC-006"
|
||
"6": "NGC-007"
|
||
"7": "NGC-008"
|
||
"8": "NGC-009"
|
||
"9": "NGC-010"
|
||
"10": "NGC-011"
|
||
|
||
cards:
|
||
# file: scripts_cards.json(파일) 사용. backoffice_db: card.nego_cards.script(negodata 편집 정본)를
|
||
# 카드코드(action_to_card)로 조회, 없으면 파일 폴백. 테넌트가 자사 카드를 편집하면 backoffice_db 로 전환.
|
||
source_type: file
|
||
sync_interval_seconds: 300
|
||
connection: {}
|
||
|
||
llm:
|
||
enabled: false
|
||
|
||
resources:
|
||
language: ko
|
||
scripts_dir: resources
|