DevLog:2025年12月11日

1、需要给应用增加多模型管理和切换、联网搜索(通过Tavily,在模型界面增加Tavily Key字段)、回收站(可删除和恢复AI对话、收藏内容)、深度思考(在使用支持深度思考的模型时,可在对话过程中看到思考过程,并且样式和回答内容要有区别)、流式输出(可能现在已经有了?)、Markdown渲染(可能现在已经有了?)等功能

2、决定先增加联网搜索、回收站、深度思考功能,Cursor规划了7步:实现联网搜索功能(Tavily):添加Tavily Key字段到设置页面和存储、创建Tavily服务,实现联网搜索API调用、在聊天中集成联网搜索功能、实现回收站功能:修改数据库添加is_deleted字段、修改删除逻辑为软删除,创建回收站页面、实现深度思考功能:修改OpenAI服务解析思考内容、修改消息显示组件,区分显示思考过程和回答内容

3、Cursor只用了几分钟就完成了如下修改:

1. 联网搜索功能(Tavily):在设置页面的API配置部分添加了Tavily Key输入字段;创建了TavilyService处理联网搜索API调用;在聊天中集成:配置Tavily Key后,发送消息时会自动进行联网搜索,并将搜索结果作为上下文发送给 AI

2. 回收站功能:数据库更新:为conversations和messages表添加了is_deleted和deleted_at字段;软删除:删除操作改为软删除,数据不会真正删除;回收站页面:在设置页面的“数据管理”部分可进入回收站;可查看已删除的AI对话和收藏内容;可恢复已删除的内容;永久删除(不可恢复)

3. 深度思考功能:OpenAI服务更新:支持解析深度思考模型的thinking字段;消息显示更新:区分显示思考过程和回答内容;思考过程:灰色背景、斜体、带边框,顶部有“思考过程”标签;回答内容:正常样式显示

4、按照目前已有的功能,应该已经可以实现从添加模型到对话到删除的完整流程了,测试一下,先让Cursor解决两个问题,以及一个新需求:

1.在模拟器中打开应用时,对话页面出现了错误提示:LocaleDataException: Locale data has not been initialized, call initializedDataFormatting(<locale>).

2.在填写API Key、Base URL、模型名、Tavily Key后,填写的信息无法保存,退出设置界面后再回来看填写的信息就消失了

3.我需要把数据统计和回收站都放到设置-数据管理里

5、第一个问题,可能是因为中文日期的问题?第二个问题,为所有输入框添加了onEditComplete回调,在失去焦点时自动保存,第三个问题,将数据统计和回收站合并到了“数据管理”卡片中,继续测试,1和3已经解决,二仍然未能保存,决定直接动个大手术,添加多模型管理和切换功能,并在其中增加模型信息保存机制,需求包括:

1.在设置界面增加“模型管理”卡片,将现有的API配置整合到“模型管理”卡片中

2.可以在“模型管理”界面查看我添加的所有模型,可以在这里新建、修改、删除模型,并且可以将我添加的任何一个模型设置为默认模型,在开启新对话时,直接使用默认模型

3.添加和修改模型的界面,需要有取消和确认按钮,点确认按钮确认添加/修改,点取消按钮可取消添加/修改,点击确认或取消后可以返回“模型管理”界面

4.在添加和修改模型的界面,增加“备注”字段,可自行填写,并在对话窗口右上角的模型切换按钮上显示备注名和模型名

5.开启新对话时,直接使用默认模型

6.在对话中允许用户切换模型,模型切换按钮放在对话窗口右上角

6、修改过程中,Cursor将操作分为如下步骤:更新AIModel模型,添加备注字段和默认模型标记;创建模型数据库表和DAO;创建模型管理的Respository和Provider、创建模型管理界面、创建添加/编辑模型界面、修改设置界面,整合API配置到模型管理、修改对话页面,添加模型切换功能、修改聊天provider使用当前模型,大概耗时5分钟

