1. 一个名字背后藏着的真实需求第一次看到“i-have-adhd”这个项目标题我脑子里蹦出来的不是某个具体的技术栈而是一类非常典型的产品思路用极简的自我声明去解决一个长期被忽视的体验问题。ADHD注意缺陷与多动障碍在中文互联网语境里经常被简化成“注意力不集中”“坐不住”“拖延症晚期”但真正身处其中的人知道它影响的远不止是能不能安静坐着而是信息处理方式、任务启动机制、时间感知、情绪调节这一整套底层操作系统的差异。这个项目标题之所以有意思是因为它没有把自己包装成一个“治疗工具”或者“效率神器”而是用一种近乎标签化的方式直接告诉外界我的大脑运行规则和大多数人不一样。这种表达本身就带有很强的产品哲学——不是去矫正差异而是让差异被看见、被适配。我接触过不少做效率工具和辅助类产品的开发者大家普遍有一个共识真正好用的工具往往不是功能最多的那个而是最懂用户“卡在哪”的那个。对于ADHD群体来说卡点非常具体任务启动困难、工作记忆容量有限、时间盲区、多线程切换成本极高、对枯燥重复的容忍度极低。所以当我顺着这个标题去拆解时我看到的不是一个简单的个人状态声明而是一个可以延展出完整产品逻辑的入口。它可能是一个浏览器插件在用户打开太多标签页时给出温和提醒可能是一个命令行工具把复杂任务拆成肉眼可见的微步骤也可能是一个极简的桌面挂件只显示“现在只做这一件事”。无论最终形态是什么核心都是围绕“降低认知负荷”和“外部化执行功能”这两个关键词展开。这篇文章我想聊的就是如果让我从零开始做一个以“i-have-adhd”为核心理念的辅助项目我会怎么设计、怎么选型、怎么落地以及在实际操作中会踩哪些坑。适合谁看如果你自己就是ADHD群体的一员或者你在为这类用户做产品又或者你只是对“如何用技术手段补偿执行功能缺陷”这个话题感兴趣那接下来的内容应该能给你一些可以直接抄作业的思路。2. 整体设计思路为什么不做“大而全”而是做“小而准”2.1 核心设计原则外部化执行功能ADHD的核心困难之一是执行功能的内化不足。什么意思大多数人在脑子里就能完成“计划-启动-维持-切换-收尾”这一整套流程但ADHD群体往往需要把这些步骤从大脑里拿出来放到外部环境里才能运转。这就像电脑内存不够时系统会自动把部分数据交换到硬盘上——不是能力问题是资源分配策略不同。所以我在设计这个项目时第一条原则就是所有关键信息必须外部化。不能依赖用户“记住”任何事情不能假设用户能“自己想起来”。每一个需要执行的步骤都必须以视觉、听觉或触觉的形式存在于外部环境中。具体到产品形态上这意味着任务不能只存在于待办列表里必须有一个“当前唯一任务”的强提示时间不能只靠内部感知必须有外部计时和视觉化进度步骤不能只写“完成报告”必须拆到“打开文档-写标题-写第一段”这种颗粒度我试过很多次如果只给ADHD用户一个模糊的任务描述比如“整理项目文档”大概率会触发拖延。但如果改成“把桌面上的三个文件拖进文件夹A”启动阻力会下降一个数量级。这不是因为任务变简单了而是因为大脑不需要再消耗额外能量去解析“整理”到底意味着什么。2.2 技术选型为什么我倾向于轻量级本地方案在技术选型上我优先考虑的是“零延迟”和“零干扰”。任何需要网络请求、需要登录、需要等待加载的方案对于ADHD用户来说都是额外的摩擦点。摩擦点越多启动概率越低。所以我的倾向是前端纯本地运行能用原生就不用框架能用轻量框架就不用重型框架存储本地文件或浏览器本地存储优先避免账号体系和同步逻辑交互键盘快捷键优先于鼠标点击减少手部移动距离通知系统级通知优先于应用内弹窗因为应用可能根本没被打开举个例子如果做一个“当前任务聚焦”的小工具我会选择用Electron或者Tauri打包一个桌面应用而不是做一个网页。原因很简单网页需要打开浏览器、找到标签页、可能被其他标签页干扰而桌面应用可以常驻托盘一个快捷键就能呼出。这个差异看起来很小但在实际使用中启动步骤从三步变成一步使用频率可能翻倍。注意这里说的“轻量级”不是指功能少而是指运行时开销小、交互路径短。功能可以很丰富但入口必须极简。2.3 与常见效率工具的本质区别市面上大多数效率工具的设计假设是用户有能力规划、有能力执行、只是需要更好的管理。但ADHD用户需要的不是“管理”而是“启动”和“维持”。这两者的区别很大。管理类工具关注的是“如何安排优先级”“如何分配时间”“如何跟踪进度”而辅助类工具关注的是“如何让用户开始做第一件事”“如何让用户不中途跑偏”“如何让用户记得回来”。前者是优化问题后者是可用性问题。所以我在设计这个项目时会刻意避开一些常见功能不做复杂的优先级矩阵因为决策本身就是消耗不做长期目标追踪因为时间盲区会让远期目标失去意义不做多项目并行看板因为切换成本太高取而代之的是一个“现在做什么”的单一入口一个“还剩多少时间”的视觉化计时器一个“下一步是什么”的微步骤提示这些功能看起来很简单但每一个都直接对应一个具体的执行功能缺陷。3. 核心细节解析从任务启动到完成的完整链路3.1 任务拆解把“一座山”变成“一级台阶”ADHD用户面对大任务时最常见的反应是“知道要做但就是动不了”。这不是懒而是大脑在面对模糊、庞大、没有明确边界的任务时会触发回避反应。解决这个问题的唯一办法就是提前把任务拆到“不需要思考就能执行”的程度。我在实际操作中总结了一个拆解标准每一步的预估时间不超过5分钟且第一步必须是物理动作。比如“写项目总结”这个任务拆解后可能是打开文档软件新建一个空白文档在标题位置输入“项目总结”写下三个关键词把第一个关键词扩展成一句话注意第一步“打开文档软件”是一个纯粹的物理动作不需要任何认知决策。这一步的意义在于打破静止状态让身体先动起来。很多ADHD用户都有类似体验一旦开始做了反而能持续做下去难的是从0到1的那一下。在代码层面这个拆解逻辑可以用一个简单的数据结构来表示{ task: 写项目总结, steps: [ {id: 1, action: 打开文档软件, done: false}, {id: 2, action: 新建空白文档, done: false}, {id: 3, action: 输入标题, done: false}, {id: 4, action: 写下三个关键词, done: false}, {id: 5, action: 扩展第一个关键词, done: false} ], currentStep: 1 }界面上只显示当前步骤完成一个才显示下一个。这个“一次只显示一步”的设计非常关键因为同时看到所有步骤会重新触发任务庞大感。3.2 时间可视化让“时间盲区”变得可见时间盲区是ADHD的另一个核心特征。不是不知道时间重要而是大脑无法直观感受到时间的流逝。15分钟和1小时在主观体验上可能差不多。所以时间必须被可视化变成可以“看见”的东西。我试过几种方案最后发现最有效的是进度条数字倒计时颜色变化的组合。进度条提供整体感知数字提供精确信息颜色变化提供紧迫感。比如剩余时间大于50%绿色剩余时间在20%-50%黄色剩余时间小于20%红色这种多通道反馈的好处是即使某一通道被忽略其他通道仍然能传递信息。有些用户对数字不敏感但颜色变化能触发注意有些用户对颜色不敏感但进度条的移动能带来感知。在实现上可以用CSS动画或者Canvas来绘制进度条每秒钟更新一次。更新频率不需要太高因为ADHD用户对频繁变化反而容易分心。每秒一次是一个比较平衡的频率。实操心得倒计时不要用“还剩XX分钟”这种模糊表述直接用“还剩12:34”这种精确到秒的格式。精确数字带来的紧迫感更强也更容易被大脑处理。3.3 干扰拦截在分心发生前介入ADHD用户的分心往往不是主动选择而是被动触发。一个通知、一个想法、一个环境变化都可能让注意力瞬间转移。所以干扰拦截的关键是“提前介入”而不是事后提醒。我在设计中会加入几个拦截机制单一窗口模式全屏显示当前任务隐藏其他所有应用入口通知静默在专注时段自动开启勿扰模式想法收集箱如果用户突然想到其他事情提供一个快速记录入口记录后立即回到当前任务第三个机制特别重要。ADHD用户经常在做事时突然想起“啊我还要回个消息”“对了那个文件还没发”如果不立即处理这个想法会一直占用工作记忆如果立即处理当前任务就断了。收集箱的作用是给这些想法一个临时存放点告诉大脑“已经记下了不用一直想着”从而释放工作记忆。// 简单的想法收集逻辑 function captureThought(thought) { const inbox JSON.parse(localStorage.getItem(thoughtInbox) || []); inbox.push({ content: thought, timestamp: Date.now(), processed: false }); localStorage.setItem(thoughtInbox, JSON.stringify(inbox)); showToast(已记录继续当前任务); }这个功能看起来很简单但实际使用中效果非常好。很多用户反馈说光是“知道有个地方可以记下来”这件事本身就能减少很多焦虑。3.4 奖励机制为什么即时反馈比长期目标更有效ADHD用户对延迟奖励的敏感度较低但对即时反馈的反应很正常。这意味着传统的“完成项目后奖励自己”这种模式效果有限因为项目完成太遥远了。更有效的做法是把奖励拆散嵌入到每一个小步骤中。我在设计中会加入这些即时反馈每完成一个步骤播放一个简短的音效进度条前进时有一个平滑的动画完成整个任务后显示一个简单的庆祝动画连续完成多个步骤后显示“连续完成X步”的提示这些反馈不需要很复杂关键是及时和一致。音效可以选择比较轻柔的提示音避免过于刺耳。动画时长控制在300毫秒以内太长会打断节奏。注意奖励机制要避免过度刺激。有些工具会用夸张的动画和音效短期可能有效但长期使用会让人感到疲劳。简洁、一致、可预测的反馈反而更持久。4. 实操过程从零搭建一个最小可用版本4.1 环境准备与技术栈选择如果你也想动手做一个类似的小工具我建议从最小可用版本开始。不要一上来就追求功能完整先做一个能跑起来的核心功能然后根据实际使用体验迭代。我的技术栈选择如下层级选择理由运行环境Node.js Electron跨平台本地运行系统级集成界面原生HTML/CSS/JS零依赖启动快无框架开销存储本地JSON文件简单可靠无需数据库通知Electron Notification系统级通知不依赖应用窗口快捷键Electron globalShortcut全局呼出减少操作路径这个组合的好处是依赖少、启动快、可控性强。Electron虽然常被诟病体积大但对于桌面常驻工具来说它的系统集成能力是网页无法替代的。安装步骤很简单mkdir i-have-adhd cd i-have-adhd npm init -y npm install electron --save-dev然后在package.json里配置启动脚本{ scripts: { start: electron . } }主进程文件main.js负责创建窗口和注册快捷键const { app, BrowserWindow, globalShortcut, Notification } require(electron); const path require(path); let mainWindow; function createWindow() { mainWindow new BrowserWindow({ width: 400, height: 600, alwaysOnTop: true, frame: false, transparent: false, webPreferences: { nodeIntegration: true, contextIsolation: false } }); mainWindow.loadFile(index.html); } app.whenReady().then(() { createWindow(); globalShortcut.register(CommandOrControlShiftA, () { if (mainWindow.isVisible()) { mainWindow.hide(); } else { mainWindow.show(); } }); }); app.on(window-all-closed, () { if (process.platform ! darwin) app.quit(); });这个最小版本已经具备了核心能力一个常驻窗口、一个全局快捷键、一个可以承载界面的容器。接下来就是往里面填充具体功能。4.2 核心功能实现当前任务聚焦模块当前任务聚焦模块是整个工具的核心。它的逻辑很简单只显示一个任务只显示当前步骤完成一个才进入下一个。界面结构可以用三个区域来组织顶部任务名称和整体进度中部当前步骤的大字显示底部完成按钮和跳过按钮HTML结构如下div idapp div idtask-header h2 idtask-name写项目总结/h2 div idprogress-bar div idprogress-fill/div /div /div div idcurrent-step p idstep-text打开文档软件/p /div div idcontrols button iddone-btn完成这一步/button button idskip-btn跳过/button /div /divJavaScript逻辑负责管理任务状态和界面更新let currentTask { name: 写项目总结, steps: [ 打开文档软件, 新建空白文档, 输入标题, 写下三个关键词, 扩展第一个关键词 ], currentIndex: 0 }; function renderStep() { const stepText document.getElementById(step-text); const progressFill document.getElementById(progress-fill); const taskName document.getElementById(task-name); taskName.textContent currentTask.name; stepText.textContent currentTask.steps[currentTask.currentIndex]; const progress (currentTask.currentIndex / currentTask.steps.length) * 100; progressFill.style.width progress %; } function completeStep() { if (currentTask.currentIndex currentTask.steps.length - 1) { currentTask.currentIndex; renderStep(); playSound(step-complete); } else { showCelebration(); } } document.getElementById(done-btn).addEventListener(click, completeStep); renderStep();这个实现非常基础但已经能跑通核心流程。你可以把任务数据存到本地JSON文件里每次启动时读取这样就不需要每次手动输入。4.3 时间可视化模块的实现细节时间可视化模块我建议独立成一个组件因为它需要频繁更新而且可能需要全屏显示。实现上可以用一个单独的窗口或者在主窗口里切换视图。核心逻辑是let timerState { totalSeconds: 25 * 60, remainingSeconds: 25 * 60, isRunning: false, intervalId: null }; function startTimer() { if (timerState.isRunning) return; timerState.isRunning true; timerState.intervalId setInterval(() { timerState.remainingSeconds--; updateTimerDisplay(); if (timerState.remainingSeconds 0) { stopTimer(); notifyTimeUp(); } }, 1000); } function updateTimerDisplay() { const minutes Math.floor(timerState.remainingSeconds / 60); const seconds timerState.remainingSeconds % 60; const display ${String(minutes).padStart(2, 0)}:${String(seconds).padStart(2, 0)}; document.getElementById(timer-text).textContent display; const ratio timerState.remainingSeconds / timerState.totalSeconds; const fill document.getElementById(timer-fill); fill.style.width (ratio * 100) %; if (ratio 0.5) { fill.style.backgroundColor #4caf50; } else if (ratio 0.2) { fill.style.backgroundColor #ff9800; } else { fill.style.backgroundColor #f44336; } }这个实现里有一个细节值得注意颜色阈值我设的是50%和20%而不是常见的60%和30%。这是因为ADHD用户对时间流逝的感知偏慢如果阈值设得太早黄色和红色出现时用户会觉得“还有时间”反而失去警示作用。把阈值往后推能让紧迫感更真实。实操心得计时器的默认时长建议从15分钟开始而不是25分钟。ADHD用户的持续注意力时长普遍偏短15分钟是一个更容易达到的目标。完成15分钟后如果状态好可以再续一个15分钟这种“可续杯”的设计比固定25分钟更灵活。4.4 数据持久化与状态恢复工具类应用最怕的就是数据丢失。ADHD用户本来就容易忘记事情如果工具本身还丢数据那信任感会瞬间归零。所以数据持久化必须做到简单可靠。我的方案是用本地JSON文件每次状态变化时立即写入。不需要数据库不需要复杂的序列化就是最朴素的读写。const fs require(fs); const path require(path); const DATA_FILE path.join(__dirname, data.json); function saveState(state) { fs.writeFileSync(DATA_FILE, JSON.stringify(state, null, 2)); } function loadState() { try { if (fs.existsSync(DATA_FILE)) { return JSON.parse(fs.readFileSync(DATA_FILE, utf-8)); } } catch (e) { console.error(读取状态失败, e); } return getDefaultState(); }这个方案的好处是透明、可调试、可手动编辑。如果用户想批量导入任务直接编辑JSON文件就行不需要额外的导入功能。对于个人工具来说这种“文件即界面”的设计反而更高效。状态恢复的逻辑是在应用启动时读取上次的状态包括当前任务、当前步骤、计时器剩余时间等。这样即使应用崩溃或者电脑重启用户回来时还能接着上次的进度继续。5. 常见问题与排查技巧实录5.1 启动阻力依然很大怎么办这是最常见的问题。即使任务已经拆得很细用户还是不想开始。这时候需要检查两个地方第一第一步是不是足够小。如果第一步是“打开文档软件”但用户连打开软件都觉得麻烦那就把第一步改成“把鼠标移到文档软件图标上”。听起来很荒谬但实际测试中这种极端微小的第一步确实能提高启动率。一旦手移动了后续动作就顺了。第二有没有“启动仪式”。有些用户需要一个固定的触发动作来进入状态比如戴上耳机、倒一杯水、打开某个特定的歌单。工具可以配合这个仪式比如在用户点击“开始”后播放一段固定的启动音效形成条件反射。5.2 中途跑偏了怎么拉回来跑偏是必然发生的关键是怎么回来。我的经验是不要对抗跑偏而是给跑偏一个“出口”。具体做法是当用户意识到自己跑偏时不需要自责只需要在工具里点一个“我跑偏了”按钮。点击后工具会显示当前任务和当前步骤并问一句“要继续吗”这个简单的确认动作往往就能把注意力拉回来。这个按钮的设计要点是不要有任何惩罚性反馈不要显示“你已经分心X分钟”这种信息。ADHD用户对负面反馈非常敏感任何带有评判意味的提示都可能引发回避。5.3 任务拆解太细导致步骤太多拆解太细确实会带来一个问题步骤列表太长完成一个任务需要点击很多次。这会让人感到繁琐。解决办法是分层拆解。第一层是粗颗粒的里程碑第二层是每个里程碑下的微步骤。界面上只显示当前里程碑和当前微步骤完成一个里程碑后自动进入下一个。这样既保证了每一步都足够小又不会让用户感到步骤无限多。问题类型表现排查方向解决技巧启动困难知道要做但动不了第一步是否足够小把第一步改成纯物理动作中途跑偏做着做着就切走了是否有干扰拦截加入想法收集箱和勿扰模式步骤过多感觉永远做不完拆解层级是否合理分层拆解只显示当前层时间感知偏差觉得还早其实快到了时间可视化是否明显用精确数字颜色变化忘记回来切走后想不起来是否有外部提醒设置定时提醒或常驻窗口5.4 工具本身变成新的分心源这是一个很讽刺但很常见的问题为了管理注意力而做的工具本身变成了新的注意力黑洞。用户可能会花大量时间调整工具设置、美化界面、研究新功能而不是用工具来做事。避免这个问题的关键是工具的功能要少到不能再少。每次想加新功能时先问自己这个功能是帮助用户做事还是帮助用户逃避做事如果是后者坚决不加。我在实际使用中会给自己定一个规则工具界面上的可点击元素不超过5个。超过5个就说明功能太多了需要砍。5.5 不同场景下的适配问题这个工具在不同场景下的使用方式差异很大。比如工作场景需要与办公软件配合可能需要窗口置顶学习场景需要与阅读材料配合可能需要分屏显示家务场景需要移动端支持可能需要语音输入我的建议是先做好一个场景不要试图覆盖所有场景。场景越多功能越复杂启动阻力越大。先把工作场景做透其他场景可以通过快捷键和窗口管理来适配不需要专门开发新功能。6. 后续扩展方向与个人体会这个项目做到最小可用版本之后其实还有很多可以延展的方向。比如可以加入简单的数据统计看看自己在什么时间段最容易启动、什么类型的任务最容易卡住。这些数据不需要很精确只要能提供一点反馈就能帮助用户更好地了解自己的模式。另一个方向是模板化。把常见的任务类型做成模板比如“写邮件”“整理文件”“准备会议”用户只需要选择模板不需要每次从零拆解。模板可以逐步积累形成个人化的任务库。还有一个方向是环境集成。比如检测到用户打开某个特定软件时自动切换到对应的任务模式或者检测到用户长时间没有操作时自动弹出提醒。这些集成需要更多的系统权限实现复杂度也更高但效果可能会更好。我个人在实际操作中的体会是做这类工具最重要的不是技术实现而是对用户状态的理解。技术方案可以很简单但每一个交互细节都需要反复推敲。一个按钮的位置、一句提示的措辞、一个动画的时长都可能影响用户的使用意愿。我踩过的坑包括把界面做得太花哨导致用户分心、把步骤拆得太细导致用户烦躁、把提醒做得太频繁导致用户直接关掉通知。每一次调整都是基于实际使用中的反馈而不是理论上的最优解。最后分享一个小技巧如果你也在做类似的项目建议先自己用一周。不要急着给别人用先自己每天用记录下每一次卡住的地方。这些卡点就是最真实的需求比任何用户调研都有效。
阅读完成 · 觉得有帮助?