MCP协议使用JSONRPC作为底层数据层的传输协议. 这是一个及其简单明了的协议, 官方定义在这儿: https://www.jsonrpc.org/specification

简单说明:

  • JSONRPC是客户端向服务器发起一个请求Request, 服务器返回一个响应Response.
  • 客户端发起的请求有id时, 服务器必须响应并带上id, 如果客户端发起的请求没有id, 则这个请求是一个"通知", 服务器不需要响应.
  • 服务器的响应中必须有id, 如果这个id是null, 则说明客户端给的id有问题
    request格式:
    {
    "jsonrpc": "2.0",  // 必选, 值必须是"2.0"
    "method": "subtract", // 必选, 值为string
    "params": [42, 23],  // 可选, 按具体method的要求
    "id": 1 // 要返回值时必选, 不要返回值是必须省略
    }

    response 成功时格式:

    {
    "jsonrpc": "2.0", // 必选, 值必须是"2.0"
    "result": 19, // 成功时必须有, 失败时必须没有
    "id": 1 // 必须有, 与客户端request中一致
    }

    response 失败时格式

    {
    "jsonrpc": "2.0", 
    "error": { // 失败时必须有, 成功时必须没有
      "code": -32601, // 必选, 为整数. 其中从-32768 到-32000 范围内的错误代码被保留用于预定义错误
      "message": "Method not found" // 必选, 为string, 一句话描述错误.
    }, 
    "id": "1" // 必选, 解析不了client发来的id时候返回null
    }

    更多示例请看官方文档. https://www.jsonrpc.org/specification

一个阳光明媚的清晨,小猫从睡梦中醒了过来,迷迷糊糊的睁开了眼睛。忽然他发现一只蝴蝶停在房间的墙上。蝴蝶长得很漂亮,身上闪着五颜六色的光。
小猫说:“蝴蝶蝴蝶,你真漂亮!你是从哪里来的呀?”
蝴蝶说:“我是从那边的大森林飞过来的。”
小猫说:“我知道,那是古代的魔法大森林!你一定会魔法吧?”
蝴蝶说:“那边有上千年的魔法还有我刚学的新魔法你要不要一起试试呀?”
小猫说:“好呀好呀那我们一起去大森林玩吧!”
蝴蝶说:“那好我带你去。”蝴蝶在空中转了一个八字,身体变大了数倍,让小猫骑在他的背上,一下就飞到了空中。
时间好像倒流了数亿年,他们来到了远古时代的大森林。这里长着各种小猫没有见过的奇花异草。有高耸入云的大树,还有长得像蚂蚁一样大小的小鸟。
蝴蝶看着小鸟,看好像有点害怕。蝴蝶说:“不用害怕这里的日常就是这样的。”
小猫说:“你带我参观一下吧!”
小猫仔细的瞧了瞧森林里的植物和动物,蝴蝶一边飞一边给他介绍这里真的很漂亮又好神奇,很快一天就过去了。
天很快就黑了。“我们回去吧!”说完小猫和蝴蝶就在一处大榕树下告别了。

