这是以下挑战的参赛作品:Hacktoberfest 开源 AI 挑战赛第 1 周:Touch Grass

简短版

你正要出门时,家里有人连珠炮似的给你列了一串:

“买 1 升牛奶。别买面包——家里还有。把包裹送到邮局。再买三个笔记本。”

大多数任务类应用会让收到这条消息的人承担所有工作:停下来、输入、拆分、记住,并正确理解取消项。

Nikalll 把这个杂乱的家庭请求变成一张经过复核的口袋卡片。你可以说出或粘贴请求,让开源权重的 Gemma 模型提出待办事项,逐项复核,确认目的地,然后把最终卡片带出门。

重要的不是 AI 生成了一份清单。重要的是已取消的项目仍然可见,数量仍然保留,不确定性仍然可见,并且由人——而不是模型——批准最终带出门的内容。

我构建了什么

Nikal 是一个语音优先的家庭跑腿交接工具,面向那些通常以嘈杂语音消息或印地语/印地英语/英语混合消息形式出现的、真实世界中的小任务。

它面向的是正要离家、需要记住别人托付自己购买、取回或送达什么的人。

流程被刻意设计得很短:

  1. 采集——录制一段简短语音或粘贴原始消息。
  2. 转写——ElevenLabs Scribe v2 将语音转为可编辑文本。
  3. 提取——通过 Backboard 调用的 Gemma 提出结构化待办事项、数量、取消项、目的地提示和澄清问题。
  4. 复核与分配——原始请求保持可见,同时用户可以编辑、取消、推迟或分配每一项。
  5. 口袋卡片——Nikal 按目的地对已批准的任务进行分组。
  6. 出门后——用户将每一项标记为已完成、无法获取、推迟或未解决。

Nikal 不是自主购物智能体。它不购买任何东西、不给任何人发消息、不查找商店、不追踪 GPS,也不假装模型输出的合法 JSON 就意味着请求已被理解。

这个设计要防止的失败

最危险的失败不是崩溃。而是一份看起来合理、却悄悄丢掉了关键部分的清单:

  • “别买面包”变成了“买面包”。
  • “两升”丢失了数量。
  • “把这个放到邮局”丢失了它的目的地。
  • 一个不明确的商店变成了一个自信的猜测。
  • 一个无法获得的物品被悄悄计为已完成。

Nikal 将这些视为产品状态,而非边缘情况。

卡片所保留的内容

  • 已包含的差事。
  • 已明确取消的差事。
  • 已推迟或未解决的差事。
  • 数量和单位。
  • 用户的原始源文本。
  • 目的地分配和手动更正。
  • 诚实的完成结果。

准备好的工作区保存在带版本控制的浏览器存储中。AI 请求是在线且托管的;准备好的本地卡片不需要再次调用模型来标记结果。我不声称这个原型是一个完全离线的 AI 应用或经过验证的可安装 PWA。

演示

在线演示: nikalll.onrender.com

视频演示:

视频演示展示的是完整的故事,而非功能导览:

  1. 从一个混乱的家庭请求开始。
  2. 保持取消和数量可见。
  3. 让 Gemma 生成一份草稿。
  4. 在审核步骤中更正或确认目的地。
  5. 准备口袋卡片。
  6. 将一项任务标记为完成,并让一个无法获得/推迟的状态保持可见。

如果托管提供商不可用,应用会保留源文本并提供手动路径,而不是伪造一个成功的 AI 结果。

代码

🚶 Nikalll (WalkRecall)

将混乱的门口语音笔记转化为结构化、可离线使用的差事卡片。

Live Demo Next.js 16 Google Gemma ElevenLabs TypeScript Strict

出门前说一次,几秒钟内审核完毕,然后带着一份可离线完全使用的、一目了然的邻里清单出门。

探索在线演示·架构·功能·快速开始



💡 问题:“门口语音笔记”的混乱

每次你走出家门,你的母亲、室友或伴侣都会连珠炮似地喊出一串混乱的差事:

“喂,听好了!你要出门的话,就从蔬菜市场买 1 公斤土豆和香菜……但别买西红柿,家里已经有了……然后从杂货店买 2 升牛奶和酸奶,但面包千万别买……再从药店买降压糖浆,别买创可贴,那东西在抽屉里!”

为什么传统工具会失败:

  1. 待办应用太慢:没有人有时间或耐心手动输入 8 个单独的项目,还要……



该项目是一个 Next.js + TypeScript 应用,领域契约、提供商边界、测试和安装说明与 UI 一同提交。

最相关的区域包括:

  • app/page.tsx——捕获、审核和口袋卡片流程。
  • app/api/extract/route.ts——有边界、经用户同意的文本提取边界。
  • app/api/transcribe/route.ts——有边界的音频上传边界。
  • lib/server/backboard.ts——显式的 Backboard 提供商/模型请求。
  • lib/server/elevenlabs.ts——ElevenLabs 语音转文本适配器。
  • lib/domain/——schema 与确定性的卡片/证据逻辑。
  • tests/——领域与提供商归一化的回归测试。

我是如何构建它的

开源权重 AI 是核心,而非装饰

Gemma 承担核心的解读任务:将对话式、混合语言的 household 指令转化为有边界的提取草稿。

浏览器从不选择提供商或模型。服务器从环境配置中选择它们,并发送带有以下内容的固定提示词:

  • 显式的提供商和模型名称;
  • 非流式输出;
  • 请求 JSON 输出作为格式化辅助;
  • 禁用记忆;
  • 禁用网络搜索;
  • 无工具或自主操作。