7、在测试之前先记录一个关于Flutter开发的知识点:关于这几天在修改过程中频繁出现的DAO、Repository和Provider。

1.DAO(Data Access Object,数据访问对象)专注于数据存储层的读写,是直接与底层数据源交互的抽象层,封装所有数据访问细节,对外提供统一的GRUD(增删改查)接口,简单说就是DAO只负责“怎么从数据库/网络/本地文件拿数据/存数据”,不关心业务逻辑

2.Repository(业务数据仓库)是“业务层与数据层的中间层”,聚合多个DAO/数据源,封装业务逻辑,为上层(UI/Provider)提供统一的业务数据接口,简单说就是Repository负责“什么时候/从哪里/拿什么数据”,是数据的“调度中心”

3.Provider(状态管理工具)是“UI层与业务层的桥梁”,管理应用的状态(如用户信息、页面数据、加载状态),并将状态分发给UI组件,实现“状态变化——UI自动刷新”,简单说就是Provider负责“管理UI需要的状态,让UI能拿到最新数据”。

4.这几个概念之间的关系是:UI依赖Provider,Provider依赖Repository,Repository依赖DAO,分层设计本质是为了降低耦合,提升代码的可维护性

8、后续再测试今天新增的功能:多模型管理和切换、联网搜索、回收站、深度思考,测试正常后,还需要补充的细节包括流式输出、回答和收藏内容的Markdown渲染、模型测试、消息时间显示等等

DevLog:2025年12月9日

1、昨天在使用Flutter重写ChatWith时,一直无法成功构建,即使用Cursor提供的终端命令也无法打开应用,同时在修改过程中,Cursor给我创建了大量的.md说明文档和.sh安装脚本文件,只是在告诉我应该怎么做,而不是像之前那样直接进行修改

2、打开一个新对话,再让Cursor继续修复Xcode报的问题,并且看看这些.md和.sh文件是否有必要保留,于是询问Cursor:我之前用Flutter重写了这个应用,但一直构建失败,提示:Command PhaseScriptExecution failed with a nonzero exit code,并且在重写过程中,文件夹里多了很多.md和.sh文件,这些文件是否可以删除?

3、Cursor修复了构建失败的问题,认为构建失败不是因为PhaseScriptExecution脚本问题,而是代码编译错误,包括Message类问题、CardTheme类型错误、类型声明错误、缺少导入等,然后清理了.md和.sh文件共23个,然后在Xcode中尝试构建,竟然真的构建成功了

4、但是出现了很多的错误提示,基本都是Stale file ‘/Users/jinlei.wu/Documents/GitHub/ChatWith/chatwith_flutter/build/ios/Debug-iphonesimulator’ is located outside of the allowed root paths.,看这个提示信息,像是这个文件的路径错误?Clean Build Folder后解决,并且可以成功构建

5、决定让Cursor删掉/Users/jinlei.wu/Documents/GitHub/ChatWith/目录下使用Swift原生构建的应用,只保留使用Flutter构建的应用

6、继续构建并测试功能,首先就是点击右上角的设置按钮,设置界面里是空白的,提示“错误:Exception: SharedPreferences not initialized”,所以也没有办法添加模型,测试对话等一系列功能,Cursor认为问题原因在于preferencesStorageProvider是同步provider,但依赖异步的sharedPreferencesProvider,当SharedPreferences尚未初始化时,preferencesStorageProvider会抛出“SharedPreferences not initialized”异常,修复之后重新生成了代码,现在可以看到设置界面了,以后再添加模型试试能否正常使用

7、这几次构建测试,总觉得应用启动速度好慢,后面还需要给应用增加多模型管理和切换、联网搜索、回收站、深度思考、流式输出、Markdown渲染等功能,又是一个不断增加功能、测试功能的过程

DevLog:2025年12月8日

1、继续上周对移动端ChatWith的修改(或者说重写),用跨端开发框架Flutter替换Swift,“我需要你按照你的建议,帮我完全迁移,并且使用你推荐的技术栈”,Cursor列举了如下步骤:

1.创建Flutter项目结构和配置文件

2.实现核心数据模型(Message、Conversation、AIModel)

3.实现数据库层(SQLite+DAO)

4.实现API服务层(OpenAI流式输出)

5.实现Riverpod状态管理

6.实现UI层(启动页、主框架、对话列表、聊天界面、收藏、设置)

7.实现Markdown渲染和主题系统

8.配置全屏显示和平台特定设置

2、Cursor只用了十来分钟就写完了数十个文件,但接下来还需要我安装Flutter SDK、进入项目并安装依赖、生成代码,然后才能运行应用

3、目前涉及的技术栈包括:状态管理: Riverpod 2.5.1、网络请求: Dio 5.4.0、本地存储: SQLite + SharedPreferences、Markdown: flutter_markdown 0.6.18

4、手动下载并解压Flutter SDK之后,我不知道下一步该怎么配置,直接跟Cursor说“我已经下载了Flutter SDK,下一步怎么操作”,它就在电脑里搜索到了Flutter SDK的位置是/Users/jinlei.wu/Documents/Dev/flutter,然后开始配置环境变量,并验证安装、安装项目依赖、生成代码,之后还创建了一个总结文档

5、但不清楚目前怎样在iOS端运行应用,于是询问“怎样在浏览器里打开当前应用?怎样在Xcode中通过模拟器打开当前应用?”,Cursor直接给我提供了两个运行说明文档QUICK_RUN.md和RUN_GUIDE.md

6、按照提示在Xcode中打开RUNNER.xcworkspace,但提示错误Command PhaseScriptExecution failed with a nonzero exit code,Cursor检查后表示是因为未安装CocoaPods(iOS开发必须的依赖管理工具,Flutter的iOS插件需要通过它来管理),虽然它给出了解决方案,我还是希望Cursor能帮我安装,但未能实现,可能是卡在权限或者无法连接GitHub的资源上了?

7、可能还是需要通过终端命令的形式来安装,Cursor给出的步骤如下,中途切换了一下网络,第一步就无法直接下载

1.安装 Homebrew(如果还没有)

/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”

这一步中途切换了下网络,不然无法下载,但依然卡在了“Downloading Command Line Tools for Xcode 26.1”,搜索发现这还不是个例,网上有不少教程都建议这里手动去苹果开发者网站下载安装,然后重新运行这个命令

2.安装 Ruby 和 CocoaPods

brew install ruby cocoapods

第一步完成之后需要关掉终端,重新打开之后再输入这一命令,不然会提示zsh: command not found: brew

3.安装 iOS 依赖

cd /Users/jinlei.wu/Documents/GitHub/ChatWith/chatwith_flutter

cd ios

pod install

cd ..

4.在 Xcode 中打开

open ios/Runner.xcworkspace

8、在上面第三步就卡住了,多次调整后依然无法在Xcode中正常构建,明明CocoaPods已经安装并且可以查到版本号了,但仍然频繁出现构建失败的情况,Cursor建议优先使用Flutter命令运行应用,但也无法运行,提示找不到设备:

cd /Users/jinlei.wu/Documents/GitHub/ChatWith/chatwith_flutter

export PATH=”$PATH:/Users/jinlei.wu/Documents/Dev/flutter/bin”

flutter run -d “iPhone 16”

9、很奇怪的一点是,不知道为啥,Cursor给我创建了大量的.md说明文档和.sh安装脚本文件,而不是像之前那样直接进行修改操作,明天打开一个新对话,再让Cursor继续修复问题,并且看看这些.md和.sh文件是否有必要保留

DevLog:2026年12月5日

1、昨天引入RichTextKit,替换了目前的备忘录模块,但依然未能正常进行构建测试,在Xcode中构建时发现存在两处错误,再次反馈给Cursor并修改后构建成功