看了最新一期的罗永浩的十字路口与刘谦的访谈,有感几点:
1、刘谦说努力没那么重要,运气占90%。他说出这个我就相信他说的话都是真的。与我运势学相通。很巧,这和马斯克说的努力10次成功一次的比例概率一模一样。
2、刘谦就此得出第2点结论:享受创造的过程而不是追求成功的结果。因为成功的结果可能性在10%以内,甚至现实往往还要更低得多。并且把这一点放在了孩子的教育上。与此同时他又说了两个例外,一个是不善交际的他做街头魔术必须要与各色人等交谈,另一个是直播带货,这两天对他来说言语方面成长很多。
3、外表和包装真的非常重要,尤其对一个刚刚起步的个体来说。刘谦说他花1万多人民币买套西装,在网站不发达的时候自己做网站还包装出好几个虚拟工作人员来伪装自己的一人公司。而且这个习惯一直持续到现在,他的外在形象包括香水发型衣服全部要自己操办不放心交给别人。这让我想到迈克尔杰克逊、乔布斯都是极其注重外观的。我看不上的那些 html css动画却真的是产品非常重要的一部分。
4、刘谦反复讲了好多次让他的观众感受哇哦一刻,甚至这一刻可以在他的一生中反复跟别人去诉说,变成一个人生的重要经历。然后魔术师为了这一刻苦练多年、准备良久。不能给别人留下这一刻就绝不出手。我想这一刻就是人生的幸福体验。人生留在脑子里值得回味的幸福体验其实很少,无论做任何一个职业,如果能给别人留下一刻的幸福体验并且记住一生那其实是非常了不起、非常有意义的事情。我觉得这可能才是艺术的定义:给别人留下铭刻一生的体验。一个产品如果能做到这一点那他就是个艺术品。

微信小程序云函数超时的问题。微信小程序,云函数有几个超时的问题。其中1个是访问cloud api的时候,这个是可以在云函数端cloud.init的时候设置。但是还有1个调用云函数超时的问题。每次调用函数运行的最长时间不能超过3秒钟。如果超过,则会返回超时。 1般情况下,只有几100毫秒就可以完成云函数的调用,但是如果调用第3方api的时候,就可能因为第3方api处理时间过长导致超时。
让ai给我找了很多办法去延长这个超市时间,但似乎都无法延长。最后只有不使用await调用,直接进行返回,才能避免。

菜鸟的教程不错,很适合做快速入门参考。https://www.runoob.com/r/r-tutorial.html
首先不要把R语言看成正常的通用编程语言,像C/C++/Java/Js那种,而是看做特定用途的语言。虽然不像是HTML/CSS这两种语言形态那么极端。可以把R语言看成是升级版的Excel函数库,当然不是一星半点的升级了。不过,你想象R语言在操作数据表有一些语言层次的支持和天然的优势就对了。
整体语法上和非严格模式的JavaScript比较相似,在此基础上讲最重大的几个区别:

  • 与多数语言不同,.是合法的变量名字符,访问一个对象的子元素要用$
  • 与多数语言不同,安装包install.packages()、修改工作目录getwd() setwd()全在语言内,就好像本身是系统脚本bat或者bash
    与Js相似又有区别的点:
  • =可以用来赋值,但这个是后来才加的,赋值符号的原住民是<-->,是的,还能向右赋值。
  • 语句尾部不用任何符号
  • 打印是 print()
  • 函数形参接受类似python的形参名=形参值的方式

用管理员打开cmd, 运行:

# 输入
net stop MariaDB
# 输出
MariaDB 服务正在停止...
MariaDB 服务已成功停止。

手动运行mysqld服务, 打印输出并跳过权限表的检查

mysqld.exe --console --skip-grant-tables

新开一个cmd,使用mysql无密码登录:

mysql -u root

进入mysql终端, 重置密码:

FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

切回mysqld的管理员cmd窗口, Ctrl+C结束mysqld运行, 启动mysqld服务:

net start MariaDB

测试新密码登录:

mysql -u root -p