默认仓库配置通过 Backboard 中的openrouter提供商使用 Gemma。具体模型可由服务器配置;仓库默认值为google/gemma-3-27b-it。不会向客户端发送 API 密钥。

Gemma 的输出不会仅因为它是 JSON 就被信任。Zod 会校验响应,服务器会检查每条证据引文是否逐字出现在原始来源中。模型无法返回受信任的目标 ID、应用 ID、时间戳、完成状态或审批决定。

ElevenLabs 是一个聚焦的输入边界

语音之所以有用,是因为原始问题常常始于口头表达。ElevenLabs Scribe v2 负责转写;随后 Nikal 会在提取前将转写文本显示为可编辑文本。

音频上传有大小限制,仅通过服务器路由接受,且不作为应用数据存储。UI 始终可以回退到文本输入。

确定性代码负责信任敏感决策

普通 TypeScript——而非模型——负责:

  • schema 校验;
  • 证据匹配;
  • 目标别名匹配;
  • 纳入/取消/推迟状态;
  • 卡片准备规则;
  • 本地持久化;
  • 结果跟踪。

一个已包含的条目如果没有确认的去向,就不能进入已准备好的卡片。未解决的条目必须被解决或明确延后。不可用的条目绝不会被悄悄标记为完成。

技术栈

  • Next.js 16 App Router
  • React 19 和严格 TypeScript
  • Tailwind CSS 4,沿用现有的 shadcn/Base UI 配置
  • Hugeicons
  • Zod 用于运行时契约
  • 通过 Backboard 调用 Gemma 进行提取
  • ElevenLabs Scribe v2 用于转录
  • Render 用于公开部署

我从第一次尝试中学到了什么

我之前的黑客松项目教会我,精致的界面和冗长的功能列表并不能证明核心问题已被解决。

所以这个项目有意做得更窄。演示只有一个完整的故事:一个混乱的请求、一份带来源链接的 AI 草稿、一次人工审核、一张口袋卡片,以及一个诚实的结果。我保留了原始文本可见,因为看起来正确的提取仍可能是错的。我把取消和不确定性保留为一等状态,因为隐藏它们比展示一个不完整的结果更糟。

我还删除了自己无法证明的说法:

  • 托管的 Gemma 不被描述为离线 AI;
  • 浏览器持久化不被描述为完全离线的 PWA;
  • 模型的 JSON 不被描述为批准;
  • 去向标签不被描述为实时商店发现;
  • 没有经过标注的留出评估,就不声称任何准确率百分比;
  • 不可用的跑腿任务不会被转换成成功状态。

最有用的工程决策是让提供方的输出穿过一个小而无聊的边界:验证它,对照原始消息核验其证据,然后让确定性的应用代码决定用户可以批准什么。

为什么开放创新很重要?

开放模型在这里很有用,因为 Nikal 并不是试图用一个不透明的助手取代人。它试图让混乱的人工交接变得可检查、可纠正。

以开放权重模型作为提取步骤的核心:

  • 模型和提供方可以在不重写产品工作流的情况下更换;
  • 提取提示词和 JSON 契约可以被检查;
  • 失败可以与人工基线对比,而不是隐藏在聊天界面后面;
  • 应用可以把批准、证据和完成状态保留在模型之外;
  • 未来自托管的 Gemma 部署可以缩小敏感家庭消息的托管数据边界;
  • 同一份安全契约可以验证不同的开放模型。

Backboard 为应用提供了一个明确的模型边界,而不是浏览器端的供应商依赖。我可以在服务器上选择 Gemma 的提供商/模型,关闭记忆和网页搜索,并让应用的其余部分独立于这一选择。

ElevenLabs 的范围刻意更小:它解决语音采集问题,然后把可编辑文本交给同一条审核流水线。它不会成为第二个决策者。

有一个重要的注意事项:当前的公开部署使用托管服务。开放创新让模型层可替换、可检查;它并不会神奇地让托管推理变得私密。当请求被发送用于转录或提取时,Nikal 会告知用户。

我的智能体会话

我用以下工具构建了 NikalOmniRush.ai作为编码和审查伙伴。该智能体在架构、领域契约、提供商边界、故障处理和测试用例方面提供了帮助;我做出产品决策,并将最终范围聚焦于一次物理世界的交接。

我没有在这份草稿中嵌入 DevRelay 会话链接,因为我没有可链接的公开已保存会话 URL。本节可以在发布前删除,或者在创建了 DevRelay URL 后替换为该 URL。

奖项类别

  • Gemma 最佳使用—— Gemma 负责核心的解读问题:嘈杂家庭语言中的数量、否定、取消、目的地提示和澄清候选。它不是装饰性的聊天。
  • Backboard 最佳使用—— Backboard 是明确的服务器端模型边界。请求固定提供商/模型,禁用记忆和网页搜索,请求结构化输出,并在结果到达审核 UI 之前对其进行验证。
  • ElevenLabs 最佳使用—— ElevenLabs Scribe v2 处理短语音笔记转录路径,并在提取之前返回可编辑文本。
  • Render 最佳使用—— 可运行的 Next.js 应用及其由提供商支持的路由已公开部署在nikalll.onrender.com。

构建者@taqui。

如果这是团队提交,队友应在发布前在此处用他们的 DEV 用户名署名。