2、测试发现目前的确已经可以实现富文本编辑器的部分功能,比如设置加粗、下划线、删除线、文字颜色、字体、对齐方式,但工具栏中的斜体、字号大小,还有一个不知道是啥按钮,点亮和取消都没有看到什么变化,而且需要先选中文字,再从菜单里选“Format——More”才能在窗口底部弹出格式工具栏,感觉不够直观,需要缩减菜单层级

3、反馈后Cursor把工具栏改成了常驻在标题和编辑器之间,但在Xcode中多次构建都存在错误,猜测可能是Composer 1模型的问题?于是把Cursor中的模型切换回了Auto再试,但在修改过程中又把格式工具栏给我改回了自定义的NSAttributedString,测试发现其中的按钮基本都没有用,于是要求Cursor用RichTextKit内置工具栏RichTextFormat.Toolbar替换自定义实现

4、这下RichTextFormat.Toolbar常驻在备忘录详情页的标题和编辑器之间了,但格式工具栏高度有些夸张了,我希望能把第一行(包含加粗、斜体、下划线、删除线、字号)常驻,其他按钮先折叠起来,在第一行按钮后方增加一个向下的箭头,点击可以展开完整的工具栏

5、Cursor在使用RichTextContent的API、RichTextStyle枚举、RichTextAction,并保持与RichTextKit的兼容性的同时,实现了我的需求,工具栏默认折叠,只显示第一行常用按钮,点击箭头可以展开更多选项,效果还可以

6、接下来添加一个支持深度思考的模型,测试思考内容的流式输出和展示是否正常

7、插播另一个话题,在使用Cherry Studio询问“有哪些比较好用的跨端开发框架”时,发现使用Cherry Studio调用百度千帆平台的DeepSeek API时,响应速度和回答速度都非常慢,回答一个问题可能需要四五分钟的时间,但直接调用DeepSeek官方的API就没有问题,看了下我在百度千帆上的费用还有47块多,消耗的速度好慢

8、说到跨端开发框架,DeepSeek推荐用Flutter,支持iOS、Android、Web、桌面(Windows/macOS/Linux),高性能、重热载、组件库丰富、生态强大,缺点在于需要学习Dart语言(有Cursor,这个不算缺点)、包体积较大、Web端体验较差(无所谓,我也没打算上Web端),看起来的确是最符合我需求的跨端开发框架

9、之前移动端的ChatWith一直无法全屏显示,多次修改也无果,决定就用它开刀了,看能否在Cursor里使用Flutter框架,把它改成跨端应用,先搞好iOS端,再搞Mac端

10、询问Cursor如果我想把ChatWith改成用Flutter框架的话,可行性如何,Cursor认为目前应用的功能在Flutter中均可实现,核心功能在Flutter中均有对应的方案,我比较关注本地存储和Markdown渲染,本次存储上,Cursor建议对话数据用sqflite数据库,配置用shared_preferences,Markdown渲染用flutter_markdown或markdown_widget,且Flutter的Markdown包更成熟,但是,需要完全重写,无法复用Swift代码

11、Cursor还推荐了如下技术栈:

核心框架:Flutter SDK(最新稳定版)

状态管理:Provider或Riverpod(推荐 Riverpod)

网络请求:dio(支持流式响应)

本地存储:shared_preferences (配置)、sqflite (对话数据)

Markdown渲染:flutter_markdown

UI组件:cupertino_icons (iOS风格图标) 、flutter_slidable (滑动操作)

并且推荐完全迁移,优点在于跨平台、长期维护成本低,缺点在于需要重写所有代码

12、继续询问,如果按照Cursor的建议完全迁移,并使用Cursor推荐的技术栈的话,让它分析了一下详细的迁移计划和项目结构建议,它直接写了三个文档:FLUTTER_MIGRATION_PLAN.md(迁移计划)、FLUTTER_CODE_EXAMPLES.md(代码示例)、FLUTTER_QUICK_START.md(快速开始),可能Cursor认为我自己会参考这三个文档来开发吧,先这样,接下来让Cursor来进行迁移