目前来看云函数是不行的,但是函数式云托管可以。sse和websocket都需要运行在云托管或者函数式云托管中。
https://docs.cloudbase.net/cbrf/intro
似乎函数式云托管支持sse也是为了大模型:
https://docs.cloudbase.net/cbrf/example#%E4%BD%BF%E7%94%A8-server-sent-event-%E6%8E%A8%E9%80%81%E6%B6%88%E6%81%AF
官方也给出了与云托管和云函数的对比
https://docs.cloudbase.net/cbrf/vs
但是,函数型云托管的sse和ws实例都是通过context传入的。如const sse = context.sse(), const ws=contex.ws, 对于第三方库里已经封装了sse方法的(如mcp官方库 @modelcontextprotocol/sdk), 似乎就只有去修改官方库源文件才能做到兼容吧? 这样多少有些得不偿失的感觉. 此时,似乎更应该去使用正常的基于容器的云托管.
价格问题. 有两个官方文档 第一个https://cloud.tencent.com/document/product/876/113602 是对云托管的计费, 第二个 https://cloud.tencent.com/document/product/876/120342 是云托管与标准计费项的换算.
那么最重要的一点就是云托管的容器实例是持续运行还是调用以后就下线的. 从 https://docs.cloudbase.net/run/develop/developing-guide 这儿看: 服务必须是无状态服务,不能依赖永久性本地状态。这是为了能够进行水平的自动扩缩容。, 应该是调用后就下线的. 另外在 概述中也提到, 实例数量会根据请求量自动调整,无请求时可缩容到 0,不产生费用。, 这点应该可以大大降低实际费用.

AI 创作中的版权难题
在 AI 的创作中,往往会遇到版权问题。因为 AI 是模拟了一个人物,如果这个人物是一个比较著名的人物,那么他的形象、他的声音都会存在版权难题。这也许就是为什么很少公开的模拟某一个具体的现在存在的人物形象。即便是虚拟的人物,由于这个虚拟人物的归属与某一个特定的公司,那也存在版权的问题。要规避这个问题,可能只能去创作历史人物,这个人物你如果有一些现代的演绎,比如说在电影、电视剧中曾经被人扮演过,那么他就会形成一个认知,这是这个人物的形象,或者他的声音应该是什么样子的。那假如说要规避它的这个已经认知的声音和形象,就需要重新去配音和重新去生成形象。按照现在的 AI 绘画的水平,它的形象的生成很难一次性就生成自己想要的那种样子,就会出现反复多次的修改的情况。会浪费必要多的时间和精力,当然这已经比你请人去从头开始绘画好很多了,声音也是如此。如何才能仿照书不同人的声音,老年人的小孩、女人的声音,正好又让他去符合自己心目中的历史形象,是一个很大的问题。这里也估计有反复尝试,试错的过程,会使一个形象的生成,包括他的头像、声音等等都需要花费比较巨大的时间。这和简单的生成一个人物的背景提示词相比,可能就有比较大的时间成本上的差异。

AI编程到今天,应该用了已经快一年时间了。慢慢的逐渐考虑它用于比较复杂的项目。
什么是复杂的项目?

  • 人工智能要理解定制的框架、开发库,而不是公开的那些。由于定制的框架和开发库缺乏公开文档,在人工智能的训练过程中,肯定不会有任何相关的资料做训练。如何能正确的使用这些框架和开发库,这是第1个复杂所在。
  • 人工智能要理解ui界面的设计,并且精确地按照涉及生成软件界面。正常情况下,ui界面一定是使用画图工具来做的。但是人工智能做ui界面,首先就遇到了内容一致性问题和将文字置于图像上的问题无法完美解决。这是第2个复杂所在。
  • 人工智能对文档中缺乏的部分,会通过幻觉自作主张的进行脑补。并且以脑补的内容作为基础填充代码的其他部分。如果没有早期发觉,它可能会污染项目的很多代码文件,导致代码最终难以修复。这是第3个复杂所在。
  • 一旦项目中的文档代码过多的时候,实现一个功能就需要引入非常多的内容作为参考才能开发。在人工智能上下文token有限的情况下,可能会导致人工智能难以正确回答。并且给人工智能输入过长的上下文会导致其注意力不集中,最终并不会完全遵循上下文的内容,甚至会遗漏很多部分。
    尝试去实现复杂的项目,就要解决上述的问题。
  • 对于定制的框架和开发库,可以先让人工智能去阅读整个开发库,去生成对应的开发文档。后面通过上下文带入开发文档,方便开发。还可以先写一个框架代码,提前将定制的库引入,这样人工智能会先阅读框架代码。并去顺着框架代码阅读引入的库。但对于api调用这种情况,还是要从文档入手。或者先让人工智能写一个api调用的库,再去写其他代码。
  • 对于现阶段人工智能还不能很好地生成图形ui设计的情况下,可以先让他设计文字形式的ui图。在文字图中标注ui元素的长宽。
  • 对于幻觉脑补,则需要对人工智能生成的代码进行立即测试,及早发现问题,避免扩散。避免生成不能测试的代码。现在还好的是,多数ai编程工具可以回退。
  • 对于引用上下文过多的情况,可以先进行模块化划分。已经划分模块的,可以将较大的模块划分成更小的模块。在每个模块中引用相对较少的上下文,并且在当前模块中实现一个较小的接口代码,其他模块引用这个接口代码,避免大模型每次都需要阅读模块代码的所有细节。
    总的原则是要把复杂的项目拆分成大模型可以很好遵循的小项目,小项目的标准是引用的上下文要少,实现的代码要少,少到大模型可以很好遵循为止。当然目前这个度还不是特别好把握。

