agent(협상카드 강화학습)와 anchoring(구간별 자동 조정)이 쌓아온 결과를 볼 수 있는 화면이 없어 DB 를 직접 열어야 확인이 됐다. 두 축은 성격이 달라 한 화면에 섞지 않고 탭으로 나눈다. 백엔드(읽기 전용 — 값의 주인은 agent·anchoring): - crud/learning_crud.py: learning·anchoring 스키마 경량 조회(negodata ORM 미매핑 테이블) - services/learning_service.py + router/v1/learning: /v1/learning/cards · /anchoring 프론트: - 사이드바 '협상 학습'(/learning) 추가, 탭 = 협상카드 | 앵커링 - 협상카드: 학습 협상·기록·타결 비율 요약 + 카드별 사용/타결/평균 점수(0 기준 좌우 막대) - 앵커링: 구간별 현재 인하폭 + 조정 이력(표본·성공률·값 변화) 검증: 로컬 실협상 3건으로 데이터 생성 후 두 탭 실화면 확인, tsc·eslint 통과.
60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from pydantic import Field
|
|
|
|
from common.models.gmodel import Res_WebPacketProtocol, WebPacketProtocol
|
|
|
|
|
|
class LearningProtocol(WebPacketProtocol):
|
|
pass
|
|
|
|
|
|
class LearningKpi(LearningProtocol):
|
|
learned_sessions: int = 0 # 학습에 반영된 협상 수
|
|
records: int = 0 # 학습 기록 수(카드 선택 1회 = 1건)
|
|
settled_sessions: int = 0 # 그중 타결된 협상 수
|
|
settle_rate: float = 0.0 # 타결 비율
|
|
last_learned_at: Optional[datetime] = None
|
|
|
|
|
|
class CardPerformanceRow(LearningProtocol):
|
|
number: str # 카드번호(NGC-001 등)
|
|
name: Optional[str] = None
|
|
type: str = "nego" # nego | wild
|
|
used_sessions: int = 0 # 이 카드를 쓴 협상 수
|
|
uses: int = 0 # 총 사용 횟수
|
|
avg_reward: float = 0.0 # 평균 보상 — agent 가 협상 결과로 매긴 성적
|
|
settled_sessions: int = 0
|
|
settle_rate: float = 0.0 # 이 카드를 쓴 협상의 타결 비율
|
|
|
|
|
|
class AnchoringCell(LearningProtocol):
|
|
supplier_type: int = 0
|
|
supplier_type_label: str = "미지정"
|
|
price_range_index: int = 0 # 목표가 기준 가격대 구간
|
|
anchoring_value: float = 0.0 # 앵커링 인하폭(‰)
|
|
last_adjusted_at: Optional[datetime] = None
|
|
|
|
|
|
class AnchoringHistoryRow(LearningProtocol):
|
|
supplier_type_label: str = "미지정"
|
|
price_range_index: int = 0
|
|
value_before: float = 0.0
|
|
value_after: float = 0.0
|
|
sample_count: int = 0 # 조정 판단에 쓴 협상 표본 수
|
|
success_count: int = 0
|
|
success_rate: float = 0.0
|
|
created_at: Optional[datetime] = None
|
|
|
|
|
|
class Res_LearningStatus(Res_WebPacketProtocol):
|
|
kpi: LearningKpi = Field(default_factory=LearningKpi)
|
|
cards: list[CardPerformanceRow] = []
|
|
|
|
|
|
class Res_AnchoringStatus(Res_WebPacketProtocol):
|
|
cells: list[AnchoringCell] = []
|
|
history: list[AnchoringHistoryRow] = []
|
|
adjusted_count: int = 0
|