DevLog:2025年12月4日

1、今天让Cursor引入RichTextKit,替换目前的备忘录模块,Cursor分成了四步操作

1.添加RichTextKit的Swift Package Manager依赖

2.更新NoteEditView,使用RichTextKit替换当前的Markdown编辑器

3.更新Note模型以支持RichTextKit的富文本格式

4.更新NotesListView以正确显示富文本内容

2、同时对之前的功能进行了调整,比如移除了编辑/预览切换功能,可以直接编辑,支持富文本编辑(加粗、斜体、下划线、字体、颜色等),保留了标题输入和字数统计功能

3、据Cursor介绍,RichTextKit提供的功能还是很丰富的,包括加粗、斜体、下划线、删除线等文本样式、字体和字号设置、文本和背景颜色、文本对齐、图片

4、测试时首先遇到了一个Missing package product ‘RichTextKit’的错误,可能是因为未能正确添加RichTextKit依赖导致的,让Cursor修正了下,今天也没有时间测试

5、昨天刚更新Cursor,今天又有更新了,最新版本号2.1.47,暂时没发现有什么区别

DevLog:2025年12月3日

1、参考ChatWith for Mac添加模型的逻辑,预置一些常用的模型服务提供商,供用户在添加模型时选择,包括OpenAI、DeepSeek、Anthropic Claude、OpenRouter、Google Gemini、智谱GLM、月之暗面Kimi、百度文心一言、百度云千帆、阿里通义千问、阿里云百炼、腾讯混元、硅基流动、火山方舟、自定义,用户在添加模型时只需选择模型服务提供商,就能自动匹配对应的BASE URL,并且都是完整的地址,选择“自定义”时,可以自行填写BASE URL,并且有提示文字“需填写完整地址”,备注、模型名称、API Key仍然需要用户自定填写

2、在修改过程中,Cursor创建了模型服务提供商定义AIModelProvider.swift,并且将新文件添加到了项目文件里,测试发现功能基本正常,然后修改了AIModelManagementView里的几处细节:

1.有两个“服务提供商”,需要删除位置靠下的“服务提供商”,虽然完成了,但目前这里的界面略丑,后面再优化一下

2.模型名称下面的说明文字需要固定为“如openai/gpt-3.5-turbo,可根据需要修改”

3.在模型列表页,左滑菜单中已有“测试”按钮,就不需要再在模型右侧设置“地球”标志了,已经让Cursor去掉了

3、明天再让Cursor引入RichTextKit,替换目前的备忘录模块吧,今天就到这儿了

DevLog:2025年12月2日

1、昨天在引入MarkdownUI替换之前自定义的MarkdownRenderer之后,Cursor未能进行构建测试,虽然也自称检查后未发现语法错误,但今天在Xcode中构建测试发现AI对话核心的文件AIChatView存在多个错误,导致构建失败,先复制给Cursor让它修复下这些错误

2、Cursor在简化了AIChatView的部分代码后构建成功,接下来测试并逐个修改各个模块的问题,先是这两个:

1.添加模型之后,发送消息后收到错误提示:发送消息失败:API错误(404),导致无法正常对话

2.AI模型管理界面缺少对模型的测试机制,需要增加测试机制,点击可测试,确认能正常连接

3、Cursor认为第一个问题是因为缺少URL补全机制导致的,于是修复了URL拼接问题,在用户填写的Base URL后面增加/chat/completions,然后在模型管理界面(包括列表视图、表单视图)添加了测试UI

4、在Xcode中打开发现测试UI工作正常,但我与测试可用的模型对话时,出现AI正在思考中的提示之后,没有收到任何回复,继续让Cursor检查原因并修复

