Task #56

KG Entity μ„€λͺ… μžλ™ 생성 β€” μ‹€ν–‰ 보고

μž‘μ—… λͺ…λ Ήμ–΄
[🟑 NORMAL] ## KG Entity μ„€λͺ… μžλ™ 생성 (qwen3:4b via Ollama) ### λͺ©ν‘œ KG의 Entity λ…Έλ“œ 쀑 summaryκ°€ μ—†λŠ” 26κ°œμ— λŒ€ν•΄ 둜컬 Ollama(qwen3:4b)둜 μ„€λͺ…을 μƒμ„±ν•˜κ³  Neo4j에 μ—…λ°μ΄νŠΈν•œλ‹€. ### λŒ€μƒ μ—”ν‹°ν‹° (US 쀑볡 6개 μ œμ™Έ) 1. Bulgaria (Location) 2. Circuit Breaker (Concept) 3. Class struggle (Concept) 4. Corporate Governance (Concept) 5. Democratic governance (Policy) 6. Foreign Investment (Concept) 7. Hanbok (Asset) 8. Hanji (Asset) 9. Historical materialism (Concept) 10. Iran-Israel war (Campaign) 11. Kazakh language (Concept) 12. Minab (Location) 13. Minister of Planning and Budget (Person - 직책) 14. No Kings Protests (Campaign) 15. President Jer (Person) 16. Quantum Computing (Asset) 17. Russian language (Concept) 18. Saudi military base (Location) 19. Ultra-imperialism (Concept) 20. cyber domains (Concept) 21. household debt (Concept) 22. labor environment (Concept) 23. like-minded nations (Organization) 24. liquefied natural gas (LNG) (Asset) 25. military domains (Concept) 26. myocardial infarction (Concept) ### μ‹€ν–‰ 방법 1. **Python 슀크립트 μž‘μ„±** (`/tmp/kg_enricher.py`): ```python import httpx import json from neo4j import GraphDatabase OLLAMA_API = "http://localhost:11434/api/chat" MODEL = "qwen3:4b" NEO4J_URI = "bolt://localhost:7687" NEO4J_USER = "neo4j" NEO4J_PASSWORD = "neo4j" # κΈ°λ³Έκ°’, μ‹€μ œμ™€ λ‹€λ₯Ό 수 있음 ENTITIES = [ ("Bulgaria", "Location"), ("Circuit Breaker", "Concept"), ("Class struggle", "Concept"), ("Corporate Governance", "Concept"), ("Democratic governance", "Policy"), ("Foreign Investment", "Concept"), ("Hanbok", "Asset"), ("Hanji", "Asset"), ("Historical materialism", "Concept"), ("Iran-Israel war", "Campaign"), ("Kazakh language", "Concept"), ("Minab", "Location"), ("Minister of Planning and Budget", "Person"), ("No Kings Protests", "Campaign"), ("President Jer", "Person"), ("Quantum Computing", "Asset"), ("Russian language", "Concept"), ("Saudi military base", "Location"), ("Ultra-imperialism", "Concept"), ("cyber domains", "Concept"), ("household debt", "Concept"), ("labor environment", "Concept"), ("like-minded nations", "Organization"), ("liquefied natural gas (LNG)", "Asset"), ("military domains", "Concept"), ("myocardial infarction", "Concept"), ] def query_ollama(name: str, entity_type: str) -> str: prompt = f"""λ‹€μŒ 엔티티에 λŒ€ν•΄ 2-3λ¬Έμž₯으둜 κ°„κ²°ν•˜κ²Œ μ„€λͺ…ν•΄μ€˜. μ§€μ •ν•™/μ •μΉ˜κ²½μ œν•™μ  λ§₯락을 μš°μ„ μ‹œν•  것. μ—”ν‹°ν‹°: {name} νƒ€μž…: {entity_type} μ„€λͺ… (ν•œκ΅­μ–΄, 2-3λ¬Έμž₯):""" response = httpx.post(OLLAMA_API, json={ "model": MODEL, "messages": [{"role": "user", "content": prompt}], "stream": False, "keep_alive": -1, "options": {"temperature": 0.3, "top_k": 20} }, timeout=60) return response.json()["message"]["content"].strip() def update_neo4j(name: str, summary: str, driver): with driver.session() as session: result = session.run( "MATCH (n:Entity {name: $name}) SET n.summary = $summary RETURN count(n) as updated", name=name, summary=summary ) return result.single()["updated"] def main(): driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD)) results = [] for name, etype in ENTITIES: print(f"처리 쀑: {name}...") try: summary = query_ollama(name, etype) updated = update_neo4j(name, summary, driver) print(f" βœ… {name}: {summary[:50]}... (λ…Έλ“œ {updated}개 μ—…λ°μ΄νŠΈ)") results.append({"name": name, "type": etype, "summary": summary, "updated": updated}) except Exception as e: print(f" ❌ {name}: {e}") results.append({"name": name, "type": etype, "error": str(e)}) driver.close() with open("/tmp/kg_enricher_results.json", "w") as f: json.dump(results, f, ensure_ascii=False, indent=2) print(f"\nμ™„λ£Œ: {len([r for r in results if 'summary' in r])}/{len(ENTITIES)}개 성곡") print("κ²°κ³Ό: /tmp/kg_enricher_results.json") if __name__ == "__main__": main() ``` 2. **μ‹€ν–‰**: ```bash cd / pip install neo4j httpx -q python /tmp/kg_enricher.py ``` 3. **Neo4j λΉ„λ°€λ²ˆν˜Έ 확인**: - ν™˜κ²½λ³€μˆ˜ `NEO4J_PASSWORD` 확인: `echo $NEO4J_PASSWORD` - Docker: `docker ps | grep neo4j` - μ—°κ²° μ‹€νŒ¨ μ‹œ λΉ„λ°€λ²ˆν˜Έ μ‘°μ • 4. **κ²°κ³Ό 확인**: - `/tmp/kg_enricher_results.json` 파일 좜λ ₯ - 성곡/μ‹€νŒ¨ 개수 보고 - μƒμ„±λœ summary μƒ˜ν”Œ 3개 좜λ ₯ 5. **KG 검증**: ```cypher MATCH (n:Entity) WHERE n.summary IS NOT NULL RETURN count(n) as enriched ``` ### μ™„λ£Œ ν›„ 보고 - μ„±κ³΅ν•œ μ—”ν‹°ν‹° 수 - μ‹€νŒ¨ν•œ ν•­λͺ©κ³Ό 이유 - μƒμ„±λœ summary μ˜ˆμ‹œ 3개 - Neo4j μ—…λ°μ΄νŠΈ 확인 κ²°κ³Ό