factcircuit
FactCircuit: an auditable claim-and-evidence verification loop with immutable provenance, staged checks, bounded retrieval, and reproducible evaluation.
输入全国任意一个地址,自动统计周边 1 km 的 7 类设施,生成交互地图与逐条校验的场地分析简报。
Translation pending
DataTypeScript · JavaScriptGitHub @dengzishuo19OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
输入全国任意一个地址(中国大陆),自动检索周边 1 km 的设施,由大模型撰写学术风格的场地分析简报,并由代码逐个校验简报中的数字。 面向建筑与城市设计专业的学生:做课程作业前,先快速获得一份带数据来源的场地概况。 ▶ 在线体验版(可输入全国任意地址,实时生成): https://www.dzs-agent.com ▶ 静态演示(预先生成的真实结果,点开即看,网络不佳时使用): https://dengzishuo19.github.io/site-analysis-agent/ 在线体验版部署在 Vercel(香港节点),并绑定了自己的域名。vercel.app 默认域名在国内被屏蔽,绑定自有域名(DNS 的 A 记录直接指向 Vercel 的服务器 IP)后,国内实测可正常打开、响应快;两个链接在国内网络下都实测可用。为保护接口额度,设有访问频率限制。 大模型擅长写作,但不擅长数数,也可能编造数字。所以这个项目把职责拆开: 校验器核对三类断言:「设施名」必须存在于数据;名称后的距离必须属于这个设施;“某类别 N 处”的 N 必须等于该类别的数量;其余数字至少要出现在统计表里。为了让校验器认得出断言,提示词要求模型使用固定句式。校验不通过时,会带着具体的纠错信息让模型重写一次;仍不通过则在页面上标红警告,不会悄悄放行。Read the full README ↗
输入全国任意一个地址(中国大陆),自动检索周边 1 km 的设施,由大模型撰写学术风格的场地分析简报,并由代码逐个校验简报中的数字。
面向建筑与城市设计专业的学生:做课程作业前,先快速获得一份带数据来源的场地概况。
▶ 在线体验版(可输入全国任意地址,实时生成): https://www.dzs-agent.com
▶ 静态演示(预先生成的真实结果,点开即看,网络不佳时使用): https://dengzishuo19.github.io/site-analysis-agent/
在线体验版部署在 Vercel(香港节点),并绑定了自己的域名。
vercel.app默认域名在国内被屏蔽,绑定自有域名(DNS 的 A 记录直接指向 Vercel 的服务器 IP)后,国内实测可正常打开、响应快;两个链接在国内网络下都实测可用。为保护接口额度,设有访问频率限制。
大模型擅长写作,但不擅长数数,也可能编造数字。所以这个项目把职责拆开:
| 环节 | 谁来做 | 原因 |
|---|---|---|
| 地址转坐标、周边设施检索 | 高德 Web 服务 API | 国内数据全 |
| 计数、按距离排序、取最近设施 | 代码 | 大模型数数不可靠 |
| 把统计数据写成书面简报 | 大模型(DeepSeek) | 擅长写作 |
| 逐条核对简报里的断言 | 代码 | 事实由代码裁决,不交给模型 |
校验器核对三类断言:「设施名」必须存在于数据;名称后的距离必须属于这个设施;“某类别 N 处”的 N 必须等于该类别的数量;其余数字至少要出现在统计表里。为了让校验器认得出断言,提示词要求模型使用固定句式。校验不通过时,会带着具体的纠错信息让模型重写一次;仍不通过则在页面上标红警告,不会悄悄放行。
杂志/刊物风格,黑白灰:用字号层级和图片排布表达信息主次,不用彩色;只有地图底图保留彩色(水系、绿地是场地分析的重要信息)。设施类别用简笔画图标区分(lib/icons.ts),不靠颜色。只用系统字体(谷歌字体在国内打不开):黑体标题与正文、宋体简报、等宽数字。
在线版首页(尚未分析时)有一句话说明、三个卖点,以及一个内置示例:7 个事先生成好的案例可切换(北京 5 个:国贸、首钢园、亦庄、北京建筑大学西城校区、八达岭;外地 2 个:上海陆家嘴、成都太古里),显示 7 类设施数量、简报节选和“已由代码校验”标记;点“用这个地址实际分析”才跑真实分析,点案例切换不请求任何接口。示例数据来自 app/components/examples.json(由 scripts/export-demo-data.mjs 与静态演示数据同时导出,只含数量、最近设施和简报节选,不含坐标),生成日期显示在页面上,不会随高德数据实时更新。分析等待时显示分步说明(定位、检索、过滤),这是按经验估计的,不是实时进度。
结果页顶部有一条可信度信息条,只展示后端已有的事实:统计经服务器签名;简报中的数字已全部核对、其中多少个与具体设施或类别逐一配对(来自校验器的覆盖率);已过滤多少个噪点(链接到 docs/testset/review.md 的规则与度量)。页面底部注明作者(邓子硕)与 GitHub 仓库;页面带分享标签与预览图(public/og.png),微信等平台是否采用以实测为准。
布局手机优先:单列、可点击元素不小于 44 px;宽屏放宽到约 960 px,地图与条形图并排。已用 375 px 与 1280 px 宽度实测,无横向滚动。
配色按 dataviz 技能 的方法计算:该色板最多只有 4 种颜色能同时通过“全配对”检查,而设施有 7 类,所以采用复合编码——颜色表示类型族(交通、生活服务、公园绿地、工业),标记里的单字表示具体类别(地、公、教、医、商、园、工),不靠颜色硬分。
| 地图(深色) | 图表(浅色) | 图表(深色) |
|---|---|---|
教育、医疗、工业三类可展开子类型(教育:大学、中学、小学、幼儿园、职业学校、其他;医疗:综合医院、社区卫生服务、口腔、医疗美容、眼科、其他专科;工业:产业园区、工厂、其他),使用者勾选后,数量、最近设施、地图、条形图随之更新。噪点过滤始终开启,不是选项;子类型是“分解 + 勾选”,默认全选,数字与大类一致。
数字仍然由服务端算并签名:/api/site 返回的签名数据里带有过滤后的点位池(每类最多 75 条,含子类型);勾选时浏览器把签名数据和勾选交给 POST /api/site/refine,服务端先验签,只用签名数据里的点位池重算,再重新签名,不访问高德、不信任浏览器提交的数字。改变口径后已生成的简报作废,需要按当前口径重新生成;简报会写明统计口径。
局限:高德的“学校”泛类分不出小学还是中学,按名称再划分,会有误分;点位池最多 75 条,设施很多的类别子类型数量是下限;子类型准确率只在自建的小测试集上核对过(教育 47 个、工业 26 个保留点位全部判对,但核对者与规则作者是同一方),医疗的子类型完全取决于高德类型。静态演示页只读显示子类型分解,不能勾选。
地铁出入口全部标出后,市中心的标记会大量重叠(国贸默认视野下 86 个标记有 72 个被压住)。现在相距很近的标记会合并为一个簇:同一类显示为该类标记加数量角标,多类显示为写着总数的圆点、下方小色点表示含有哪几类;点击簇放大拆开,18 级以上全部单独显示;图例隐藏的类别不参与聚合。聚合只改变显示,不改变标出的设施集合与任何统计数字。5 个演示案例默认视野下被压住的符号降到 0–2 个(lib/map-cluster.test.ts 回归测试)。
高德的地理编码在无法确定具体地点时,会静默返回一个行政区划中心点:例如输入“北京建筑大学”(有西城、大兴两个校区),它返回“北京市(level=省)”,坐标是市中心。如果直接照单全收,后面的统计、地图、简报都会建立在错误的位置上,而且看起来完全正常,所以这一步必须先校验定位精度:
| 情况 | 例子 | 处理 |
|---|---|---|
| 输入本身只是行政区名 | 北京、朝阳区 | 拒绝,提示输入更具体的地点 |
| 高德没认出具体地点,退回了行政中心 / 只定位到道路、村庄、开发区 | 北京建筑大学、长安街、中关村 | 用关键字搜索给出候选,让用户选 |
| 定位精确但有多个相距超过 300 m 的候选 | 北京大学(4 个校区) | 让用户选 |
| 定位精确 | 国贸地铁站、首钢园、清华大学 | 直接分析 |
候选去掉上级也在结果里的子点位(如校区在列表中时去掉校内的系;上级不在结果里的保留,例如挂在上级片区下的“成都太古里”。原规则为只保留 parent 为空的顶层点位,即校区本身,而不是校内的系、食堂、停车场)。用户选中候选时,服务器只接受自己签发的令牌(HMAC 签名、30 分钟有效、坐标必须在北京范围内),不接受浏览器提交的任意坐标。判断逻辑是纯函数并有单元测试。
parent 字段把校内院系、院内科室、园区楼栋折叠到所属机构,并按类型与名称剔除培训机构、党校、药店、写字楼里标成“工厂”的公司等类别归错的点位(附属学校、异地分部保留为独立设施);折叠后若没取完全部结果,数量按“至少”标注。过滤规则用一份人工标注的测试集度量(5 个场地、389 个点位,npm run eval:poi):误杀 1/184,漏网 16/205;用没参与调规则的 4 个场地抽查未见误杀,但测试集很小,这些数字不能外推到所有场地。需要 Node.js 20+,以及高德开放平台的 Web 服务 Key、Web 端(JS API)Key 和 DeepSeek API Key。
npm install
cp .env.example .env.local # 然后在 .env.local 中填入你自己的 Key
npm run dev # 打开 http://127.0.0.1:3000(不要用 localhost,见下)
npm test # 运行单元测试
本地必须用 127.0.0.1 访问:高德的域名白名单不接受 localhost,而地图会按访问域名校验 Key。
关于地图 Key:Web 端(JS API)Key 会出现在浏览器里,这是它的工作方式,无法像其他 Key 那样藏在服务器里。它是一个独立的 Key(与 Web 服务 Key 分开),靠高德控制台里的域名白名单保护(127.0.0.1、GitHub Pages 域名、在线版域名);白名单可以被非浏览器工具伪造,最坏的后果是有人消耗它的每日额度,不会产生费用。高德的服务条款规定:未购买技术服务许可时,所提供的 Key 与额度仅供短期、少量的测试使用——本项目是技术演示,请勿大量访问。
**排错:**若地图区域提示“脚本已加载但不可用”或“Key 格式不正确”,多半是环境变量里的 Key 带了多余字符(空格、换行、引号、变量名前缀)。高德在这种情况下不会报错,只会返回一个不定义 AMap 的脚本,页面上就是“脚本已加载但不可用”。代码会自动去掉首尾空白与引号,并要求 Key 是 32 位字母数字;重新填写环境变量并重新部署即可。
.env.local 已被 .gitignore 忽略,Key 只在服务端使用,不会出现在前端代码或返回结果中。生产环境还需要配置 SIGNING_SECRET(随机字符串,生成方法见 .env.example),缺少时所有页面和接口都会返回 500(安全失败,不会放行未签名的数据)。
在线版对所有人开放,背后消耗的是作者的接口额度,所以做了这些防护:
/api/site 返回的数据带 HMAC-SHA256 签名(30 分钟有效),/api/report 只接受验签通过的数据。别人无法伪造统计数据来滥用大模型,也无法借设施名称做提示词注入。/api/health 在生产环境返回 404;基础安全响应头。**这套防护的边界:**限流数据存在进程内存里,在多实例的无服务器环境下每个实例各自计数,只是“尽力而为”,防不住有意的攻击。兜底靠 DeepSeek 预充值制(最坏情况是余额用完)和高德的每日额度;如果被滥用,下一步是把计数迁移到共享存储(如 Redis)。
lib/amap.ts 高德接口封装(地理编码、周边搜索)
lib/stats.ts 设施统计(类别与分类编码在此配置)
lib/llm.ts 大模型调用封装(OpenAI 兼容格式,换模型只改环境变量)
lib/report.ts 简报生成 + 校验重试
lib/verify.ts 数字校验(纯函数) ← 含 verify.test.ts
app/api/ site(统计)、site/refine(自选子类型口径)、report(简报)、health(连通性检查)
docs/index.html 静态演示页(由 scripts/build-demo.mjs 生成)
docs/tasks/ 每个开发阶段的派工单与验收记录
项目借助 AI 编程 Agent 完成:我提出需求、审阅设计并逐条验收。每个阶段先写派工单(背景、输入输出、不许改的文件、验收标准),完成后按验收标准核对并留下证据,记录保存在 docs/tasks/。开发中真实发现并修复的问题包括:
sortrule=distance 返回顺序并不严格按距离,导致统计表“最近设施”出错,改为多取并在代码中排序。设施数据来自高德开放平台,简报由 DeepSeek 生成。本项目仅作技术演示与学习,简报仅基于统计表,不构成任何规划或投资建议。