5、Cursor修复了流式解析问题,包括改进流式响应解析逻辑、改进错误处理、增强兼容性等,虽然可以正常构建了,但我测试了两个问题,回答内容都未能完整显示,输出了一部分就停了,并且停止按钮一直未能变成发送按钮(正常的话应该收到所有回答之后停止按钮就会变成发送按钮)

6、Cursor认为问题原因在于流式输出解析顺序和ViewModel中的更新逻辑,前者主要是先检查finish_reason再处理delta,导致最后一块内容可能被跳过,当finish_reason存在时直接break,未处理该条数据中的delta,后者主要是更新频率限制在100ms,可能导致最后的内容未及时更新,同时,为了确保流式输出正确完成,Cursor也做了一些修改,无论finish_reason是否存在,都会在结束时调用onUpdate,即使delta为空,也会更新一次,确保状态正确,isLoading会被正确设置为false,停止按钮会变回发送按钮

7、继续在Xcode中测试了两个问题,这次可以完整显示所有回答内容了,并且停止按钮也会随着输出结束变回发送按钮

8、接下来准备参考ChatWith for Mac添加模型的逻辑,预置一些常用的模型服务提供商供用户选择,包括OpenAI、DeepSeek、Anthropic Claude、OpenRouter、Google Gemini、智谱GLM、月之暗面Kimi、百度文心一言、百度云千帆、阿里通义千问、阿里云百炼、腾讯混元、硅基流动、火山方舟、自定义,然后让Cursor引入RichTextKit,替换目前的备忘录模块

DevLog:2025年12月1日

1、目前ChatWith for Mac的主要问题在于偶发应用卡死问题,之前已经多次修复但一直未能解决,先暂停

2、先把手机端的NoteWith搞一个版本到手机上进行实测,目前的NoteWith还有很多地方需要完善下才能通过TestFlight发布测试版,比如还没有应用图标(需要让ChatGPT给做一套),上次将对话和备忘录改用Core Data存储之后未做实际测试,且还需要引入三方库MarkdownUI和RichTextKit,完善AI问答和备忘录的渲染效果和编辑体验

3、先让ChatGPT给设计图标,这次以蓝色为底色,并且“也需要一些设计感,像上面那套图标那样简洁就可以”,但这次ChatGPT也把“NoteWith”给套到了对话消息的图标里,要求“不要把NoteWith放在对话消息图标里,没有体现出Note的含义”,然后要求ChatGPT基于这张图生成一套用于iOS App的图标文件,可以直接放到项目文件里使用,很快就生成了,图标搞定

3、时隔半个月再打开Cursor,发现它推出了自己的模型Composer 1,据称生成速度相比同类模型快四倍,且目前可以免费使用,决定使用它来为应用引入三方库MarkdownUI和RichTextKit

4、先引入MarkdownUI,指令“我需要为当前的应用引入三方库MarkdownUI,用于AI问答内容的显示效果渲染”,Cursor指出需要先添加Swift Package Manager依赖,再更新代码以使用MarkdownUI渲染AI回答内容,在引入MarkdownUI之后更新了AIChatView,以使用MarkdownUI来渲染AI回答内容,并且相比之前自定义的MarkdownRenderer增加了代码块、行内代码等样式,接下来需要在Xcode中打开项目,MarkdownUI会自动下载并集成,AI问答内容将使用MarkdownUI进行渲染

5、Composer在执行这次修改时速度的确很快,但在修改结束后未能进行构建测试,要求构建之后仍然不行,说是“命令行构建因模拟器配置问题无法完成,但依赖已成功解析,代码语法检查通过,项目配置正确,建议在Xcode中直接构建和运行,Xcode会自动处理模拟器配置”

6、然后打开Xcode,发现模拟器又要更新版本至iOS 26.1,需要下载8.32GB,看来我的确是有阵子没有用Xcode运行iOS应用了,而且貌似在新的系统版本下载完之前无法进行构建测试,只能等了,看今晚能不能把模拟器下载完,明天再构建测试

