
    %~i#                        d Z ddlmZ ddlZddlZddlmZ ddlZddlm	Z	  ej                  e      ZdZ G d d      Zy)	uJ   벡터 DB 래퍼 — chromadb + sentence-transformers 기반 의미 검색    )annotationsN)Optional)SentenceTransformerz%paraphrase-multilingual-MiniLM-L12-v2c                  Z    e Zd ZdZdef	 	 	 	 	 ddZddZdddZddZddZ	ddZ
dd	Zy
)VectorStoreu+   인사이트의 벡터 DB 관리 및 검색insightsc                    t        j                  |      | _        t        |d      | _        | j                  j                  |ddi      | _        t        j                  d|||       y)	u   
        Args:
            db_path: chromadb 저장 경로 (예: /home/jay/projects/insuwiki/data/chroma_db/)
            collection_name: 컬렉션 이름
            model_name: sentence-transformers 모델명
        )pathcpu)devicez
hnsw:spacecosine)namemetadatauD   VectorStore 초기화 완료 — db_path=%s, collection=%s, model=%sN)	chromadbPersistentClient_clientr   _modelget_or_create_collection_collectionloggerinfo)selfdb_pathcollection_name
model_names       ]/home/jay/projects/insuwiki/.worktrees/task-2064-dev6/scripts/kakao_knowledge/vector_store.py__init__zVectorStore.__init__   sf      00g>)*UC<<@@ "H- A 
 	R		
    c                   |syg }g }g }|D ]  }|j                  dd      }|s't        j                  d|j                  dd             ?| j                  |      }||j                  dd      |j                  dd      t	        |j                  dd            |j                  dd      |j                  d	d
      |j                  dd      |j                  dd      |j                  dd      t        j                  |j                  dg       d      t        j                  |j                  dg       d      t        j                  |j                  dg       d      t        j                  |j                  dg       d      |j                  dd      |j                  dd      d}|j                  |       |j                  |       |j                  |        |sy| j                  j                  |      j                         }	| j                  j                  ||	||       t        j                  dt        |             t        |      S )u  인사이트 리스트를 벡터 DB에 추가.

        각 인사이트의 title + summary + key_points를 결합하여 임베딩 텍스트 생성.
        이미 존재하는 ID는 업데이트(upsert).

        Returns:
            추가/갱신된 인사이트 수
        r   id u!   ID 없는 인사이트 스킵: %stitlecategorytypesummary
confidencemediumexpertsource_datesource_chat
key_pointsF)ensure_asciiparticipantsrelated_topicstagsquestionanswer)r    r"   r#   r$   r%   r&   r(   r)   r*   r+   r-   r.   r/   r0   r1   )ids
embeddings	metadatas	documentsu    VectorStore upsert 완료: %d건)getr   warning_build_embed_textstrjsondumpsappendr   encodetolistr   upsertr   len)
r   r   r2   textsr4   insight
insight_id
embed_textr   r3   s
             r   add_insightszVectorStore.add_insights2   s     "	 !	'G T2.JBGKKPWY[D\]//8J  Wb1#KK
B7GKK34";;y"5%kk,A!++h3&{{="=&{{="="jjKKb1 !%

KK3%! #'**KK 0"5E# 

7;;vr#:O#KK
B7!++h3+H0 JJz"LL$X&C!	'F [[''.557
!	 	  	
 	6CA3xr   c                X   | j                         dk(  rg S | j                  j                  |g      j                         d   }t	        || j                               }| j
                  j                  |g|ddg      }g }|j                  d      xs g g}|j                  d      xs g g}|d   }	|d   }
t        |	|
      D ]e  \  }}|j                  |j                  dd      |j                  dd      |j                  dd      t        |      |j                  d	d      d
       g |S )u   의미 기반 유사 인사이트 검색.

        Returns:
            [{"id": str, "title": str, "category": str, "distance": float, "summary": str}, ...]
        r   r4   	distances)query_embeddings	n_resultsincluder    r!   r"   r#   r%   )r    r"   r#   distancer%   )countr   r=   r>   minr   queryr6   zipr<   float)r   rN   top_kquery_embeddingrI   resultsoutputraw_metadatasraw_distancesmetadatas_listdistances_listmetadists                r   search_similarzVectorStore.search_similart   s/    ::<1I++,,eW5<<>qAtzz|,	""((-. +. ) 
  K08RDK08RD&q)&q)nn= 		JD$MM((4,!XXgr2 $R 8 %d#xx	26		 r   c                   	 | j                   j                  |gdg      }|j                  dg       }|sy|d   }|syt        |      }dD ]=  }|j                  |      }t        |t              s%	 t        j                  |      ||<   ? |S # t
        j                  t        f$ r g ||<   Y bw xY w# t        $ r!}t        j                  d||       Y d}~yd}~ww xY w)u   ID로 인사이트 조회r4   )r2   rJ   Nr   )r+   r-   r.   r/   u   get_by_id 오류 (id=%s): %s)r   r6   dict
isinstancer9   r:   loadsJSONDecodeError	TypeError	Exceptionr   debug)	r   rC   rS   r4   rY   result
list_fieldvalexcs	            r   	get_by_idzVectorStore.get_by_id   s    	&&**L$ + G  K4IQ<D$ZFV 0
jj,c3'0-1ZZ_z*	0 M !00)< 0-/z*0  	LL7SI	sE   3B1 B1 1B1 1B	B1 B.+B1 -B..B1 1	C:CCc                    | j                  |      }|y	 | j                  j                  |g       t        j	                  d|       y# t
        $ r!}t        j                  d||       Y d}~yd}~ww xY w)u   ID로 인사이트 삭제NF)r2   u   VectorStore 삭제 완료: %sTu   delete_by_id 오류 (id=%s): %s)rh   r   deleter   r   rb   r7   )r   rC   existingrg   s       r   delete_by_idzVectorStore.delete_by_id   so     >>*-	###5KK7D 	NN<j#N	s   3A
 
	A4A//A4c                6    | j                   j                         S )u!   저장된 인사이트 수 반환)r   rL   )r   s    r   rL   zVectorStore.count   s    %%''r   c                    |j                  dd      }|j                  dd      }|j                  dg       }dj                  d |D              }| d| d| j                         S )uv   인사이트에서 임베딩용 텍스트 생성.

        format: "{title} {summary} {' '.join(key_points)}"
        r"   r!   r%   r+    c              3  2   K   | ]  }t        |        y w)N)r9   ).0kps     r   	<genexpr>z0VectorStore._build_embed_text.<locals>.<genexpr>   s     "@r3r7"@s   )r6   joinstrip)r   rB   r"   r%   r+   key_points_texts         r   r8   zVectorStore._build_embed_text   si    
 GR(++i,[[r2
(("@Z"@@'!O#45;;==r   N)r   r9   r   r9   r   r9   )r   
list[dict]returnint)   )rN   r9   rQ   ry   rx   rw   )rC   r9   rx   zOptional[dict])rC   r9   rx   bool)rx   ry   )rB   r]   rx   r9   )__name__
__module____qualname____doc___DEFAULT_MODELr   rE   r[   rh   rl   rL   r8    r   r   r   r      sO    5
  *(	

 
 	
:@D#J6(	>r   r   )r   
__future__r   r:   loggingtypingr   r   sentence_transformersr   	getLoggerr|   r   r   r   r   r   r   <module>r      s=    P "     5			8	$8B> B>r   