mirror of
https://github.com/NomaDamas/k-skill.git
synced 2026-06-24 02:04:11 +00:00
The fine-dust proxy now resolves natural-language region hints through city-level station lists and only returns a report when a single station can be justified. When the hint is ambiguous, the proxy returns a small candidate list so callers can retry with an exact station name instead of silently guessing. The skill guidance was updated to match that runtime contract: region hint first, then retry with stationName when candidate_stations are returned. Coordinate-centric guidance was removed from the primary skill surface so the default path stays lightweight and consistent with the live proxy behavior. Constraint: The current AirKorea key can access city-level and station-level measurement APIs but station-info lookups may still return 403 Constraint: Free-API proxy responses must stay safe to expose publicly, so ambiguous locations should not be auto-guessed Rejected: Auto-pick the first city-level station for unmatched district hints | hides ambiguity and returns misleading air-quality data Rejected: Keep coordinate-first language in the primary skill | no coordinate source exists in the default user flow Confidence: high Scope-risk: moderate Reversibility: clean Directive: Preserve the ambiguous_location contract; if you improve matching later, prefer evidence-backed narrowing over silent fallback guesses Tested: node --test scripts/skill-docs.test.js; npm run test --workspace k-skill-proxy; python3 -m unittest discover -s scripts -p test_fine_dust.py; live curl for ambiguous regionHint=광주 광산구 and exact stationName=우산동(광주) Not-tested: Broader region alias quality outside the manually checked examples
4.8 KiB
4.8 KiB
사용자 위치 미세먼지 조회 가이드
이 기능으로 할 수 있는 일
- 지역명/행정구역 힌트로 측정소 후보 찾기
- 단일 측정소 확정이 어려우면 후보 측정소 목록 반환
- 정확한 측정소명으로 재조회
- PM10, PM2.5, 등급, 조회 시각 요약
먼저 필요한 것
필요한 시크릿
클라이언트 기본값:
- 기본 external proxy URL:
https://k-skill-proxy.nomadamas.org KSKILL_PROXY_BASE_URL는 override 가 필요할 때만 사용
프록시 없이 direct fallback 으로 쓸 때만:
AIR_KOREA_OPEN_API_KEY
입력값
- 기본: 지역명/행정구역 힌트(
regionHint) - 재조회: 정확한 측정소명(
stationName)
기본 흐름
KSKILL_PROXY_BASE_URL가 있으면 먼저k-skill-proxy의/v1/fine-dust/reportendpoint 를 호출합니다.regionHint가 들어오면 프록시는 먼저 시도명을 추출하고,getCtprvnRltmMesureDnsty로 해당 시도 측정소 목록을 확보합니다.- region token 이 시도 내 실제 측정소명과 유일하게 대응하면 그 측정소로
getMsrstnAcctoRltmMesureDnsty를 호출합니다. - 단일 측정소 확정이 어려우면
ambiguous_location과candidate_stations를 반환합니다. - 클라이언트/사용자는 후보 중 정확한 측정소명으로 다시
/v1/fine-dust/report?stationName=...를 호출합니다. - PM10, PM2.5, 등급, 조회 시점/조회 시각을 함께 요약합니다.
프록시 예시:
SOPS_AGE_KEY_FILE="$HOME/.config/k-skill/age/keys.txt" \
sops exec-env "$HOME/.config/k-skill/secrets.env" \
'python3 scripts/fine_dust.py report --region-hint "서울 강남구" --json'
후보 반환 예시:
curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/fine-dust/report' \
--data-urlencode 'regionHint=광주 광산구'
정확한 측정소명 재조회:
curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/fine-dust/report' \
--data-urlencode 'stationName=우산동(광주)'
원본 AirKorea endpoint 형태를 거의 그대로 쓰고 싶으면 passthrough endpoint 도 사용할 수 있습니다. 별도 client API 는 불필요하고, 프록시가 serviceKey 만 서버에서 주입합니다.
curl -fsS --get 'https://k-skill-proxy.nomadamas.org/B552584/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty' \
--data-urlencode 'returnType=json' \
--data-urlencode 'numOfRows=1' \
--data-urlencode 'pageNo=1' \
--data-urlencode 'stationName=강남구' \
--data-urlencode 'dataTerm=DAILY' \
--data-urlencode 'ver=1.4'
예시
지역 기반 direct fallback:
SOPS_AGE_KEY_FILE="$HOME/.config/k-skill/age/keys.txt" \
sops exec-env "$HOME/.config/k-skill/secrets.env" \
'curl -sG "http://apis.data.go.kr/B552584/MsrstnInfoInqireSvc/getMsrstnList" \
--data-urlencode "serviceKey=${AIR_KOREA_OPEN_API_KEY}" \
--data-urlencode "returnType=json" \
--data-urlencode "numOfRows=50" \
--data-urlencode "pageNo=1" \
--data-urlencode "addr=서울 강남구"'
실시간 측정값:
SOPS_AGE_KEY_FILE="$HOME/.config/k-skill/age/keys.txt" \
sops exec-env "$HOME/.config/k-skill/secrets.env" \
'curl -sG "http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty" \
--data-urlencode "serviceKey=${AIR_KOREA_OPEN_API_KEY}" \
--data-urlencode "returnType=json" \
--data-urlencode "numOfRows=100" \
--data-urlencode "pageNo=1" \
--data-urlencode "stationName=중구" \
--data-urlencode "dataTerm=DAILY" \
--data-urlencode "ver=1.4"'
helper script 반복 검증:
python3 scripts/fine_dust.py report \
--station-file scripts/fixtures/fine-dust-stations.json \
--measurement-file scripts/fixtures/fine-dust-measurements.json \
--region-hint "서울 강남구"
fallback / 대체 흐름
- 지역명/행정구역을 먼저 받습니다
- 단일 측정소를 확정하지 못하면 후보 측정소 목록을 돌려줍니다
- 사용자는 후보 중 하나를 선택해
stationName으로 다시 조회합니다 - 측정소 목록 API가 403 이어도
getCtprvnRltmMesureDnsty와 측정소별 실측 API 조합으로 우회합니다
주의할 점
- 실시간 수치라 조회 시각을 같이 적어야 합니다
- PM10/PM2.5 값이
-이거나 비정상이면 등급도 함께 재확인합니다 - API 가
khaiGrade를 비워 보내면 통합대기등급은정보없음으로 표시합니다 - regionHint 는 자연어이므로 단일 측정소가 안 잡히는 경우가 자주 있습니다
- hosted 모드에서는 upstream AirKorea key 를 클라이언트에 배포하지 않고 proxy 에만 둡니다