7、想尝试添加一个自定义的模型,在Cursor的设置中,目前预置的模型包括Composer 1、Grok Code、Kimi K2,并且可以通过填写API Key等信息快速添加OpenAI、Anthropic、Google、Azure、AWS Bedrock的模型,有一点之前没有注意,就是如果要使用其他兼容OpenAI的模型的话,可以开启“OpenAI API Key”,填写Key,并打开Override OpenAI  Base URL修改API地址,然后在上方找到Add Custom Model填写模型名称,我试一下OpenRouter的Claude Sonnet 4,不知道为啥加不上,感觉添加模型不是很方便

8、上周看Trae.ai官方公众号推送了文章说TRAE SOLO已经登陆中国版,并且可以免费使用,今天更新了下Trae,据介绍,SOLO 模式集成包括 IDE 在内的多种工具。你只需表达需求,它就会基于目标主动推进完整开发流程。

-SOLO=The Responsive Coding Agent,可以让你直观了解智能体正在处理的内容——从文件、工具到完整的工作上下文,它会随你的操作和变化即时响应,始终与你的工作流保持同步。

-从清晰的规划开始,与子智能体协作,将复杂问题拆解为更为聚焦的任务。借助完整代码上下文进行迭代、重构与优化,实现高精度的工程化执行。

-自动将长对话整理为结构化的任务流,清晰呈现执行路径。所有改动统一汇总在代码变更视图,配合上下文状态统一展示,方便回溯与协作。

介绍了这么多,也没有看出来它到底和之前、和Cursor有什么不同,后面再实际测试看看吧

DevLog:2025年11月17日

1、继续修正之前的问题,并且增加一些细节,首先是数据统计功能,对Cursor说:我需要在设置中增加针对每个模型的数据统计功能,显示自从该模型被添加以来的对话数据量,包含输出Tokens和输入Tokens,这一修改涉及Core Data模型、AIService、DataManager和AIModelManagementView

2、修改后测试发现AIModelManagementView里显示的内容有些多,比如Base URL这一行其实没有必要在这里显示,数据统计功能现在像是一个表格,改成单行就可以了,继续让Cursor修改

3、测试过程中发现对话时偶尔会遇到点击发送按钮后应用卡死的情况,继续让Cursor排查问题,Cursor进行了添加防止重复发送机制、优化Core Data操作、改进错误处理、减少不必要的操作等改进,但仍然没有解决问题,我在打开应用后,打开一个有历史对话记录的对话,输入问题并提交后应用就会卡死,可能是加载历史对话记录导致的卡顿?Cursor优化了处理大量历史消息时的性能问题,并且优化消息的payload构建,包括预取数据、减少faulting、优化排序等等操作

4、再次测试,首次打开一个有对话记录的对话并且提交问题后不会卡死了,但切换到另一个对话并且提交问题时又卡死了,Cursor继续优化流式响应处理,但依然存在应用卡死的问题,甚至打开应用后,打开一个已有历史消息的对话,应用就会被卡死

5、再次修改时,Cursor采用了分批处理消息(每批处理50条消息,避免一次性处理过多)、异步执行、预取优化等操作,并指出卡死时因为打开有大量历史消息的对话时,应用会一次性处理所有消息,长时间占用主线程,Core Data faulting导致同步IO操作,且排序操作在处理大量数据时耗时,现在我看见Cursor这种煞有介事的解读都已经麻木了,AI对自己的思考和操作都非常自信,但实际结果可能并没有多么好,实测果然还是会卡死

6、决定先绕开这个问题,将应用的对话界面修改成每次打开应用时,默认用模型列表里的第一个模型开启新对话,这样应该能避免一打开应用就加载历史对话导致的卡死问题,修改后的工作流程变成了:应用启动时,AIChatSessionListView出现——检查是否有模型配置——如果有模型,使用第一个模型创建新对话——自动选中新对话,用户可以直接开始聊天

