Skip to content

Repository files navigation

此刻附近(Nearby Now)

English documentation for judges: README_EN.md

一个开源的本地生活管家智能体:用户只要说一句现在的心情,它就会调查所在城市当天的公开活动和附近场景,直接给出一个低成本、现在能执行的行动方案。

公开英文演示:Nearby Now — One Sentence In, One Local Plan Out

OpenAI Build Week:Codex + GPT-5.6 的协作过程、关键决策与新增内容见 BUILD_WITH_CODEX.md,英文投稿文案和视频材料见 submission/README.md

它解决的不是“搜索哪个景点”,而是:

我今天想出去走走,但不知道做什么。

系统不会让用户先填写目的地、预算、交通方式和游玩时长,也不会返回一长串排行榜。智能体会在内部比较“参加当天活动”和“只在附近闲逛”两条路径,核验现实条件后替用户做一次决定。

核心体验

  • 中英文即时切换:界面、离线方案和 AI 输出语言同步切换,语言设置保存在本机。
  • 一句话输入:描述心情,或者点击“我不想说,直接安排”。
  • 管家式决策:最终只给一个方案,而不是地点榜单。
  • 活动 / 闲逛双路径:既调查当天活动,也准备一个不依赖活动的附近漫游方案。
  • 公开信息核验:活动必须具备当地日期、明确地点、可参加时段和公开来源。
  • 低成本优先:优先公共空间、步行、小型文化活动、市场、图书馆和轻量小任务。
  • 低置信度审美线索:最多三张照片和三首歌曲只用于判断场景氛围,不用于推断身份、健康或固定人格。
  • 多设备 PWA:手机、平板和桌面浏览器共用同一套界面,可安装到桌面。
  • 透明降级:API 不可用时明确进入离线闲逛模式,不编造实时活动。

工作方式

flowchart LR
  A["一句心情 + 可选照片/歌曲"] --> B["粗略定位与临时状态判断"]
  B --> C["调查当天活动"]
  B --> D["构造附近闲逛方案"]
  C --> E["日期/时间/地点/来源证据门"]
  D --> F["开放状态/天气/安全检查"]
  E --> G["比较执行成本与此刻匹配度"]
  F --> G
  G --> H["只输出一张行动海报"]
Loading

每次实时推荐遵循以下原则:

  1. 从用户的一句话临时判断精力、社交需求、刺激需求和行动阻力。
  2. 同时形成至少一个 event 候选和一个 roam 候选。
  3. 活动缺少日期、时间、地点或公开来源中的任何一项,就淘汰该活动。
  4. 闲逛方案也必须结合真实场景,并包含一个简单的小任务,而不是轮换固定文案。
  5. 最终只展示一个可执行方案、三步脚本、预计时间和成本、核验摘要及来源。

更完整的设计见 docs/architecture.md

快速开始

环境要求

  • Node.js 18 或更高版本(服务端使用原生 fetch)。
  • 一个现代浏览器。
  • 实时智能体模式需要至少配置一个受支持的模型 API;不配置也可以体验离线模式。

启动应用

项目没有运行时第三方依赖,直接启动本地 Node 服务:

node services/agent-api/server.mjs

打开:

http://127.0.0.1:4173

服务只监听本机回环地址 127.0.0.1,不会默认暴露到局域网或公网。

配置模型 API

启动后点击页面右上角的 API 设置,选择提供商并填写密钥、模型和 API 地址。密钥会保存到 Git 忽略的 services/agent-api/.env,浏览器页面只显示末四位掩码。

提供商 默认模型 API 根地址 搜索与多模态方式
OpenAI gpt-5.6 https://api.openai.com/v1 Responses API、web_search、授权照片输入
Google Gemini gemini-2.5-flash https://generativelanguage.googleapis.com/v1beta generateContent、Google Search grounding、图片连通测试
魔搭 ModelScope Qwen/Qwen3.5-35B-A3B https://api-inference.modelscope.cn/v1 OpenAI 兼容 Chat Completions、服务端公开网页搜索、图片连通测试

Gemini 的“API 地址”建议填写 API 根地址。若误填完整的 .../models/...:generateContent 地址,服务端也会自动归一化,并以“模型”字段中的模型名构造请求。

魔搭 API-Inference 需要关联的阿里云账号完成实名认证;否则请求会到达魔搭,但模型端会拒绝推理。可在 ModelScope 账号设置完成认证。

也可以手动创建配置:

Copy-Item services/agent-api/.env.example services/agent-api/.env

然后编辑 services/agent-api/.env

AI_PROVIDER=gemini

OPENAI_API_KEY=
OPENAI_MODEL=gpt-5.6
OPENAI_BASE_URL=https://api.openai.com/v1

GEMINI_API_KEY=你的_Gemini_API_Key
GEMINI_MODEL=gemini-2.5-flash-lite
GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta

MODELSCOPE_API_KEY=
MODELSCOPE_MODEL=Qwen/Qwen3.5-35B-A3B
MODELSCOPE_BASE_URL=https://api-inference.modelscope.cn/v1

PORT=4173

不要把真实密钥提交到 Git,也不要把密钥写入 apps/web

Android 手机应用

Android 版本是真正可安装、独立运行的 APK,不是“添加到主屏幕”的网页快捷方式,也不需要 Nearby Now 电脑服务器。应用内置中英文界面、心情快捷预设和离线闲逛方案;配置用户自己的模型 API 后,由 Android 原生代码直接通过 HTTPS 生成实时推荐。

Nearby Now Android 手机版

