韩国家庭垃圾投放查询技能实战:基于 k-skill 的 household-waste-info 与 k-skill-proxy 密钥注入架构解析
2026/9/17 20:47:56 网站建设 项目流程

韩国家庭垃圾投放查询技能实战:基于 k-skill 的 household-waste-info 与 k-skill-proxy 密钥注入架构解析

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

导读

household-waste-info是 k-skill 技能仓库中面向韩语用户的生活类(utility)技能,它通过调用韩国行政安全部(행정안전부)"生活垃圾分类投放信息"(생활쓰레기배출정보)公共数据 Open API,按**市郡区(시군구)**查询生活垃圾、食物垃圾与可回收物的投放标准、投放星期与时间信息,并以用户友好的摘要形式返回。本篇文章将围绕该技能在仓库中的两个核心文档——SKILL.md 与 instruction.md——完整讲解其使用场景、认证架构、代理路由参数约束、端到端工作流,并结合 k-skill-proxy 源码与测试用例,深入剖析serviceKey服务端注入、分页参数强校验、内存缓存等底层实现,帮助你掌握"官方 Open API + 代理收口密钥 + 技能指令"这套可复用的开发范式。


一、技能概览:它能做什么

1.1 核心能力

根据 instruction.md 的定义,本技能调用行政安全部的生活垃圾投放信息 Open API,向用户提供按地区划分的三类投放信息:

  • **生活垃圾(생활쓰레기)**的投放标准与星期/时间;
  • **食物垃圾(음식물쓰레기)**的投放标准与星期/时间;
  • **可回收物(재활용품)**的投放标准与星期/时间。

几个关键设计决策:

  • 基本查询单元是市郡区名(SGG_NM,即以行政区划名称为入口;
  • 响应需整理为易于理解的摘要,而不是把 API 原始负载直接抛给用户;
  • Base URL 对齐原始 APIhttps://apis.data.go.kr/1741000/household_waste_info
  • serviceKeyDATA_GO_KR_API_KEY)仅由代理服务器注入与管理,用户侧不保存密钥。

1.2 典型使用场景

文档给出了四类典型用户问法,分别覆盖"星期""时间""地点/方法"三个维度的查询:

用户提问(示例)对应查询意图
"강남구 쓰레기 배출 요일 알려줘"(告诉我江南区垃圾投放星期)按市郡区查询投放星期
"우리 동네 음식물쓰레기 언제 버려?"(我们小区的食物垃圾什么时候扔?)查询食物垃圾投放时间
"재활용품 배출 시간 확인해줘"(帮我确认可回收物投放时间)查询可回收物投放时间
"생활쓰레기 배출 장소/방법 찾아줘"(帮我找生活垃圾投放地点/方法)查询投放地点与投放方法

这四类问法共同指向一个事实:用户的自然语言中通常只有地区名,没有结构化参数,因此技能的核心职责是"识别地区 → 构造查询 → 摘要结果"。

1.3 前提条件与运行环境

运行该技能需要满足以下环境要求(instruction.md):

  • 互联网连接;
  • 可执行curlpython3的运行环境;
  • 可访问原始 API 的环境;
  • 可访问用于密钥注入的代理(proxy)的环境。

值得强调的是:默认路径下用户不需要额外编写客户端 API 层,直接通过代理路由即可完成查询(详见第三节)。


二、认证与密钥架构:为什么用户端不需要 API 密钥

这是本技能最有代表性的架构决策之一,值得单独展开。

2.1 认证需求

instruction.md 明确指出:用户侧默认没有任何必需的认证密钥。可选环境变量只有一个:

  • KSKILL_PROXY_BASE_URL—— 当使用自托管(self-hosted)代理时才需要设置;未设置时默认走官方托管的k-skill-proxy.nomadamas.org

2.2 密钥管理的三条原则

文档以编号形式明确了认证密钥的使用原则:

  1. 端点/参数体系遵循原始 API:代理路由对外暴露的参数名与原始 API 保持一致,客户端无需学习两套协议;
  2. serviceKey由代理服务器管理并注入:密钥只存在于服务器侧;
  3. 用户本地环境无需放置DATA_GO_KR_API_KEY:这既降低了密钥泄露风险,也让技能对最终用户几乎零配置。