7、修改之后实现了我的需求,但我发现目前应用的流式输出好像又出现了问题,像是每次跳出来一两句甚至一两段,Cursor分析后表示这是因为之前使用定时器延迟更新(0.12秒),导致内容在buffer中累积,每0.12秒才更新一次UI,于是将content和thinking内容改成了立即更新,不再使用定时器延迟,tavilyResults也改成了立即更新,这样可以实现接近逐字显示的平滑输出效果,明天再测试下看看

DevLog:2025年11月7日

1、今天再次遇到了用ChatWith for Mac对话时应用卡住的问题,但强制退出、重新对话时又能正常对话了,猜测可能是因为单个对话中内容比较多时,应用还未加载完成就提问,就会导致应用卡死?而且我还发现在不同对话间切换时,有时不会直接跳到最新的对话底部,有时还需要滚动一下才能看到对话内容,体验上也不够统一,继续优化,并且需要把停止生成按钮、快捷键支持、代码块复制、消息时间显示、数据导出功能、使用统计这些功能加进来,测试基本完善后,更新版本号为v0.3,移动端NoteWith的开发暂停

2、向Cursor反馈了这些问题,询问是否是因为内容加载机制导致的,Cursor分析后表示的确和对话内容加载机制有关,主要包括“流式更新时频繁遍历Core Data关系”和“每次保存都整表刷新会话列表”,建议拆分保存和刷新逻辑,减少loadAISessions()调用频率,或换成增量更新,同时在切换会话和流式结束后再合适地触发滚动,避免“滚动到底部”信号在数据还没稳定时被打断

3、具体操作上,需要先重构流式消息的更新方式,再优化Core Data刷新的节奏,修改一次之后依然存在打开对话窗口时不自动滚动到最新对话底部的情况,再次让Cursor修改之后可以自动滚到到最新对话底部了

4、接下来开始增加一些小功能,包括停止生成按钮、快捷键支持、代码块复制、消息时间显示、数据导出功能、使用统计,先增加停止生成按钮(发送消息后、正在回答时发送按钮变成停止生成按钮,点击可以停止生成)、消息时间显示(显示绝对时间),这两个功能都在AI对话界面里,其他功能稍等

5、修改过程中发现,今天Cursor的对话的语言风格突然变了,可能是Auto模式换成了另一个模型?而且也不会根据我之前的要求自动进行构建测试了,甚至在我要求进行构建测试时,也会出现因为权限问题导致的构建失败,挺奇怪的

6、修改之后测试发现已经有了停止生成按钮(但未测试)和消息时间显示功能,连续询问了三个问题,前两个问题都可以正常回答,但第三个问题在点击发送后应用就卡死了,我提交了调试信息,Cursor再次进行了节流流式更新、结束时一次性收尾、降低Core Data压力等优化,这次依然没有自动进行构建测试,那我只有自己继续测试了,连续多轮对话看是不是还会被卡死

7、连续问到第三个问题时应用依然会卡死,再次让Cursor修改,流式输出过程中只往缓冲区追加字符串,不直接操作Core Data,用定时器把写库和UI刷新节流到120ms等操作,这样每条回复只会做少量大块复制,避免了第三次对话时的主线程卡顿(当然这都是Cursor说的,具体体验如何还得看测试结果),再次测试,打开上次因卡死未收到回复的对话时也被卡死了,这次Cursor进行了清理空白AI消息、修改滚动逻辑、思考内容默认折叠(我还是更希望默认展开)等操作,再次测试,切换对话、切换模型后提问时依然有问题

8、这两天对ChatWith应用卡死问题的修改不是很顺畅,开始反思到底有没有必要在同一个对话里切换模型,对这种操作的支持,可能增加了应用的复杂性,如果增加一个默认模型机制(其实一开始是有的,但我给去掉了),每次创建新对话时就直接用默认模型,或者在新建对话时即要求用户选择模型,在一个对话中只允许使用一个模型,可能会更简单一些,但我最初借鉴的Chatbox和Cherry Studio,的确都支持在对话过程中切换模型