han-dong.link — 空间化作品驾驶舱、基于来源的问答与职位匹配 agent
- TypeScript
- Astro
- React
- Three.js
- Spatial UI
- Provider-agnostic LLM
- LLM Tool-Calling
- Generative UI
- Guardrails
- Progressive Enhancement
职位匹配 agent 把贴上或上传的 JD 转成带来源的契合简报,面向招聘方快速核对;同一套 han-dong.link 也把即时问答助手与 Three.js 驾驶舱串起简介、作品、研究与履历。
一眼看懂
角色 独立开发者 — 互动驾驶舱 UI、Three.js 导航、问答与职位匹配 agent loop、带来源答案卡、文件/JD 护栏、部署
问题
公开作品集要同时服务招聘方、技术同侪与研究合作者,不能让读者自己猜每个主张背后有什么证据。静态页面可以列出作品,但很少能回答职位相关问题,也很少展示网站本身如何组织证据。
解法
我做了空间化驾驶舱,也保留正典阅读页,并把两者连到同一组 Astro content collections,供问答与职位匹配共用。访客可以打开简介、作品、研究与履历四个星球,也可以线性阅读或透过带证据的卡片提问。
成果
已在 han-dong.link 上线 · 主页驾驶舱入口呈现即时作品集数量 · 答案卡引用来源页 · 可见回答轨迹 · 职位匹配把 JD 文字或文件转成强项、相邻证据、缺口与追问
我的工作
- 空间化作品驾驶舱:围绕助手构建的 Three.js 体验,以简介、作品、研究、履历四个星球呈现,并为减少动态、手机与无 WebGL 环境保留 read-mode 页面
- 五个 typed tools(getProjects / getPublications / getStack / getTimeline / getContact),LLM 按问题自选,并有文字兜底
- 职位匹配 agent:独立 `/role-fit` 页面接受贴上的 JD 文字或 PDF/PNG/JPEG/WebP 上传,输出包含强匹配、相邻证据、诚实缺口与招聘方追问的倡导式简报——不做百分比打分或录用/不录用建议
- Source-linked 生成式 UI:每个工具结果渲染成 React 卡片(项目卡、论文列表、工具标签、时间线、联络),并连回对应来源页
- 可见回答轨迹:助手把从站内内容检索到答案卡生成的来源路径显示出来,让访客能看见回答为何成立
- content collections 作为单一数据源——新项目自动进 agent,无需重训、无需 embedding
- 诚实的说服:先讲优势、用一句简短承认短板、绝不编造事实/头衔/数字
技术证据
- 渐进增强的 Three.js 外壳:WebGL/减少动态/手机能力检查、启动序列、键盘与滚轮导航,以及从同一组 Astro content collections 显示即时数量的驾驶舱仪表板
- Agent loop:校验输入 → 从 collections 组装 grounded system prompt → LLM 工具决策 → 工具调用去重 → 解析 typed tools → 渲染卡片 + 文字
- Observable agent traces 让 loop 可检查:检索到的 collection 记录、选中的 tool cards 与最终文字保持可见连接,不会消失在纯聊天回答里
- 护栏:输入校验(长度上限、prompt-injection 正则、拒答越界与套取 prompt)加 per-IP 限流
- 职位匹配护栏:JD 专用校验、拒绝而非爬取第三方招聘连结、PDF/图片提取、证据白名单、数字/资质主张守卫,以及完整分析延迟时基于站内证据生成简报
- provider-agnostic LLM 整合 + 确定性 mock fallback,dev / 无 key 时完全离线可跑
- Astro + Vercel 服务端渲染;三语(EN / 繁中 / 简中);答案经 markdown 渲染
Agent loop
每个问题的流程:校验输入 → 从 content collections 组装 grounded system prompt → 问 LLM 该调哪些工具 → 工具调用去重 → 解析 typed tools → 渲染卡片加文字。由 LLM 决定说什么、调哪个工具;代码不硬编码问题到答案的路由。
最新 agent 更新把这条路径变成可见 answer trace:被检索的来源记录、选中的卡片与最终文字保持连接,因此助手可被检查,而不是只能被相信。
Role Fit——带证据的 JD 匹配
Role Fit 是独立任务流程,而不是另一个聊天 prompt。招聘方可以贴上职位描述,或上传 PDF/截图;网站提取 JD 文字后,对照公开 content collections,输出按强匹配、相邻证据、缺口与待确认问题组织的简报。
边界是明确的:本站不读取第三方招聘网站 URL,不把 JD 存入聊天历史,不编造私人细节,也不做百分比打分或录用/不录用建议。trace 也会标记结果何时只由站内证据组成,让边界保持可检查。
Grounded,而非 RAG
content collections 是单一数据源。没有 embedding、没有向量库——网站新增一个项目就自动进 agent,零重训。system prompt 明确:只用提供的信息、绝不编造事实/头衔/数字;若某细节不在,就直说并指向联络方式。
护栏与诚实的说服
输入按长度校验并筛查 prompt-injection 尝试;越界、角色扮演、套取 prompt 的请求一律拒答;请求按 IP 限流。Role Fit 另加 JD 专用校验、上传文件提取限制、第三方 URL 拒答、证据白名单,以及数字/资质主张守卫。prompt 先讲优势并诚实标出缺口——有说服力,但绝不编造。
驾驶舱外壳——空间化作品集
驾驶舱是网站的互动前端。它以全窗口 Three.js 场景呈现四个可导航星球:简介、作品、研究、履历。访客可用滚轮、键盘或点击在四个星球之间移动;每个星球打开的卡片都来自与助手相同的 Astro content collections,因此 3D 场景、档案视图与答案卡保持一致。
仪表板呈现同一组 collections 的即时数量。减少动态、手机与无 WebGL 环境保留正典 read-mode 页面,让空间化互动叠加在可访问、可回链的作品集之上。
界面截图