这一设计与 SKILL.md 中的硬性规则("绝不在聊天、文件或 shell 参数中询问、打印或存储明文凭据")互为印证:密钥隔离不是可选项,而是技能的安全底线。


三、官方 API 面与代理路由设计

3.1 官方 API 面

项目
Base URLhttps://apis.data.go.kr/1741000/household_waste_info
端点(Endpoint)GET /info
密钥注入仅由代理k-skill-proxy在服务端注入serviceKey

也就是说,代理路由实际上对接的上游完整地址是https://apis.data.go.kr/1741000/household_waste_info/info,这在 server.js 中可以直接看到:

const url = new URL("https://apis.data.go.kr/1741000/household_waste_info/info");

3.2 代理支持的查询参数(核心约束)

instruction.md 对代理路由的参数约束做了非常明确的定义,这是整个技能最容易踩坑的部分:

参数约束说明
cond[SGG_NM::LIKE]必填市郡区名包含式搜索
pageNo/numOfRows(或page_no/num_of_rows必填,且值必须是1/100其他值或非整数(不只含数字)的字符串一律返回400,上游不会被调用
returnType恒为json代理强制指定,客户端即使传值也被忽略
serviceKey禁止客户端传递由代理在服务端注入

分页参数之所以被锁死在1/100,是因为生活垃圾分类投放信息按市郡区粒度查询后,单页 100 条足以覆盖绝大多数地区的完整投放规则;同时统一固定分页也简化了缓存键的设计(见第四节源码分析)。

3.3 附加过滤器的说明

原始 API 还支持cond[DAT_CRTR_YMD::*](数据生成日期)、cond[DAT_UPDT_PNT::*](数据更新点)等附加过滤条件,但当前代理路由并不透传(pass-through)这些参数。文档给出了务实的原因:用户常见提问(如"강남구 쓰레기 배출 요일")仅靠市郡区搜索就足够了;如果需要按时间维度排序,可以在客户端依据响应中的DAT_UPDT_PNT自行排序。


四、端到端工作流

instruction.md 将完整流程划分为四个步骤,下面逐一展开并结合源码佐证。

4.1 第一步:先询问地点

在没有拿到用户地区信息之前,绝不直接发起查询。文档推荐的标准提问语是:

"확인할 지역(시/군/구)을 알려주세요. 예: 강남구, 수원시 영통구"(请告诉我要查询的地区(市/郡/区)。例如:江南区、水原市灵通区)

这一步对应了技能的核心查询粒度——市郡区名(SGG_NM),先确认位置才能构造出合法的cond[SGG_NM::LIKE]参数。

4.2 第二步:校验输入并解析查询

  • 如果市郡区输入为空,则再次向用户询问;
  • 如果输入含糊不清(例如只给了"首尔"这种市域而非市郡区),则应以包含上级行政区划的形式向用户重新确认。

4.3 第三步:通过代理调用(密钥在服务端注入)

代理会在服务端注入serviceKey后再把请求转发给原始 API。文档给出的标准 curl 示例为:

curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/household-waste/info' \ --data-urlencode "cond[SGG_NM::LIKE]=강남구" \ --data-urlencode "pageNo=1" \ --data-urlencode "numOfRows=100"

使用要点:

  • returnType会被代理强制为json,所以客户端无需再单独发送该参数;
  • 如果设置了KSKILL_PROXY_BASE_URL环境变量,则以该值替换默认的托管代理地址。

同样的调用方式在 k-skill-proxy/README.md 中也有对应示例(使用${LOCAL_PROXY_BASE_URL}指向自托管实例),证明这是代理的通用调用约定。

4.4 第四步:为用户生成摘要

从响应中抽取必要字段,用简洁、口语化的方式整理给用户。文档指定的摘要字段见下表:

类别响应字段
管理区域 / 目标区域MNG_ZONE_NMMNG_ZONE_TRGT_RGN_NM
投放地点 / 投放方法EMSN_PLCLF_WST_EMSN_MTHDFOD_WST_EMSN_MTHDRCYCL_EMSN_MTHD
投放星期 / 时间LF_WST_EMSN_DOWFOD_WST_EMSN_DOWRCYCL_EMSN_DOW,以及各类别的开始/结束时间
不收运日UNCLLT_DAY
咨询处MNG_DEPT_NMMNG_DEPT_TELNO

在测试用例 server.test.js 中可以验证这些字段的真实形态,例如LF_WST_EMSN_DOW: "월,수,금"(周一、周三、周五)与LF_WST_EMSN_BGNG_TM: "18:00"LF_WST_EMSN_END_TM: "23:00"(开始/结束时间)。字段以全大写韩文缩写命名,是行政安全部公共数据 API 的原始风格。


五、源码级实现:路由、密钥注入、缓存与错误处理

本节基于 k-skill-proxy 源码 还原household-waste-info在代理侧的真实实现,帮助你理解指令文档约束背后的代码逻辑。

5.1 路由注册与参数校验

代理在server.js中注册了GET /v1/household-waste/info路由(server.js),处理顺序如下:

  1. 读取查询参数中的cond[SGG_NM::LIKE]
  2. 若缺失或为空 → 返回400,错误码为bad_request,消息为cond[SGG_NM::LIKE] is required
  3. 调用validateHouseholdWastePaginationQuery(query)校验分页参数(server.js),该校验器的规则与指令文档完全一致:
    • 同时接受pageNo/numOfRowspage_no/num_of_rows两种命名;
    • 两者都必填,缺任一即400
    • 值必须通过^\d+$(纯数字)正则,非数字字符串(如abc)直接400
    • 值必须严格等于pageNo=1numOfRows=100,否则400

从代码结构可以推断:该校验是先于上游请求执行的,因此一旦参数非法,代理会直接拒绝,而不会把非法请求转发给 data.go.kr。

5.2 serviceKey 注入与上游请求构造

校验通过后,代理固定使用pageNo = "1"numOfRows = "100",并构造上游请求(server.js):

const url = new URL("https://apis.data.go.kr/1741000/household_waste_info/info"); url.searchParams.set("serviceKey", config.molitApiKey); url.searchParams.set("pageNo", pageNo); url.searchParams.set("numOfRows", numOfRows); url.searchParams.set("returnType", "json"); url.searchParams.set("cond[SGG_NM::LIKE]", sggNm.trim());

几个值得注意的实现细节:

  • serviceKey来自config.molitApiKey,而该配置项由环境变量DATA_GO_KR_API_KEY解析而来(server.js),即指令文档所说"密钥由代理服务器管理";
  • returnType被硬编码为json,印证了"客户端传值也会被忽略"的约束;
  • cond[SGG_NM::LIKE]会先trim()再传入,避免首尾空格导致匹配失败。

5.3 密钥未配置时的行为

如果代理服务器没有配置DATA_GO_KR_API_KEY,路由会返回503,错误码为upstream_not_configured,消息为DATA_GO_KR_API_KEY is not configured on the proxy server.(server.js)。这属于指令文档"失败模式"中提到的第一种情况——密钥缺失/失效时的服务端表现。

5.4 内存缓存

路由使用makeCacheKey({ route: "household-waste-info", sggNm: sggNm.trim() })作为缓存键(server.js)。命中缓存时,响应中的proxy.cache.hittrue并附上ttl_ms;未命中时,代理会发起上游请求并把结果连同queryproxy元信息写入缓存。这意味着同一市郡区的重复查询会被代理层去重,从而降低对公共数据 API 的调用压力。

5.5 上游异常映射

  • 上游返回非 2xx → 代理返回502,错误码upstream_error(附带上游状态码);
  • 上游网络请求抛错 → 代理返回502,错误码upstream_fetch_failed

这两类错误对应指令文档"失败模式"中的"公共数据 API 临时故障/流量限制"。此外,k-skill-proxy/README.md 还提醒了一个常见坑:DATA_GO_KR_API_KEY需要在公共数据门户对相应服务单独申请"使用申请(활용신청)"并获批后才能生效,未激活时上游会返回 401/403 或 data.go.kr 的认证错误 XML,代理会将其转换为 upstream error。


六、测试用例验证

k-skill-proxy 的测试套件 为household-waste/info路由覆盖了五类关键场景,是对指令文档约束的直接可执行验证:

  1. cond[SGG_NM::LIKE]400/bad_request(server.test.js);
  2. 未配置DATA_GO_KR_API_KEY503/upstream_not_configured(server.test.js);
  3. 缺少分页参数 →400(server.test.js);
  4. 非法分页值(pageNo=99&numOfRows=5pageNo=abc)→400,且不调用上游(server.test.js);
  5. 正常请求 → 注入serviceKey、强制returnType=json、写入缓存(server.test.js):
    • 通过 mockglobal.fetch捕获上游 URL,断言其 origin + pathname 正是https://apis.data.go.kr/1741000/household_waste_info/info
    • 断言响应中的proxy.cache.hit首次为false,第二次请求命中缓存;
    • 断言回显的query.sgg_nmquery.page_noquery.num_of_rows与请求一致;
    • 还有用例验证客户端即使传returnType=xml也会被忽略(server.test.js)。

这些测试从行为层面确认了:参数的强校验、密钥的服务端注入、返回类型的强制、以及缓存机制,全部是代理路由的硬性实现,而非文档建议


七、失败模式排查清单

结合 instruction.md 的失败模式与上文源码分析,整理一份排查清单:

现象根因排查/处置
返回503 upstream_not_configured代理服务器未配置DATA_GO_KR_API_KEY或密钥已过期,serviceKey注入失败在代理侧配置/更新密钥(server.js)
查询结果为空搜索的地区名与 API 数据不一致(如行政区划变更、名称不匹配)改用更接近官方区划名称的输入,或使用上级区划重新确认
上游报错 / 响应异常公共数据 API 临时故障或流量限制等待后重试;检查DATA_GO_KR_API_KEY是否已在 data.go.kr 对该服务单独申请激活
返回400 bad_request缺少cond[SGG_NM::LIKE],或未传分页参数补齐参数(server.js)
返回400(分页规则)pageNo/numOfRows不是1/100,或为abc等非纯数字字符串严格使用1/100;代理会直接拒绝,上游不会被调用(server.js)

八、完成条件(Done when)

instruction.md 定义了一次成功技能执行的判定标准,可作为 Agent 自查清单:

  1. 已确认用户所在地区(市郡区);
  2. 已成功调用代理的/v1/household-waste/info路由;
  3. 已把投放星期/时间/地点整理为3~6 个核心要点摘要提供给用户。

九、注意事项与最佳实践

最后是文档反复强调的几条注意事项,也是将该技能投入实际使用的纪律要求:

  • 密钥零落地:用户侧不保存DATA_GO_KR_API_KEY,密钥只在代理服务器端管理;
  • 摘要而非透传:不要把 API 原始负载直接展示给用户,必须整理成用户友好的摘要;
  • 多结果排序:当响应包含多条记录时,优先按最新的DAT_UPDT_PNT(数据更新点)排序展示,保证信息时效;
  • 官方数据源:本技能的数据来源为韩国公共数据门户(공공데이터포털)的官方数据集,查询结果具有官方依据。

此外,SKILL.md 还定义了技能运行时的三条硬性规则(即使不通过 CLI 也适用):未经用户明确事先同意,绝不执行支付、消息/邮件发送、最终提交、取消或公开发布等操作;绝不在聊天、文件或 shell 参数中询问、打印或存储明文凭据;绝不绕过法律、到场核验、验证码、身份核验或电子签名等边界。这些规则与本文的密钥代理架构共同构成了该技能安全运行的前提。

如需在运行时获取最新指令,可通过技能 CLI 拉取:

npx -y @nomadamas/k-skill@0 instruct household-waste-info npx -y @nomadamas/k-skill@0 files household-waste-info

该技能的类型定义为utility、语言区域为ko-KR、采用 MIT 许可证,相关元数据可在 skill.json 中查看。完整的指令文档与技能说明分别保存在 instruction.md 与 SKILL.md,代理路由实现与测试用例则分别位于 server.js 和 server.test.js。

【免费下载链接】k-skill한국인을 위한 스킬 모음집 - 에이전트를 한국인으로项目地址: https://gitcode.com/GitHub_Trending/ks/k-skill

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询