最近对AI Agent使用的一些感受
我接触对话型AI比较早,好几年前就开始使用ChatGPT了。但是对AI Agent的使用相对较晚,前不久Open Claw大火的时候才开始接触这个概念。 关于大模型的话,Deepseek刚开源的时候在自己电脑上部署过v1的版本。由于硬件的限制,体验很差,就没有深入的研究。 最开始是使用Cursor,感觉很不错。以前使用ChatGPT来写代码的时候。做的最多的事情就是不断的复制粘贴。现在很方便,它能…
阅读全文Latest Posts
记录技术、生活和一些阶段性的想法。
我接触对话型AI比较早,好几年前就开始使用ChatGPT了。但是对AI Agent的使用相对较晚,前不久Open Claw大火的时候才开始接触这个概念。 关于大模型的话,Deepseek刚开源的时候在自己电脑上部署过v1的版本。由于硬件的限制,体验很差,就没有深入的研究。 最开始是使用Cursor,感觉很不错。以前使用ChatGPT来写代码的时候。做的最多的事情就是不断的复制粘贴。现在很方便,它能…
阅读全文当一个人又写接口又写前端的时候,最大的痛苦莫过于接口改动后还要修改前端项目并重新部署。 以前在项目少、接口不多的时候还没有感觉。现在项目多了之后,改动一个接口就要去使用这个接口的前端项目挨个改。尤其是加了TS之后,还要手动维护类型标注,头更痛了。 我司使用的是YAPI,研究一下发现太重了,并且配置复杂。我找到了一个更轻量、配置更少的解决方案: Ovral。 我的JAVA项目一开始就配置有swagg…
阅读全文之前我Github Action的workflows部署Nextjs项目的流程是这样的:控制服务器拉取代码,打包、构建镜像并运行。 由于打包代码后构建镜像都在我2核2G的服务器上,导致执行这个流程的时候服务器上的其他应用卡顿,有时候甚至会导致服务器卡死。 思索之下决定优化我的部署流程,采用在Github Action打包和构建镜像,服务器直接拉取镜像并运行的方式,大大减轻了我服务器压力。 这个方法…
阅读全文最近正在优化我的博客项目,想好好摆弄一下服务端渲染和SEO优化等。多方研究下最终拍板决定使用Next.js重构我的Vue博客。 一开始我以为会很简单,但实际操作下来仿佛发现了新世界。 从代码架构到部署流程,完全是另外的一套体系。尤其是部署方式,不再是我熟悉的那种“前端打包 - 上传 dist - Nginx 托管静态文件”流程。 现在,我将带大家回顾一下我的项目迁移过程。记录一下 Next 项目与…
阅读全文四月还是没有什么起色,日复一日,光阴慢慢消散了,还是说说五一吧。 刚过完五一回来,开车是真的累人。 这次回家把庭院收拾了一下,吊兰长得到处都是。还记得最初收到两小棵吊兰时,深怕养不活。当第一次看到它开出小白花的时候,心情非常的激动。现在长满了庭院,拔除了大部分,因为要腾出地方来种其他的。 三角梅正是爆花的时候,顶上一片紫红。以前剪了三颗枝条来扦插的,现在已经长出了围墙外面。现在种的地方土比较浅,下…
阅读全文数据库文件就备份在服务器上始终还是不太放心,想到直接做图床用的是阿里云的对象存储,今天折腾一下,把数据库备份也上传到OSS。 备份流程其实挺简单,首先写一个脚本,核心是使用mysqldump将数据备份出来并压缩成一个压缩包,并且删除掉7天前的备份。然后创建一个定时任务,每天凌晨三点自动运行一下这个脚本。而oss的作用就是在备份成功后将打包好的压缩包上传到阿里云oss,这样即使服务器数据全部丢失,我…
阅读全文买的车衣到了,夏天太阳大,怕晒伤座椅。 一个月没有开车,这个月油价涨疯了,油箱里面的油还是7块的,加油站已经涨到10块了。 正为一个月没开车省下了几百块钱而沾沾自喜,洗车的时候被告知脚垫下有积水。 洗完车开到最近的天猫养车门店检查一下,原来是原先给我行车记录仪走线的师傅把我右侧A柱的排水管撬歪了,导致排水管没有对准排水口,水全部流到了坐垫下。 上个月又是雨季,拆车后掺不忍睹。厚厚的一层水,坐垫下方…
阅读全文清明节假期一休息玩,马上又要上班了。最近上班实在感觉麻木了,各种焦虑和压抑。不是因为工作太忙了,而是因为太闲了,让我感到很强烈的危机感。 回到正题,写一下26年第一季度的总结。 平平无奇的工作。 刚从结婚旅行回来,在香格里拉跨年,顺便过了个生日。 过年,今年很热闹。 结婚之后的过年感觉非常疲惫,以前天天躺在家打游戏,现在是每天都开车在路上。 一开始沉迷于域名,认识了大佬论坛。买了有几个域名,但是因…
阅读全文在我的两核两G服务器无数次卡死重启之后,我终于发现了个好东西:Swap。 Swap是什么? Swap 是 “内存不够时的备用仓库(硬盘当内存用)” 正常情况下,程序都在内存中运行。但如果内存不够了,系统就会把一部分“不常用的数据”挪到硬盘上,这个硬盘空间就叫 Swap(交换空间) 如果你加了 swap,内存满的时候,系统不会立刻杀程序,而是先把数据挪到 swap 虽然会变慢,但服务还能活着。 应该…
阅读全文使用Promise,可用于测试按钮loading等
阅读全文官网:[链接] 服务器配置2核2G即可 安装nodejs和npm: 安装openclaw: 启动:,随后根据引导一步步配置即可。 <br / 启动成功后,服务运行在18789端口上,但是不能公网访问。 需要采用SSH 隧道的方式,在本地执行 → 不执行命令,只转发端口 → 本地 18789 端口映射到服务器 127.0.0.1:18789 最后本地访问[链接]即可。 若想不输入密码,只需将本地的公…
阅读全文折腾了一下网站的字体。 第一次用心仪的字体时采用的是霞鹜文楷。 那时候还不太懂这个问题,直接把十多mb的ttf文件扔到网站上了,体验可想而知有多差。后面放弃了,很长时间没有再用字体。 前两天偶然在别人的博客上看到这个原侠正楷的字体,感觉阅读文章时很舒服,所以决心还是折腾一下。 大概思路是将原文件ttf子集化(只取自己用到的字,去除一些不常用的生僻字),然后转换成woff2格式。在网上能找到很多种方…
阅读全文在句子用作谓语的动词,最普通、最常见的动词,用作句子中的谓语。谓语动词和中文中不同,它能够根据不同的状态表示出动作的时、体、气 (即动作发生的时间、动作的状态:已完成还是正在进行、动作的假设和情感等) &x20;谓语动词主要分为五大类,也对应着英语中的五大句型: 1. 无需动作承受者的谓语动词: The rabbit slept. (这里的slept因为没有宾语,所以也称为不及物动词。后面的2\4…
阅读全文最近状态不太好 健身没有起色 理财亏损 - 做事不在状态,虚度光阴 <br / 最近的日子大部分都是: 早上起来,蹲厕所,墨墨上刷10个单词,做一下游戏的日常任务。 胡乱收拾一下踩点上班,早餐有时候吃有时候不吃。 没有多少工作,上班就等着9点半股票开盘。 股票开盘期间也没心思学习,总想着股票的涨跌,所以就刷刷知乎,刷刷视频。 11点早盘结束,开始无聊。肚子饿,等吃饭,也没心思学习。 12点下班吃饭…
阅读全文2025年7月30日晚,暴雨。 雨夜一如既往的让人转眼七月也快过去,马上到八月,还有两个月的时间准备订婚和结婚的相关事宜。 这个月的主题是:炒股和健身。 股票就不多说了,有得有失,具体的都在股票复盘记录中有写,除金钱上的盈亏外也从股市中的波动中悟到了很多人生道理。 健身已约有半个月了,除了刚开始练伤了休息了两天,其余时间风雨无阻,至少也需要在跑步机上出一身大汗。保持着健身和减脂餐,体重体态虽无大的…
阅读全文这是极度想搞钱且付诸了行动的一个月。 首先是学习上,上个月花时间系统的对Typescript进行了学习,这个月也将React官方文档过了一遍。 其次是投资,上周开通了股票账户至今已经炒股了3天。前两日运气好赚了一点,第三天也就是周五亏损。目前战况是盈利了约20元。 然后是副业,在小红书上连续一周进行了每日一次的发文。内容是推荐书籍、影视、音乐。没有涨粉,点赞人数加起来也就一手之数。 这个月对于Re…
阅读全文记录第一辆自行车,喜德盛黑客380 下班心血来潮扫了个共享单车直奔喜德盛线下店。 本来是想看看黑客350的,结果店里没有。看了看黑客380,加点预算直接拿下。(本人程序员,对黑客二字感觉莫名亲近) 前两天骑得屁股超级痛。后面买了坐垫骑了几天,现在拿掉坐垫好像感觉不到痛了。 距离现在买车到现在已经骑行了一周,上班通勤来回十余公里。一开始单程需要四十来分钟,并且腿酸屁股痛。现在只需要不到三十分钟了,并…
阅读全文今天阅读了一下《穷爸爸富爸爸》。才看了第一章就深深被触动了。这本书讲得非常通俗易懂,让我明白“为钱工作”还是“让钱为我工作”两种观念之间的鸿沟般的差距。结合这几年打工的状况,我被深深的带入了其中。 触动之下,我在东方财富开了个股票账户。虽然身边人好像都在用同花顺,但是它的账户要到券商开户,没有自己的券商,让我难以选择。加之我在东方财富旗下的天天基金买过几年的基金,App也很好用,所以就选择了东方财…
阅读全文最近在专研 React 文档,遇到文档中这样的一句话让我陷入了沉思:“在组件主体中声明的所有变量都是响应式的。” 基于 Vue,我对响应式的理解是这样的:响应式变量是被 Vue 的响应式系统(基于 Proxy)追踪的,只要它们发生变化,Vue 就会自动更新视图。比如通过 ref() 或 reactive() 创建的对象,计算属性 computed,甚至是 watchEffect() 等副作用监听器…
阅读全文有些组件可能需要控制和同步 React 之外的系统。例如,你可能需要使用浏览器 API 聚焦输入框,或者在没有 React 的情况下实现视频播放器,或者连接并监听远程服务器的消息。在本章中,你将学习到一些脱围机制,让你可以“走出” React 并连接到外部系统。大多数应用逻辑和数据流不应该依赖这些功能。 当你希望组件“记住”某些信息,但又不想让这些信息 触发新的渲染 时,你可以使用 ref 。 u…
阅读全文Reducer 可以整合组件的状态更新逻辑。Context 可以将信息深入传递给其他组件。你可以组合使用它们来共同管理一个复杂页面的状态。 这里的tasksReducer是我们用于处理tasks的方法,如新增,删除,修改等。 initialTasks是初始化tasks的默认值。 tasks是任务列表、dispatch用于调用tasksReducer来操作tasks。 接下来需要将tasks和dis…
阅读全文通常来说,你会通过 props 将信息从父组件传递到子组件。但是,如果你必须通过许多中间组件向下传递 props,或是在你应用中的许多组件需要相同的信息,传递 props 会变的十分冗长和不便。Context 允许父组件向其下层无论多深的任何组件提供信息,而无需通过 props 显式传递。 这里的1是默认值 这里需要用useContext来使用LevelContext 注意!这个示例还不能运行。因…
阅读全文React 控制 UI 的方式是声明式的。你不必直接控制 UI 的各个部分,只需要声明组件可以处于的不同状态,并根据用户的输入在它们之间切换。这与设计师对 UI 的思考方式很相似。 通俗的说就是根据一个状态来判断展示哪一个组件。 React推荐使用尽量简单但是意义明确的state: 1. 如果两个 state 变量总是一起更新,请考虑将它们合并为一个。 2. 仔细选择你的 state 变量,以避免…
阅读全文state 中可以保存任意类型的 JavaScript 值,包括对象。但是,你不应该直接修改存放在 React state 中的对象。相反,当你想要更新一个对象时,你需要创建一个新的对象(或者将其拷贝一份),然后将 state 更新为此对象。 在 React 中,状态是不可变的(immutable)。React 不会深入比较对象内部的属性变化,而是通过引用是否变化 来判断是否需要更新组件。 Vue…
阅读全文事件处理函数还将捕获任何来自子组件的事件。通常,我们会说事件会沿着树向上“冒泡”或“传播”:它从事件发生的地方开始,然后沿着树向上传播。 如果你点击任一按钮,它自身的 onClick 将首先执行,然后父级 <div 的 onClick 会接着执行。 在 React 中所有事件都会传播,除了 onScroll,它仅适用于你附加到的 JSX 标签。 事件处理函数接收一个 事件对象 作为唯一的参数。按照…
阅读全文React 组件是常规的 JavaScript 函数,但 组件的名称必须以大写字母开头,否则它们将无法运行! 在看到标签时,小写为html标签,大写为自己的组件。 返回语句可以全写在一行上,但是,如果你的标签和 return 关键字不在同一行,则必须把它包裹在一对括号中。没有括号包裹的话,任何在 return 下一行的代码都 将被忽略!不过也要注意:()是(),<\</是<\</,括号只是用于包裹…
阅读全文在上一章我们学习了基础的react语法,现在我们了解一下企业级开发 安装一个构建工具,如 Vite、Parcel 或 rsbuild。这些构建工具提供了打包和运行源代码的功能,提供本地开发的开发服务器,以及部署应用到生产服务器的构建命令。 使用命令npm create vite\@latest,选择React模板,即可创建React应用。 路由决定了当用户访问特定 URL 时显示的内容或页面。你需…
阅读全文当在 React 中调用 useState 提供的 状态更新函数时,React 会触发该组件的重新渲染。也就是说组件的主体部分会再次执行。 Vue在改变某个变量的状态时不会重新执行onMounted。虽然Vue 和 React 都是响应式框架,但它们的更新机制不同。React 是“重新执行组件函数”,而 Vue 是“依赖追踪+局部更新”。 重新渲染 ≠ 重新操作 DOM,React 重新渲染组件时…
阅读全文今天开坑React,本来想看原版文档,奈何英语水平有限。加之最近也许要面试,故先使用中文文档。 本文采用了与vue对照的方式进行对比学习,如果是熟悉vue的人学习起来会更好理解。如果你不了解vue,推荐去看官方文档,也很容易理解:[链接] 按照我的一点印像,react使用js函数return一个html标签,这就是react的组件 React 组件必须以大写字母开头,而 HTML 标签则必须是小写…
阅读全文分享一个好东西,可以在Linux上使用节点 原文:[链接]
阅读全文YAGNI 是“You Ain't Gonna Need It”的缩写,意思是“你不会需要它”。它是一种软件开发原则,来自于极限编程(Extreme Programming),主张程序员应该在明确需求出现后才实现相应功能。这个原则的核心是避免过度设计和预先实现不必要的功能,从而降低复杂性,提高代码的可维护性。 YAGNI 强调在现实需求出现之前,不要实现任何功能,即使你认为将来可能会需要。这样可以…
阅读全文这两部分配置内容繁多,推荐查看原文: 1. tsconfig.json文件 2. tsc命令
阅读全文TypeScript 接受一些注释指令。所谓“注释指令”,指的是采用 JS 双斜杠注释的形式,向编译器发出的命令。 // @ts-nocheck告诉编译器不对当前脚本进行类型检查,可以用于 TypeScript 脚本,也可以用于 JavaScript 脚本。 上面示例中,document.getElementById(123)存在类型错误,但是编译器不对该脚本进行类型检查,所以不会报错。 如果一个…
阅读全文TypeScript 提供了一些内置的类型工具,用来方便地处理各种类型,以及生成新的类型。 这些类型工具都是语言本身提供的,可以直接使用。 Awaited<Type用来取出 Promise 的返回值类型,适合用在描述then()方法和 await 命令的参数类型。 上面示例中,Awaited<Type会返回 Promise 的返回值类型(string)。 它也可以返回多重 Promise 的返回值…
阅读全文映射(mapping)指的是,将一种类型按照映射规则,转换成另一种类型,通常用于对象类型。 举例来说,现有一个类型A和另一个类型B。 上面示例中,这两个类型的属性结构是一样的,但是属性的类型不一样。如果属性数量多的话,逐个写起来就很麻烦。 使用类型映射,就可以从类型A得到类型B。 上面示例中,类型B采用了属性名索引的写法,\[prop in keyof A]表示依次得到类型A的所有属性名,然后将每…
阅读全文TypeScript 提供强大的类型运算能力,可以使用各种类型运算符,对已有的类型进行计算,得到新类型。 注意区分typeof,typeof是用于查看一个变量的类型 keyof 是一个单目运算符,接受一个对象类型作为参数,返回该对象的所有键名组成的联合类型。 由于 JavaScript 对象的键名只有三种类型,所以对于任意对象的键名的联合类型就是string|number|symbol。 keyo…
阅读全文declare 是 TypeScript 中的关键字,用于声明变量、函数、类、模块或类型的存在,但不做具体实现。它的作用是告诉 TypeScript 编译器:“这个东西已经存在了,在别的地方定义了,你就不要再报错了”。 declare 关键字用来告诉编译器,某个类型是存在的,可以在当前文件中使用。 它的主要作用,就是让当前文件可以使用其他文件声明的类型。举例来说,自己的脚本使用外部库定义的函数,编…
阅读全文装饰器(Decorator)是一种语法结构,用来在定义时修改类(class)的行为。 在语法上,装饰器有如下几个特征。 (1)第一个字符(或者说前缀)是@,后面是一个表达式。 (2)@后面的表达式,必须是一个函数(或者执行后可以得到一个函数)。 (3)这个函数接受所修饰对象的一些相关值作为参数。 (4)这个函数要么不返回值,要么返回一个新对象取代所修饰的目标对象。 举例来说,有一个函数Inject…
阅读全文namespace 用来建立一个容器,内部的所有变量和函数,都必须在这个容器里面使用。 上面示例中,命名空间Utils里面定义了一个函数isString(),它只能在Utils里面使用,如果用于外部就会报错。 如果要在命名空间以外使用内部成员,就必须为该成员加上export前缀,表示对外输出该成员。 编译后命名空间Utility变成了 JavaScript 的一个对象,凡是export的内部成员,…
阅读全文任何包含 import 或 export 语句的文件,就是一个模块(module)。相应地,如果文件不包含 export 语句,就是一个全局的脚本文件。 模块本身就是一个作用域,不属于全局作用域。模块内部的变量、函数、类只在内部可见,对于模块外部是不可见的。暴露给外部的接口,必须用 export 命令声明;如果其他文件要使用模块的接口,必须用 import 命令来输入。 如果一个文件不包含 exp…
阅读全文TypeScript 提供了“类型断言”这样一种手段,允许开发者在代码中“断言”某个值的类型,告诉编译器此处的值是什么类型。TypeScript 一旦发现存在类型断言,就不再对该值进行类型推断,而是直接采用断言给出的类型。 对于没有类型声明的值,TypeScript 会进行类型推断,很多时候得到的结果,未必是开发者想要的。 上面示例中,最后一行报错,原因是 TypeScript 推断变量foo的类…
阅读全文enum(枚举)在 TypeScript 中是一个用于定义一组命名常量的工具,它可以让代码更加清晰、可读、可维护。 假设你有一组固定的值,比如一周的七天、订单状态、用户角色、性别等等。用字符串或数字硬编码是很容易出错的,比如: Enum 结构的特别之处在于,\\它既是一种类型,也是一个值。\\绝大多数 TypeScript 语法都是类型语法,编译后会全部去除,但是 Enum 结构是一个值,编译后会…
阅读全文前面的是比较基础的,后面的对我来说就是进阶的了。想要玩转企业级开发,后面的东西必须认真对待了。 有些时候,函数返回值的类型与参数类型是相关的。 上面示例中,函数getFirst()总是返回参数数组的第一个成员。参数数组是什么类型,返回值就是什么类型。 这个时候只能用any来处理了 但是这样的标注,就反映不出参数与返回值之间的类型关系。就算返回一个'123'也不会报错。 为了解决这个问题,TypeS…
阅读全文类(class)是面向对象编程的基本构件,封装了属性和方法,TypeScript 给予了全面支持。 类的属性可以在顶层声明,也可以在构造方法内部声明。 TypeScript 有一个配置项strictPropertyInitialization,只要打开(默认是打开的),就会检查属性是否设置了初值,如果没有就报错。 上面示例中,如果类的顶层属性不赋值,就会报错。如果不希望出现报错,可以使用非空断言…
阅读全文刚试了一下优化OSS 前两天已将删除图床图片时删除OSS图片了。但是还没有实现删除文章时清理文章中的图片。 之前在浏览器访问OSS图片链接的时候会自动弹出下载,原因是出于安全考虑,当您通过Bucket默认域名访问某些文件时,可能会触发强制下载或禁止下载。如果您希望在浏览器中正常预览或下载这些文件,您需要为Bucket绑定自定义域名,并通过自定义域名访问OSS文件。绑定自定义域名不会影响Bucket…
阅读全文interface是对象的模板,可以看作是一种类型约定,中文译为“接口”。使用了某个模板的对象,就拥有了指定的类型结构。也就是说,能用来声明一个对象的结构。 和type类似,但是interface主要用于描述对象结构,不支持直接定义基本类型、联合类型。元组。而type 可以描述任何类型(包括基本类型、联合类型、元组等)。 interface能用extends,可继承多个接口,而type需要用&来组…
阅读全文直接标注: 属性的类型可以用分号结尾,也可以用逗号结尾。 除了type命令可以为对象类型声明一个别名,TypeScript 还提供了interface命令,可以把对象类型提炼为一个接口。 如果某个属性是可选的(即可以忽略),需要在属性名后面加一个问号。 属性名前面加上readonly关键字,表示这个属性是只读属性,不能修改。只读属性只能在对象初始化期间赋值,此后就不能修改该属性。 如果对象的属性非…
阅读全文函数的类型声明,需要在声明函数时,给出参数的类型和返回值的类型。如果没有返回值,可以标注为void 返回值的类型通常可以不写,因为 TypeScript 自己会推断出来。 如果变量被赋值为一个函数,变量的类型有两种写法。 如果函数的某个参数可以省略,则在参数名后面加问号表示。 设置了默认值的参数,就是可选的。如果不传入该参数,它就会等于默认值。 可选参数与默认值不能同时使用。 参数解构 : res…
阅读全文根本特征:所有成员的类型必须相同,但是成员数量是不确定的,可以是无限数量的成员,也可以是零成员。 需要只读数组的时候,只需要再类型声明前加上readonly: TypeScript 将readonly number\[]与number\[]视为两种不一样的类型,后者是前者的子类型。(因为只读数组没有pop()、push()之类会改变原数组的方法) 特殊的是:如果这样写就会报错:const arr:…
阅读全文Js类型:boolean string number object undefined null bigint symbol TypeScript 继承了 JavaScript 的类型设计,以上8种类型可以看作 TypeScript 的基本类型。复杂类型由它们组合而成。 和Java不同,js类型的名称都是小写字母,首字母大写的Number、String、Boolean等在 JavaScript 语…
阅读全文