20260223基于zot registry搭建本地镜像仓库

镜像获取

直接下载

百度云

上传过程记录

从百度云下载

百度云总文件夹: https://pan.baidu.com/s/5U9ZYswxhKohgcmqKvdopPg

通用镜像: https://pan.baidu.com/s/1xYEncWT2WIVNL23bPGA8rw?pwd=py3z

群晖镜像: https://pan.baidu.com/s/1JuQqTgrf9fE46rHpTiWAuw?pwd=hmm2

准备相关文件夹和配置文件

密码文件$BASE_DIR/etc/htpasswd随便找个服务器生成

配置文件$BASE_DIR/etc/config.json内容如下

启动服务

通用镜像

访问

群晖镜像

制作过程记录

群晖Container Manager需要镜像主动声明EXPOSE端口才能勾选web stationd配置,手动修改镜像如下

打包到本地文件上传到百度云

启动命令

手动启动一次后,通过群晖网页修改后续配置暴露即可

访问

参考文档

https://github.com/project-zot/zot

https://zotregistry.dev/v2.1.14/install-guides/install-guide-linux/#about-binary-images

https://zotregistry.dev/v2.1.14/articles/mirroring/#mirroring-modes

https://zotregistry.dev/v2.1.14/general/releases/?h=docker#getting-container-images

20250830算法题解析-偏爱的字符串

废话

最近博客突然打不开了,看了一眼是PHP开始报莫名奇妙的错误。这个博客主题是当年随便从网上找的一个,历经多个PHP和wordpress大版本变化还凑合能正常展示已经非常不易了,中途历经多次魔改和打补丁。原计划是在10周年之前把所有文章彻底重写一次换掉wordpress,但以我这个鸽子的风格看了一眼还有1个月时间显然不现实,所以这次我直接放弃了,直接用官方的模板改了改css就成了现在这个样子。

看了一眼历史记录,我的第一篇博客还是在大学时候联系ubuntu linux搭建wodpress后写的,当时正好是大一的期末即将C语言考试,写了一系列的C语言教程当作期末复习。众所周知我的算法比较弱(相比于栋神或然妞),并且从未在算法上怎么努力过,就这么得过且过了10年,做深度算法的分析屈指可数。印象中比较清晰的只有KMP算法、Levenshtein距离、上班时为了优化聊天室pin消息new红点的算法、为了模仿outlook日程布局设计的排版算法。

前段时间在群里看到有人在讨论一个算法题,我简单分享了思路,但懒得动手。这次正好做个深度解析。顺带一提虽然现在ai编程非常的火,工作的话因为讲究效率优先有时候无需考虑原理,只要结果对就行。但长期来看我的态度还是要磨练下基本功,不然AI错了你根本纠正不回来,所以本次不会使用任何AI补全,完全一步步手动实现再逐步优化。

原题目

https://www.nowcoder.com/practice/294da7ea5f184655a31bf659035fc874?tab=note

视频版

https://www.bilibili.com/video/BV1cChqzqEh8

描述

小李天生偏爱一些字符,对于一个字符串,他总是想把字符串中的字符变成他偏爱的那些字符。如果字符串中某个字符不是他所偏爱的字符,称为非偏爱字符,那么他会将该非偏爱字符替换为字符串中距离该字符最近的一个偏爱的字符。这里的距离定义即为字符在字符串中的对应下标之差的绝对值。如果有不止一个偏爱的字符距离非偏爱字符最近,那么小李会选择最左边的那个偏爱字符来替换该非偏爱字符,这样就保证了替换后的字符串是唯一的。小李的所有替换操作是同时进行的。
假定小李有 m 个偏爱的字符,依次为c1,c2…cm,当小李看到一个长度为 n 的字符串 s 时,请你输出小李在进行全部替换操作后形成的字符串。

输入描述:

第一行输入两个正整数n,m。
接下来一行输入m个字符c1,c2…cm,每两个字符之间用空格隔开,表示小李偏爱的字符。

接下来一行输入一个字符串s。

1≤n≤1e5,1≤m≤26,保证题目中所有的字符均为大写字符,小李偏爱的字符互不相同,且偏爱字符至少出现一次。

输出描述:

输出一行字符串,表示小李将给定的字符串s替换后形成的字符串。

输入:

输出:

说明:

题目分析

我做算法题因为没有限时,所以一般来说我都是先用暴力手段写正确结果,再逐步优化

题目里废话实在太多,翻译成人话就是把后续所有输入都改成指定的几个字母,以最近的为准,如果距离一样用左边的。

暴力版本

加一点优化

根据刚才的运行结果,如果尝试打印寻找过程

注意到每次左侧寻找的距离都是递增的,so优化思路就是不要每次都从头开始搜,如果还没出现新的偏爱字符,那上一次寻找的结果直接+1就是本次搜索的结果,如果距离右侧最新的偏爱字符过半了,那就是右侧的结果。因此之前循环的状态需要记录下左侧和右侧的距离或索引。

TODO 待编写代码

再加一点优化

按上面的思路,如果能提前知道哪些位置是偏爱字符,那么根本不需要逐个字符判断、搜索、替换,可以直接按偏爱字符的位置就能计算最终的结果。你会发现最终结果只和偏爱字符的位置有关,和其他输入的字符无关,你甚至都不需要读入其他字符也能计算出最终结果

TODO 待编写代码

另类思路

按上面所说既然结果和其他字符无关,只需要特殊字符和对应的位置+总字符串长度就能计算的话。实时处理也是可能的,这也是目前AI输入输出常见的表现形式,打字机效果。当输入一个字符后,实时输出最终结果,当发现前几个字符结果不对了,删除前n个字符后纠正回正确的字符。这种算法不需要预处理,但因为无法预知后续输入所以必须有纠正的过程出现。实际实现逻辑只需记录最后一次输入的偏爱字符和当前字符和最后一次输入的偏爱字符距离,即可知道是应该打印最后一次的偏爱字符,还是应该删除前n个距离当前输入的偏爱字符更近的字符。

TODO 待编写代码

20250503jupyter-mcp-server自动化

背景

20250131jupyter自动修改IDEA项目SDK、获取GIT信息

20230429 IaC之IDE,也许是下一个ChatIDE?

在我尝试将jupyter kotlin kernel 内嵌到IDEA的JVM后,用jupyter控制IDEA用了很长时间,但除了utils工具类之外IDEA的openapi和公开的方法基本都是为了UI而编写的异步代码,这在自动化过程中获取返回值非常不方便。我预期的是直接复制粘贴官方源码稍微改改就能用,不想对官方代码做大的结构修改。

继IDEA官方编写MCP后,我发现二月份的时候jupyter也有MCP server了。

datalayer在尝试用ai把jupyter自动化,使用自然语言描述数据处理的请求然后生成notebook并执行python代码,我一看这不正好是我想要的么。

如果我人工能操作jupyterlab完成结果,相比调整kotlin脚本的控制流,我只需要糊一点python代码就能代替我手工操作的部分

原理

jupyter mcp server的代码非常的少,我想要的其实是排除mcp的部分,去掉注解改一改直接就能用

本质上是直接调用了jupyter lab的接口获取websocket,通过jupyter lab的collaboration扩展通道操作notebook

过程记录

安装jupyter lab,注意这里新增了jupyter-collaboration

实测发现之前的安装命令不好使了,日志报错如下

很明显kernel接到了jupyterlab的请求但反序列化失败了,注意到jupyterlab没指定版本

根据上一次安装记录对比版本号可发现,是最近jupyterlab的更新4.4.0时header新增了一个字段,而kotlin kernel反序列化不接受未定义的字段导致,因此降级到4.3的最后一个版本4.3.6

还是记录下版本号方便后续对比

降级后测试原来的功能正常

第一次先使用再建一个独立virtualenv防止破坏环境

按官方文档安装依赖,修改官方的源码作为测试脚本。因为官方是使用独立进程的python kernel运行脚本,而我是要让一个已经运行了的内嵌kernel执行,所以需要指定下当前的kernel_id复用。否则代码会启动一个新的python kernel执行kotlin脚本就和我的预期不符了

既然python文件单独执行是能成功的,也就意味着python kernel也能执行相同的代码,而一个jupyterlab可以同时开启notebook分配不同的kernel。既然如此已经有一个现成的python环境了为什么不直接用呢?因此续尝试合并这个独立的python环境到jupyterlab的python环境

为了防止安装新的依赖破坏现有版本,pip list记录下当前的依赖版本后再安装新的依赖,通过对比安装前后差异可以发现都是datalayer实现的库,这些库用于和jupyterserver交互并且除了websocket没有什么额外的垃圾依赖进来

合并后的安装命令

 

然后就可以尝试将脚本放入另一个notebook中了,kernel如下

执行效果如下

到此为止用python半自动的控制IDEA的目标达成,python代码可以控制IDEA并且能调用IDEA JVM的所有代码,同时执行过程全部可见、可追溯、可重放。这样后续就可以看实际情况逐渐把这个过程的控制权交给AI。
但我没想好的是:当一个程序有能力对自身进行修正的时候,让AI有这么强大的行动能力会不会带来额外的安全问题

后续计划

jupyterlab的启动内置到idea插件中,全自动化整个初始化流程
升级embedded kotlin jupyter core兼容最新的jupyterlab的header字段

参考

https://github.com/dev-assistant/skykoma-plugin-idea

https://github.com/datalayer/jupyter-mcp-server/tree/main/jupyter_mcp_server 

 

20250323postwoman/hoppscotch私有化部署

背景

尝试搭建个私有化的postman玩

视频版见B站 https://www.bilibili.com/video/BV1SDoBYrEjC

准备

一台虚拟机

一个域名

一个SMTP服务器:我用的是qq的,需要一个额外授权码当密码用

安装docker和docker-compose

准备环境配置

注:安全起见SMTP密码在视频发布后会失效

准备compose文件

首次启动

注意首次需要初始化一下数据库

进入后台并试玩

从http://postwoman.hylstudio.local/admin登录完成首次设置后可用

todo

TODO 扩展一种本地的密码登录或CAS登录?

参考

https://docs.hoppscotch.io/documentation/self-host/getting-started

https://docs.hoppscotch.io/documentation/self-host/community-edition/install-and-build

20250201AI应用相关技术调研

背景

20230515LLM笔记

继上次调研后,很久没更新AI相关技术了,这次一并更新。

应用

全本地部署的ai https://github.com/mudler/LocalAI

应用框架

数据索引框架 data index framework

llamaindex

https://docs.llamaindex.ai/en/stable/ https://github.com/run-llama/llama_index

https://docs.llamaindex.ai/en/stable/use_cases/agents/ Property Graph Index可以用neo4j

https://docs.llamaindex.ai/en/stable/module_guides/storing

Vector Stores:Elasticsearch、Lantern、OpenSearch、Postgres、Qdrant

Document Stores:Mongo、Redis

Index Stores:Mongo、Redis

Chat Stores:Redis

Key-Value Stores:Mongo

Note: At the moment, these storage abstractions are not externally facing. https://docs.llamaindex.ai/en/stable/module_guides/storing/customization/

ai agents framework

自动化框架 restack

https://www.restack.io/

agents框架 eko

https://github.com/FellouAI/eko

pydantic

https://github.com/pydantic/pydantic-ai

composio

https://composio.dev/swe-kit/

https://github.com/ComposioHQ/composio/tree/master/python/swe?utm_source=website

https://docs.composio.dev/framework/llamaindex

https://docs.composio.dev/framework/langchain

比langchain底层的工作流agent编排框架 LangGraph

prompt框架

https://docs.langchain4j.dev/

https://github.com/langchain4j/langchain4j

https://docs.spring.io/spring-ai/reference/index.html

https://github.com/spring-projects/spring-ai

xinference

AI上下文协议框架MCP

https://modelcontextprotocol.io/introduction

https://modelcontextprotocol.io/quickstart

https://github.com/modelcontextprotocol

https://github.com/modelcontextprotocol/servers

知识库

上层

https://github.com/getzep/graphiti

向量数据库

https://lancedb.github.io/lancedb/concepts/storage/ embeddedable|localfile|s3

https://www.trychroma.com/ embeddedable|localfile

https://milvus.io/ need etcd、Pulsar embeddedable|s3

es dense_vector

20250131jupyter自动修改IDEA项目SDK、获取GIT信息

背景

20230429 IaC之IDE,也许是下一个ChatIDE?

在2023年4月的时候从phodal的项目中知道了jupyter core是可以embedded之后,我就尝试将它embedd进了IDEA自身以获取全量IDE的自动化能力

源码:https://github.com/dev-assistant/skykoma-plugin-idea

示例:https://github.com/dev-assistant/skykoma-plugin-idea/blob/main/demo/demo.ipynb

因部分java项目的sdk总是没法正确识别,IDEA多年以来的bug都需要手动选下无法完成全量的自动化,所以在官方处理之前想尝试解决下。部分kotlin简写本次一并更新,同时替换掉了基于命令行的git信息获取,改成git4idea接口和官方保持一致

20250201更新:

今天发现官方有了mcp-server的实现,以及已经有了基于MCP的客户端来集成但功能有限,我的插件甚至比MCP的出现(2024年11月25日)和IDEA官方MCP实现(2024年12月9日)要早得多(2023年4月)

自动设置SDK

注意到源码com.intellij.openapi.roots.ui.configuration.ProjectConfigurableUi就是project structure的实现

myProjectJdkConfigurable内容修改时候会触发


而当myLanguageLevelCombo变动时会触发


所以最终实际修改的是LanguageLevelProjectExtensionImpl.getInstanceImpl(myProject).currentLevel

也不难发现是SDK选择后生效的代码

而从ProjectJdkTable.getInstance().findJdk()等一系列方法可以快速获取想要的Sdk对象

官方初始化过程可参考

自动操作GIT

相关操作都在GitRepositoryManager里,UI操作参考GitLogBranchOperationsActionGroup即可

分支UI的操作见plugins/git4idea/resources/META-INF/plugin.xml

可以看到右键菜单是固定的一个分组+两个固定操作,分组操作里会根据选中项是否有分支和tag决定是否显示相关操作

git4idea.ui.branch.GitBranchPopupActions.RemoteBranchActions.CheckoutRemoteBranchAction

TODO

git4idea.ui.branch.GitBranchPopupActions.CheckoutAsNewBranch

TODO

com.intellij.vcs.log.ui.actions.RefreshLogAction

git4idea.actions.GitFetch

com.intellij.openapi.vcs.changes.actions.RefreshAction

 

其他自动化

可以参考官方MCP实现

https://github.com/JetBrains/mcp-server-plugin/tree/master/src/main/kotlin/org/jetbrains/mcpserverplugin

或直接翻官方的IDEA源码https://github.com/JetBrains/intellij-community照抄即可

END