应该坚持用AI编程吗?
是的。我发现一个最大的好处,尤其是对于独立开发者来说,AI编程总会用一些让你从未见过的、令人惊喜的语言特性或者函数。因为一个人的编程习惯容易固化,越早学习一种编程语言,越习惯用这种语言的早期风格。而如今编程语言的进化日新月异,新的语言版本带来了新的特性,而自己由于对旧模式得心应手,也就不会在关注和使用。对于第三方库来说更加明显,一般都是到了某个函数需要弃用、或者弃用以后才会去想办法找新的替代,也就是不出问题就不会去查文档的。比如我看到好多人写JS仍然喜欢用callback回调地狱处理异步函数, 各种括号真得深入地狱十八层了,也没有使用promise风格;我自己一直很喜欢使用promise,却不知道css标准早已经支持了变量var和计算calc,以为这个还是其他第三方CSS扩展如SCSS/LESS才有的功能(因为了解SCSS和LESS太早了);也是AI帮我知道了页面栈获取函数getCurrentPages其实有超强的能力,因为栈中页面的所有函数包括setData都可以调用而且起作用(即使页面是hide状态)。新的语言特性让代码变得清爽简洁,自然也能节约大量时间,这是从AI编程可以学到的。
另外, AI处理页面UI确实速度又快又好, 不过有些情况AI会考虑不到, 如微信小程序自动注入一些CSS, 这些需要在和AI的配合中逐步写入它的规则中。

看了把科学带回家的一篇文章名字叫:为什么在沙发上睡着很容易,在床上睡着很难。我有一个洞察是:睡不着的原因并不是脑袋里想事情,而是对未知的焦虑。相反来说,能睡着的原因是略带新鲜的完全掌控感。
人的大脑几乎是无时无刻都在想事情的,很少情况会脑袋空空如也地发呆。即便对于躺倒就睡的人在躺倒的前一刻,至少也想着要盖被子,枕枕头。而现代人的生活一般都是连续的。今天应有未做完的事情,需要明天继续做。明天怎么完成这个事情的方法,今天还没有想出来。因为工作是充斥了整个白天一整天的最主要的事物,所以到了晚上睡觉前,那些没有完成的事情就会在脑海里翻转出来,寻找解决方案。但无论你找得到方案还是找不到方案,都需要第2天白天去实施,没法躺在床上尝试的。这就意味着你无法检验这个方案到底是否可行。所以最终不管你找不找得到方案,都会焦虑的睡不着。因此归根结底,你在睡觉前脑子里想的这个事情是无法获得完全掌控感的。
所以这里的第1个洞察就是要获得完全掌控感。
那么为什么要略带新鲜呢?如果在思考的事情非常乏味,很容易丢失注意力,而转回到白天的工作上去。如果思考的事情。非常新鲜有趣,会导致自己忍不住要持续的想下去,也会睡不着。
这里就有第2个洞察,略带新鲜,目的是牵引注意力在完全掌控感之中。同时又不让注意力沉浸在新鲜感中。
由于新鲜是相对的。所以同一种方法可能对不同的人有不同的适用。