启用手机端 AI:

  1. 安装 APK,打开底部 智能体 或顶部 API 设置
  2. 选择 OpenAI 或 Google Gemini,填写自己的 API Key;模型和 HTTPS 根地址可保持默认。
  3. 回到首页输入一句心情,或直接点选“有点累 / 有点闷 / 想独处 / 想新鲜一点”。
  4. App 会把临时心情线索、当前城市、当地时间和自愿保存的低置信度偏好直接交给模型;模型联网比较当天活动与附近闲逛,最后只给一个方案。
  5. 没有 Key、无网络、额度不足、返回结构不合格或活动缺少公开来源时,App 会明确退回内置离线闲逛方案。

API Key 不会写入网页、源码或 APK。原生层用 Android Keystore 生成不可导出的 AES 密钥,再以 AES-GCM 加密保存用户 Key;Key 不通过 JavaScript 回传。应用禁止明文 HTTP,并关闭包含密钥的系统备份。卸载 App 会清除本地配置。

当前独立 APK 支持 OpenAI Responses API(含 web_search)和 Gemini generateContent(含 Google Search grounding)。桌面网页仍保留 Node 服务与 ModelScope 适配器,但它们不是 Android 版的运行依赖。

构建测试 APK:

Set-Location android
.\gradlew.bat clean assembleDebug lintDebug

安装包输出到 android/app/build/outputs/apk/debug/app-debug.apk。更多说明见 android/README.md

使用方法

  1. 打开“我的偏好”,可选填常用城市、三首喜欢的歌曲和最多三张照片。
  2. 照片默认只在浏览器本地提取明暗、冷暖等低维色彩线索。
  3. 只有勾选本次照片授权后,压缩副本才会随当前请求发送给模型。
  4. 回到首页说一句心情,例如:“周末有点闷,不想去商场,但想出去透透气。”
  5. 允许一次大致定位;如果定位失败,智能体只追问当前城市。
  6. 等待智能体完成理解、搜索、比较、核验和决定。
  7. 根据行动卡直接开始,或者点击跳过让系统避开类似方案。

独立 AI 技能包

skills/local-life-concierge/ 是可以脱离网页应用独立使用的技能包:

skills/local-life-concierge/
├── SKILL.md
├── agents/
│   └── openai.yaml
└── references/
    └── recommendation-contract.md

将整个目录复制到个人 Codex 技能目录:

~/.codex/skills/local-life-concierge/

之后可以直接说:

使用 $local-life-concierge,结合我现在的心情,替我调查今天附近能做的一件事。

技能包规定了活动证据门槛、闲逛候选要求、结构化输出合同和隐私边界,入口文件是 skills/local-life-concierge/SKILL.md

API

本地服务同时托管 PWA 和智能体接口:

方法 路径 用途
GET /api/health 查看当前提供商、模型及实时/离线状态
GET /api/config 读取脱敏后的本机 API 配置
PUT /api/config 保存、切换或移除本机模型配置
POST /api/test-multimodal 用一张图片验证 Gemini 或 Qwen 多模态连通性
POST /api/plan 提交心情、粗略位置、偏好和可选图片,生成唯一行动方案

配置写接口只接受来自 localhost127.0.0.1 的请求。服务端对图片格式、总体积、模型名和 API 地址进行基础校验。

隐私与安全

  • 原始照片默认不上送;浏览器只保存照片数量和提取后的低维色彩线索。
  • 用户逐次授权后,才发送最长边不超过 768 像素的压缩图片;服务端不把图片写入磁盘。
  • 桌面网页的 API 密钥保存在 Git 忽略的 .env;Android Key 由 Android Keystore + AES-GCM 加密保存在 App 私有存储,均不会写入前端源码。
  • 精确坐标只用于当前推荐;长期偏好仅保存用户主动选择的城市和审美线索。
  • 心情判断是临时工作假设,不构成心理诊断,也不推断敏感属性。
  • 项目只使用无需绕过登录的公开网页信息,不声称访问私密社交内容。
  • 实时活动没有足够证据时,系统会回退到低依赖的闲逛方案。
  • 用户可以在“我的偏好”中清除城市、偏好、历史和反馈。

项目结构

apps/web/                       零依赖 PWA 客户端
android/                        独立 Android APK、加密 BYOK 配置与原生模型直连
services/agent-api/             零依赖 Node.js 服务、静态服务器与模型编排
skills/local-life-concierge/    可独立分发的 AI 技能包
docs/architecture.md            数据流、多设备与生产化架构
tests/smoke.mjs                 结构与关键契约冒烟测试
submission/                     演示提交相关素材

验证

node --check services/agent-api/server.mjs
node --check apps/web/app.js
node tests/smoke.mjs

测试会检查页面关键元素、本地配置接口、三种模型提供商、多模态通路、搜索通路以及活动证据门槛是否仍然存在。

当前限制

  • 这是本地运行的开源原型,不提供托管账户、跨设备同步或推送通知。
  • Android 独立版采用 BYOK(用户自带 API Key);模型提供商的额度、计费、地区可用性和数据条款由用户自己的账户决定。
  • ModelScope 的免费 API-Inference 受账号认证、动态额度和并发限制影响。
  • 公开网页索引不能替代所有社交平台的官方 API;登录后或私密内容不在搜索范围内。
  • 地图路线、天气和营业状态目前没有完整的地区适配器,生产版本应接入对应区域的正式数据源。
  • 活动信息具有时效性,界面展示的来源和核验摘要仍应由用户在出发前快速确认。

许可证

代码采用 MIT License。地点、地图、天气、模型和活动数据仍需遵守各自供应商的许可、署名、额度及使用条款。

About

An open-source AI-assisted same-day local activity planner with event discovery, fallback roaming, and an offline-ready PWA.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages