structverify 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- structverify/__init__.py +83 -0
- structverify/adaptation/__init__.py +0 -0
- structverify/adaptation/adapter_trainer.py +341 -0
- structverify/adaptation/feedback_store.py +31 -0
- structverify/adaptation/kosis_crawler.py +317 -0
- structverify/adaptation/sample_builder.py +149 -0
- structverify/adaptation/synthetic_generator.py +320 -0
- structverify/adaptation/update_embeddings.py +178 -0
- structverify/agent/__init__.py +21 -0
- structverify/agent/builder_agent.py +226 -0
- structverify/agent/conformance_agent.py +171 -0
- structverify/agent/dependency_planner.py +151 -0
- structverify/agent/indexing_agent.py +153 -0
- structverify/agent/indexing_planner.py +169 -0
- structverify/agent/integration_example.py +182 -0
- structverify/agent/loop.py +1165 -0
- structverify/agent/memory.py +207 -0
- structverify/agent/planner.py +817 -0
- structverify/agent/prompts/__init__.py +15 -0
- structverify/agent/prompts/planner_prompts.py +219 -0
- structverify/agent/prompts/reflect_prompts.py +387 -0
- structverify/agent/reflect.py +227 -0
- structverify/agent/runtime_agent.py +1272 -0
- structverify/agent/schemas.py +262 -0
- structverify/agent/source_profiler.py +229 -0
- structverify/agent/tools/__init__.py +64 -0
- structverify/agent/tools/base.py +222 -0
- structverify/agent/tools/calculate.py +244 -0
- structverify/agent/tools/catalog_search.py +859 -0
- structverify/agent/tools/deep_explore.py +293 -0
- structverify/agent/tools/explore_catalog.py +423 -0
- structverify/agent/tools/fetch_evidence.py +922 -0
- structverify/agent/tools/finish.py +423 -0
- structverify/agent/tools/meta_explore.py +267 -0
- structverify/agent/tools/query_rewriter.py +134 -0
- structverify/agent/tools/read_original.py +144 -0
- structverify/agent/tools/replan.py +365 -0
- structverify/agent/workspace.py +958 -0
- structverify/api.py +804 -0
- structverify/config/default.yaml +350 -0
- structverify/core/__init__.py +0 -0
- structverify/core/config_loader.py +30 -0
- structverify/core/pipeline.py +280 -0
- structverify/core/schemas.py +362 -0
- structverify/detection/__init__.py +26 -0
- structverify/detection/_config.py +163 -0
- structverify/detection/_llm.py +24 -0
- structverify/detection/candidate/__init__.py +1 -0
- structverify/detection/candidate/heuristic.py +60 -0
- structverify/detection/candidate/llm.py +51 -0
- structverify/detection/candidate_scorer.py +81 -0
- structverify/detection/claim_detector.py +164 -0
- structverify/detection/claims/__init__.py +1 -0
- structverify/detection/claims/worthiness.py +142 -0
- structverify/detection/domain/__init__.py +1 -0
- structverify/detection/domain/classify.py +84 -0
- structverify/detection/domain/preview.py +36 -0
- structverify/detection/domain/registry.py +99 -0
- structverify/detection/domain_classifier.py +75 -0
- structverify/detection/prompts/__init__.py +1 -0
- structverify/detection/prompts/candidate.py +38 -0
- structverify/detection/prompts/claim_worthiness.py +48 -0
- structverify/detection/prompts/domain.py +41 -0
- structverify/detection/prompts/schema.py +508 -0
- structverify/detection/prompts_loader.py +167 -0
- structverify/detection/schema/__init__.py +1 -0
- structverify/detection/schema/expand.py +83 -0
- structverify/detection/schema/induce.py +441 -0
- structverify/detection/schema/regenerate.py +162 -0
- structverify/detection/schema/temporal_hints.py +130 -0
- structverify/detection/schema/validate.py +193 -0
- structverify/detection/schema_inductor.py +112 -0
- structverify/detection/synthetic_generator.py +270 -0
- structverify/explanation/__init__.py +0 -0
- structverify/explanation/_config.py +18 -0
- structverify/explanation/_llm.py +25 -0
- structverify/explanation/explainer.py +183 -0
- structverify/explanation/fallback.py +29 -0
- structverify/explanation/formatters.py +75 -0
- structverify/explanation/prompts/__init__.py +1 -0
- structverify/explanation/prompts/match.py +27 -0
- structverify/explanation/prompts/mismatch.py +20 -0
- structverify/explanation/prompts/multihop.py +16 -0
- structverify/explanation/prompts/unverifiable.py +17 -0
- structverify/graph/__init__.py +0 -0
- structverify/graph/claim_graph.py +226 -0
- structverify/graph/document_graph.py +487 -0
- structverify/graph/graph_builder.py +238 -0
- structverify/graph/graph_multihop.py +335 -0
- structverify/graph/graph_store.py +281 -0
- structverify/graph/provenance.py +52 -0
- structverify/memory/__init__.py +44 -0
- structverify/memory/agent_memory.py +142 -0
- structverify/memory/embedder.py +69 -0
- structverify/memory/exemplar_store.py +241 -0
- structverify/memory/normalizer.py +91 -0
- structverify/memory/schema.py +119 -0
- structverify/memory/storage/__init__.py +29 -0
- structverify/memory/storage/jsonl_store.py +117 -0
- structverify/memory/working_memory.py +370 -0
- structverify/preprocessing/Dockerfile.scraper +27 -0
- structverify/preprocessing/__init__.py +0 -0
- structverify/preprocessing/extractor.py +574 -0
- structverify/preprocessing/pdf/__init__.py +16 -0
- structverify/preprocessing/pdf/fields.py +95 -0
- structverify/preprocessing/pdf/markdown.py +107 -0
- structverify/preprocessing/pdf/models.py +34 -0
- structverify/preprocessing/pdf/ocr.py +172 -0
- structverify/preprocessing/pdf/pipeline.py +74 -0
- structverify/preprocessing/pdf/reader.py +119 -0
- structverify/preprocessing/pdf/scoring.py +61 -0
- structverify/preprocessing/scraper_sandbox.py +561 -0
- structverify/preprocessing/segmenter.py +48 -0
- structverify/preprocessing/sir_builder.py +240 -0
- structverify/progress.py +591 -0
- structverify/retrieval/__init__.py +0 -0
- structverify/retrieval/base.py +208 -0
- structverify/retrieval/base_connector.py +85 -0
- structverify/retrieval/catalog_ranker.py +300 -0
- structverify/retrieval/catalog_search.py +583 -0
- structverify/retrieval/chunking.py +92 -0
- structverify/retrieval/custom_csv_source.py +386 -0
- structverify/retrieval/custom_db_source.py +396 -0
- structverify/retrieval/custom_docs_source.py +152 -0
- structverify/retrieval/dimension_resolver.py +281 -0
- structverify/retrieval/evidence_subgraph.py +63 -0
- structverify/retrieval/kosis_connector.py +1192 -0
- structverify/retrieval/kosis_relevance.py +142 -0
- structverify/retrieval/kosis_source.py +1541 -0
- structverify/retrieval/query_builder.py +72 -0
- structverify/retrieval/registry.py +133 -0
- structverify/retrieval/relevance_judge.py +141 -0
- structverify/retrieval/row_matcher.py +267 -0
- structverify/storage/__init__.py +0 -0
- structverify/storage/db_manager.py +157 -0
- structverify/storage/dwh_manager.py +92 -0
- structverify/storage/init_db.py +99 -0
- structverify/storage/raw_storage.py +29 -0
- structverify/training/__init__.py +26 -0
- structverify/training/curator.py +124 -0
- structverify/training/dataset.py +134 -0
- structverify/training/doctor.py +99 -0
- structverify/training/evalgate.py +96 -0
- structverify/training/generate.py +101 -0
- structverify/training/loop.py +116 -0
- structverify/training/recipe/train_mlx.py +99 -0
- structverify/training/recipe/train_qlora.py +104 -0
- structverify/training/tasks.py +79 -0
- structverify/utils/__init__.py +0 -0
- structverify/utils/embedding_client.py +248 -0
- structverify/utils/llm_client.py +809 -0
- structverify/utils/logger.py +81 -0
- structverify/verification/__init__.py +0 -0
- structverify/verification/_config.py +45 -0
- structverify/verification/adapters.py +405 -0
- structverify/verification/conformance.py +117 -0
- structverify/verification/decide_verdict.py +216 -0
- structverify/verification/decide_verdict_agent.py +454 -0
- structverify/verification/growth_diff.py +267 -0
- structverify/verification/row_match.py +345 -0
- structverify/verification/units.py +64 -0
- structverify/verification/verdict_thresholds.py +232 -0
- structverify/verification/verifier.py +84 -0
- structverify-0.3.0.dist-info/METADATA +903 -0
- structverify-0.3.0.dist-info/RECORD +168 -0
- structverify-0.3.0.dist-info/WHEEL +5 -0
- structverify-0.3.0.dist-info/licenses/LICENSE +21 -0
- structverify-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def is_table_relevant(indicator: str, table_name: str) -> bool:
|
|
5
|
+
"""
|
|
6
|
+
[v5] indicator와 테이블명이 같은 분야인지 키워드 검사.
|
|
7
|
+
LLM 미사용 — 키워드 겹침 + 도메인 그룹 매칭 (빠름).
|
|
8
|
+
|
|
9
|
+
"연평균기온" vs "기술개발 성과" → False
|
|
10
|
+
"연평균기온" vs "종관기상 평년값" → True
|
|
11
|
+
"평균 최저기온" vs "고온 일수 노출" → True (기온 그룹)
|
|
12
|
+
"시가총액" vs "산업별 취업자" → False
|
|
13
|
+
|
|
14
|
+
[박재윤 - 2026-05-14]: 국가 불일치 체크 추가
|
|
15
|
+
indicator에 외국 국가명 있는데 테이블이 국내 통계면 → False
|
|
16
|
+
|
|
17
|
+
[박재윤 - 2026-05-18]: 세부 대상 불일치 차단
|
|
18
|
+
전체 사망자 indicator인데 영아사망 테이블 매칭되는 문제 방지
|
|
19
|
+
|
|
20
|
+
[박재윤 - 2026-05-18]: UN/IMF 국제 데이터 테이블 차단
|
|
21
|
+
"""
|
|
22
|
+
import re
|
|
23
|
+
|
|
24
|
+
if not indicator or not table_name:
|
|
25
|
+
return True
|
|
26
|
+
|
|
27
|
+
ind_lower = indicator.lower()
|
|
28
|
+
tbl_lower = table_name.lower()
|
|
29
|
+
|
|
30
|
+
# [박재윤 - 2026-05-14]: 국가 불일치 체크
|
|
31
|
+
_FOREIGN_COUNTRIES = {"미국", "일본", "중국", "독일", "영국", "유럽", "프랑스", "캐나다"}
|
|
32
|
+
_FOREIGN_TABLE_MARKERS = {"국제", "해외", "외국", "세계"}
|
|
33
|
+
foreign_in_indicator = any(c in ind_lower for c in _FOREIGN_COUNTRIES)
|
|
34
|
+
foreign_in_table = any(c in tbl_lower for c in _FOREIGN_COUNTRIES | _FOREIGN_TABLE_MARKERS)
|
|
35
|
+
if foreign_in_indicator and not foreign_in_table:
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
# [박재윤 - 2026-05-18]: UN/IMF 국제 데이터 테이블 차단
|
|
39
|
+
_INTERNATIONAL_MARKERS = {"un ", "imf ", "oecd ", "세계은행", "국제연합"}
|
|
40
|
+
if any(m in tbl_lower for m in _INTERNATIONAL_MARKERS):
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
# [박재윤 - 2026-05-14]: 장래 추계 테이블 차단
|
|
44
|
+
_FORECAST_TABLE_MARKERS = {"장래", "추계", "전망"}
|
|
45
|
+
if any(r in tbl_lower for r in _FORECAST_TABLE_MARKERS):
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
# [박재윤 - 2026-05-14]: 해외 지역명 체크 추가
|
|
49
|
+
_REGION_MARKERS = {"남부·동남아시아", "동남아시아", "동북아시아", "중앙아시아",
|
|
50
|
+
"아프리카", "중동", "남미", "북미", "오세아니아", "서남아시아"}
|
|
51
|
+
region_in_table = any(r in tbl_lower for r in _REGION_MARKERS)
|
|
52
|
+
if not foreign_in_indicator and region_in_table:
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
# [박재윤 - 2026-05-18]: 세부 대상 불일치 차단
|
|
56
|
+
# 전체 사망자/출생아 indicator인데 영아·신생아 테이블 매칭되는 문제
|
|
57
|
+
_SPECIFIC_SCOPE_MARKERS = {"영아", "신생아", "모성"}
|
|
58
|
+
table_is_specific = any(m in tbl_lower for m in _SPECIFIC_SCOPE_MARKERS)
|
|
59
|
+
if table_is_specific:
|
|
60
|
+
ind_has_specific = any(m in ind_lower for m in _SPECIFIC_SCOPE_MARKERS)
|
|
61
|
+
if not ind_has_specific:
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
stopwords = {
|
|
65
|
+
"통계", "현황", "조사", "결과", "항목", "지표", "전체", "기타",
|
|
66
|
+
"관련", "변화", "추이", "비교", "분류", "지점별", "행정구역별",
|
|
67
|
+
"성별", "연령별", "시도별", "시도", "연도별", "월별",
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
def _tokens(text: str) -> set[str]:
|
|
71
|
+
words = set(re.split(r'[\s·,/()()\-_]+', text.lower()))
|
|
72
|
+
return {w for w in words if len(w) >= 2 and w not in stopwords}
|
|
73
|
+
|
|
74
|
+
ind_tokens = _tokens(indicator)
|
|
75
|
+
tbl_tokens = _tokens(table_name)
|
|
76
|
+
|
|
77
|
+
# 1) 직접 키워드 겹침 (2글자 이상 토큰)
|
|
78
|
+
overlap = ind_tokens & tbl_tokens
|
|
79
|
+
if overlap:
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
# 2) 부분 문자열 포함 (indicator 토큰이 테이블명에 포함)
|
|
83
|
+
tbl_lower = table_name.lower()
|
|
84
|
+
for tok in ind_tokens:
|
|
85
|
+
if len(tok) >= 3 and tok in tbl_lower:
|
|
86
|
+
return True
|
|
87
|
+
|
|
88
|
+
# 3) 도메인 키워드 그룹 — 같은 그룹이면 관련 있음
|
|
89
|
+
_GROUPS = [
|
|
90
|
+
# 기상/기후
|
|
91
|
+
{"기온", "기상", "기후", "날씨", "온도", "폭염", "한파", "평균기온",
|
|
92
|
+
"연평균", "최저기온", "최고기온", "강수", "강우", "습도", "종관"},
|
|
93
|
+
# 인구/가구
|
|
94
|
+
{"인구", "출산", "사망", "고령", "청년", "세대", "가구", "출생", "혼인"},
|
|
95
|
+
# 고용/노동
|
|
96
|
+
{"고용", "실업", "취업", "임금", "근로", "노동", "쉬었음", "경제활동",
|
|
97
|
+
"일자리", "실업률", "고용률"},
|
|
98
|
+
# 경제/산업
|
|
99
|
+
{"경제", "성장", "물가", "소비", "생산", "수출", "수입", "무역", "gdp"},
|
|
100
|
+
# 주식/금융
|
|
101
|
+
{"주가", "시총", "코스피", "코스닥", "시가총액", "금리", "환율", "주식"},
|
|
102
|
+
# 교육
|
|
103
|
+
{"교육", "학교", "학생", "진학", "졸업", "입학"},
|
|
104
|
+
# 보건/의료
|
|
105
|
+
{"의료", "건강", "질환", "사망률", "병원", "보건"},
|
|
106
|
+
# 환경
|
|
107
|
+
{"환경", "오염", "대기", "수질", "폐기물", "탄소", "에너지"},
|
|
108
|
+
# 농업
|
|
109
|
+
{"농업", "농가", "농림", "수확", "경작", "과수"},
|
|
110
|
+
# 부동산/건설
|
|
111
|
+
{"주택", "건설", "부동산", "아파트", "토지", "분양"},
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
ind_lower = indicator.lower()
|
|
115
|
+
for group in _GROUPS:
|
|
116
|
+
ind_hit = any(kw in ind_lower for kw in group)
|
|
117
|
+
tbl_hit = any(kw in tbl_lower for kw in group)
|
|
118
|
+
if ind_hit and tbl_hit:
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
_OVERSEAS_MARKERS = (
|
|
125
|
+
"동북·중앙아시아", "남부·동남아시아", "중앙아시아", "동남아시아",
|
|
126
|
+
"북아메리카", "남아메리카", "유럽", "아프리카", "오세아니아",
|
|
127
|
+
"oecd", "g20", "세계", "국제", "해외",
|
|
128
|
+
)
|
|
129
|
+
_SPECIALIZED_MARKERS = (
|
|
130
|
+
"해양기상", "항공기상", "고층기상", "등표", "레윈존데",
|
|
131
|
+
"공항기상", "부이", "방재기상",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def is_overseas_mismatch(table_name: str, claim_query: str) -> bool:
|
|
135
|
+
stat_lower = table_name.lower()
|
|
136
|
+
claim_lower = claim_query.lower()
|
|
137
|
+
return any(kw in stat_lower and kw not in claim_lower for kw in _OVERSEAS_MARKERS)
|
|
138
|
+
|
|
139
|
+
def is_specialized_mismatch(table_name: str, claim_query: str) -> bool:
|
|
140
|
+
stat_lower = table_name.lower()
|
|
141
|
+
claim_lower = claim_query.lower()
|
|
142
|
+
return any(kw in stat_lower and kw not in claim_lower for kw in _SPECIALIZED_MARKERS)
|