由于小智使用了opus编解码音频,而在xiaozhi-esp32-server中,使用了libopus.js进行音频解码。
libopus.js的代码经过压缩,仍然有825K。由于微信小程序不支持opus,以前我试图用AI将libopus改为支持微信小程序环境,然而失败了。以前以为是代码过大的原因,今天才发现,除此之外还有libopus.js使用了asm.js的原因。
asm.js在2013年由mozilla在firefox中提出并实现,其他浏览器也有实现,但似乎支持度一般,也不是正式的JS标准。asm.js以"use asm"开头,后面使用js的子集代码,去掉了js动态语言部分,加载时会先编译再运行来提高运行速度。
其他浏览器不在强力支持的原因是,asm.js后来在2015年演化为W3C标准制定的WebAssembly, 提出了浏览器中运行编译后二进制代码的方式和二进制.wasm文件。由于wasm和js同等地位且wasm可以被js调用,并且wasm可以由多种语言编译而来,得到了众多浏览器和node.js的广泛支持,所以asm.js逐渐被淘汰了,现在浏览器中写asm.js代码,能用但是会提示已经被deprecated了。
不同语言编译为wasm的编译器不太一样,C/C++最著名的是emscripten, rust是wasm-pack,其他语言也有,但是似乎不如这两个这么流行。可能是C/C++/Rust本身就是最快的几个语言了,其他语言也许编译后的效率比不上。emscripten历史比较悠久,在asm.js还流行的时候就可以把C/C++编译为asm.js代码了.

如果你曾经把小程序的开发切换为多端应用的开发方式,那么即使你切换回普通小程序的开发方式,仍然会出现多端应用的某些标记已经在你的项目中生成了。主要增加了project.miniapp.json文件, 在project.config.json文件中增加了"projectArchitecture": "multiPlatform"配置项。
在小程序打包上传的时候会增加一个分包,名字叫做 /donutAuthorize__/,可以在详情-基本信息-上次上传/预览中看到。
然而你搜索遍整个项目都不会找到donut的一点点信息的,也不会提醒你审核问题。然而你在发布后审核会以你提前获取了用户的昵称、手机号码、头像为理由驳回你的申请。我提交了三次,其中有一个比较负责的审核给我截了图,截图中显示我的小程序获取你在当前小程序的登录态信息。下面有个说明:

说明
将移动应用和多端应用绑定即可消除该水印;如已绑定移动应用,需在开发者工具中切摸到小程序模式重新提交小程序代码生成新版本方可消除该水印
这里才有一点点多端应用作祟的线索。

下面是多端问答机器人的回复, 解决了问题. 我找了小程序审核和小程序审核客服都没有能正确回答出来.

我不想用多端模式开发小程序, 向回到单纯的小程序开发模式, 该怎么办

多端问答机器人
若需从多端应用模式恢复为普通小程序开发模式,请按以下步骤操作:

删除配置文件:

删除项目根目录下的 project.miniapp.json 文件(多端应用专用配置)
修改工程配置:

打开 project.config.json 文件
移除 "projectArchitecture": "multiPlatform" 配置项
完成上述操作后,重新打开项目即可恢复为普通小程序项目。该操作不会影响原有小程序功能,但会丢失多端应用特有的配置(如构建模式、多端API等)。

删除app.json中的"miniApp": { "useAuthorizePage": true }配置

注意事项:

操作前建议备份项目文件
若项目中使用过多端专用API,恢复后需自行处理兼容性问题
再次切换回多端模式需重新绑定小程序

都是小端的形式; 以Window Paint.net生成的24位BMP文件为例:
位置|大小|内容
--|--|--
0x0| 2 | BM
0x2| 4 | 文件大小
0x6| 4 | 保留位, 一般全0
0xA| 4 | 像素数据起始位置, 一般为0x36
0xE| 4 | DIB(Bitmap Information Header)头长度(), 一般为0x28
0x12| 4 | 图片宽
0x16| 4 | 图片高
0x1A| 2 | color plane数量, 必须是1
0x1C| 2 | 色深, 24位就是0x18
0x1E| 4 | 压缩方法, 一般全0
0x22| 4 | 图片大小, 一般全0, 因为0x2已经说了文件大小, 减去头部0x36就知道了.
0x26| 4 | 横向分辨率, pixel/meter.
0x2A| 4 | 纵向分辨率, pixel/meter.
0x2E| 4 | color palatte数量, 一般全0
0x32| 4 | 重要颜色使用数量, 一般全0
0x36| n*3 | 颜色像素, 从左下角开始一行一行到右上角. 因为是小端排列,所以是BGR顺序, 每个一个字节. 如果一行不足4字节, 则补0.
像素区域一行补零的方式是: 如宽度为3px的画面, 一行像素为9个字节, 则一行后面补3个0byte, 到12个字节.

https://blog.csdn.net/qq_41126242/article/details/145050324

Nor Flash和Nand Flash

特性 Nor Flash Nand Flash
读写速度 高速,支持随机读写(类似于RAM) 较慢,按块顺序读写
写入速度 较慢 快速
擦除速度 较慢,擦除整个块(约5秒) 快速,擦除块(约4毫秒)
擦除次数 较少,一般为10000次左右 较多,可达100万次以上
可靠性 高,不易发生位反转 一般,易发生位反转,需使用ECC/DCC算法
容量 较小,通常在1MB到32MB之间 较大,通常在8GB到512GB之间
成本 较高 较低
接口 类似SRAM,有独立地址和数据总线 使用I/O总线串行访问
擦除方式 按字节擦除 按块擦除
应用领域 存储代码、关键数据、嵌入式系统等 存储大量数据,如固态硬盘、U盘等
执行方式 支持片上执行(XIP) 需要先将数据读入RAM再执行

硬件连线

Flash Pin MCU--FLash方向 作用
SCK M-->F 串行时钟, 确定Flash工作频率
CS M-->F 片选, 需要交互的时候打开(拉高),用完关闭(拉低)
MOSI M-->F MCU输出/串行输入, 有时候简称SI
MISO M<--F MCU输入/串行输出, 有时候简称SO

此外Flash还有VCC和GND自然不用说, 还有WP(写保护)和 HOLD/RESET(暂停/复位), 这两个一般就拉高处于可写、可用状态, 加起来就8个脚.
还有一种四线SPI的用法加快读的速度(Flash写比较慢也快不了), 叫做QSPI, 此时SI/SO/WP/HOLD都将作为双向IO口与MCU连接. 但多数情况单线就够了.

与Flash的交互通道: SPI的3个寄存器

SPI寄存器 MCU--Flash写入方向 作用
CR M-->F 控制寄存器1~2Byte, 控制Master模式, SPI使能能
DR M<->F 数据寄存器 1Byte, 双向的, 读写都通过这一个. 通常是一串数据包括 1B命令 + 3B地址 + nB数据.
SR M<--F 状态寄存器 1Byte, 读取Flash发来的状态, 主要是看Flash处理完上一条发过去的数据没有

Flash读/擦/写结构

Flash都是必须先擦再写的,否则就写不进去。英文里,为了与普通的写 Write区别, Flash的写叫做Program,所以普通的Write = Erase + Program.
Flash从小到大的结构单位依次是 Page < Sector < Block < Device. Page是Program的最小单位, Sector是Erase的=最小单位. 所以每次写操作是要先在内存中读取并合并至少一个Sector的新旧数据, 擦除并写入的.