2026年4月

为了把这个去掉甚至充了个 pro,
但是 opus 在写了那个 files.exclude 文件将各种 dot 文件屏蔽掉了
但是始终未能得到解决,这里也是力竭了
(图片好像不太会贴)

我一般都是直接打开项目的但是有时要做一些文件整理看到一堆 dot 文件就是很烦但纯终端笨人又难以适应mental_boom
希望有佬遇到过相同的事

金币仍然给各位拉满了希望不吝指教

机器是 512g 的,nas 划了 1T 做时间机器备份,今天又报空间不足了,但是页面上明明写着老旧备份会在空间不足时删除,这机制看着没用啊

顺便说一下这是第二次了,上一次我是清了整个时间机器盘,重新备份的

看起来大多数现实中家长并不介意孩子把短视频烂梗当成口头禅,什么“包的包的”,“芭比 Q 了”,“六百六十六”之类的。孩子从同龄人圈子中学了好多这些玩意带回家,但全家也就我一个人反感,老人跟老婆都觉得无所谓,最开始我是直接命令禁止的,但是细想大家都这样的,我直接禁止在家说也无异于掩耳盗铃,很苦恼,我想请教一下各位有孩子的 V 友,你们是怎么处理这事的?

https://github.com/ImSingee/git-plus

单一二进制直接运行,或是也打了一个 docker 镜像可用;建议运行在 NAS


从当年 GitHub 封了俄罗斯以后就一直想有这么个备份工具吧,之前靠一堆 bash 脚本完成的,现在算是借 AI 的手用 Go 重写了又做了个 Web 页面

1. 支持备份自己的 Repo 、Star 的 Repo 和 Watch 的 Repo

算是做了两方面的考量,一是自己写的代码存档下(防止被封号),二是自己收藏/关注的存档下(防止删库等)

2. 记录所有的变更历史

可能是自己误操作,也可能是收藏的 repo 出了什么变故;有的时候库可能还在,但 branch 被覆盖了

现有的工具遇到这种情况大都没做特殊处理,需要靠自己跑 reflog 或是按时间去找 commit

我的设计是,完整记录所有分支头的 commit 变化 —— 随意回滚

3. 定时同步

可选的定时同步,可以每天固定跑一次

期货功能

其实还有一些功能在计划中,比如索引所有的仓库来搜索、仓库有更新发通知(参考 ReleaseBot),也包括支持更多源(如 Gitlab )等,感兴趣的话也可以直接回复这个帖子,等发布了我 at 告知

买的京东 Plus 送的 12 积分,5 积分换了京东家政 2 小时

约的时间是近四天内,无论选系统推荐的时间或是其它任何时间均是预约火爆,
我不死心,约 4 月 30 日系统推荐的时间总不火爆吧,很遗憾,依然是销售火爆。
问 Plus 客服说让我换时间约或约系统推荐时间除此无它。

烦请有经验的前辈指点怎么才能约上。

img

img

大模型公司的 AI 社交产品卖的卖死的死,近期的当红炸子鸡体验起来也就那么回事儿,没有真人交流。

试想一下某一天冒出来一个“ai2ex”,帖子都是 AI 生成,回复也是(哦那是 moltbook )。

🇮🇩 陶菲克 (2013/06/12 🔚)

  • 世锦赛: 🥉🥇🥉🥈
  • 奥运会: 🥇
  • 高级别: 🏆 × 16
  • 胜率数: 75%

🇲🇾 李宗伟 (2019/06/13 🔚)

  • 世锦赛: 🥉🥈🥈🥈
  • 奥运会: 🥈🥈🥈
  • 高级别: 🏆 × 50
  • 胜率数: 84%

🇨🇳 林丹 (2020/07/04 🔚)

  • 世锦赛: 🥈🥇🥇🥇🥇🥇🥈
  • 奥运会: 🥇🥇
  • 高级别: 🏆 × 49
  • 胜率数: 84%

🇨🇳 谌龙 (2023/05/19 🔚)

  • 世锦赛: 🥇🥇🥉🥉
  • 奥运会: 🥉🥇🥈
  • 高级别: 🏆 × 26
  • 胜率数: 80%

🇯🇵 桃田贤斗 (2024/05/03 🔚)

  • 世锦赛: 🥉🥇🥇
  • 奥运会: ❌
  • 高级别: 🏆 × 19
  • 胜率数: 78%

🇩🇰 安赛龙 (2026/04/15 🔚)

  • 世锦赛: 🥉🥇🥇
  • 奥运会: 🥉🥇🥇
  • 高级别: 🏆 × 25
  • 胜率数: 78%

📰 今日新闻精选:

  • 2026 软科中国大学排名发布:清华大学、北京大学、浙江大学蝉联综合性大学前三
  • 我国网民平均每人每天刷视频超 200 分钟,其中微短剧人均单日观看时长为 129 分钟,已超长视频
  • 广东将运用无人机、AI 识别等新技术,继续严查摩电违法行为
  • 张雪机车 LOGO 被指抄袭,设计公司声明:系独立创作完成,商标已核准注册
  • U20 女足亚洲杯:中国队 0 比 2 不敌日本,遗憾止步半决赛;此前已锁定 U20 女足世界杯参赛资格
  • 近期多家银行停发部分信用卡,有银行去年发卡量减少 500 万张,超八成银行信用卡透支余额下降
  • 湖南邵阳一工地挖出大量古钱币,预估约 3 吨,初判为钱庄窖藏,涵盖唐宋金时期 40 多个年号
  • 苹果官微发文提醒 iPhone 用户:最近发现一些恶意攻击,请立即更新 iOS
  • 海关总署:5 月 1 日起,擅自引进 21 类外来物种将面临最高 25 万元处罚
  • 日媒:3 月中国内地访日游客人数同比大幅下降 55.9%,连续第四个月同比下降
  • 法媒:法国全票通过文物归还法案,圆明园文物或有望回中国,法议员称雨果希望的一天终于到来
  • 外媒:迪拜帆船酒店宣布将停业 1 年半进行大规模修复工程,此前因美以战事遭袭击着火
  • 美媒:美国加征关税被最高法院裁定为非法,将向进口商退还超 1 万亿美元关税
  • 美媒:黎以美三方会谈结束,同意将正式启动黎以直接谈判;十国呼吁立即停止黎巴嫩境内一切敌对行动
  • 美媒:美伊正逐步接近达成结束战争的框架协议,双方考虑将停火延长两周;美国被曝将向中东增派数千名士兵,施压伊朗达成协议

📅 今日信息:

  • 公历:2026-04-16 星期四 白羊座
  • 农历:二〇二六年二月廿九
  • 下一节气:2026-04-20,谷雨
  • 今年进度:29.04%(已过 106 天,剩余 258 天)

🌟 历史上的今天

  • 1943 年:瑞士化学家阿尔伯特·霍夫曼首次合成并意外体验了 LSD 的致幻效果,这一天后来被称为“自行车日”。
  • 1972 年:阿波罗 16 号发射升空,这是美国阿波罗计划中第五次成功登月的任务。

Hermes 搭建可视化 web-dashboard 界面

官网升级版本配置解决通过 nginx 代理

Hermes 搭建可视化 web-dashboard 界面官网 hermes【https://hermes-agent.nousresearch.com/docs/user-guide/feature...

升级版本

查询当前版本是否和官网一致

hermes version

图片

升级版本

hermes update

配置 hermes dashboard

http://192.168.0.107:9119/

图片

hermes dashboard --host 0.0.0.0

图片

原因是 hermes 安全控制不允许本机之外访问,解决通过 nginx 代理。

安装 nginx

curl -o nginx-1.26.2.tar.gz http://nginx.org/download/nginx-1.26.2.tar.gz
tar -zxvf nginx-1.26.2.tar.gz
cd nginx-1.26.2

编译环境

# 安装开发工具组(包含 gcc、make 等所有编译必需工具)
sudo yum groupinstall "Development Tools" -y

编译

./configure --prefix=/usr/local/nginx --with-http_ssl_module
make
sudo make install

启动

sudo /usr/local/nginx/sbin/nginx

图片

配置代理

cd /usr/local/nginx/conf/
vim nginx.conf
server {
    listen 9118;
    #server_name 你的内网IP;
    server_name 192.168.0.107

    location / {
        proxy_pass http://127.0.0.1:9119;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        # 注意:此处已移除 auth_basic 相关配置
    }
}

重启 nginx 服务

./nginx -s reload

访问如下地址

http://192.168.0.107:9118/

图片

如果不能访问确认端口是否启用

netstat -tlnp | grep 9119

重启 hermes dashboard 后台启动命令

nohup hermes dashboard > /tmp/hermes-dashboard.log 2>&1 &

一、什么是配置中心?

配置中心,是把会变化的配置从程序里搬到程序外,并且能被集中、统一、可控地管理。

二、Go轻量级配置中心Consul的使用

1. 在配置中心配置一个KV “config/golang\_per\_day/50”

图片

2. 编码

package main
import (
    "bytes"
    "fmt"
    "log"
    "os"
    "os/signal"
    "sync"
    "syscall"
    "github.com/gin-gonic/gin"
    "github.com/hashicorp/consul/api"
    "github.com/spf13/viper"
)
const (
    srvName = "golang_per_day_50"
    srvHost = "192.168.1.31" //这里写自己的 IP 地址,否则docker里的Consul无法访问到
    srvPort = 8080
    srvID   = "golang_per_day_50-192.168.1.31:8080"
)
var (
    appConfig *Config
    lock      sync.RWMutex
)
type Config struct {
    Consul ConsulConfig `mapstructure:"consul" json:"consul"`
    Redis  RedisConfig  `mapstructure:"redis" json:"redis"`
}
type RedisConfig struct {
    Host     string `mapstructure:"host" json:"host"`
    Port     int    `mapstructure:"port" json:"port"`
    Db       int    `mapstructure:"db" json:"db"`
    Password string `mapstructure:"password" json:"password"`
}
type ConsulConfig struct {
    Host string `mapstructure:"host" json:"host"`
    Port int    `mapstructure:"port" json:"port"`
}
func main() {
    r := gin.Default()
    // 定义一个 ping 接口
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    // 1. 定义健康检查接口
    r.GET("/health", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "status": "ok",
        })
    })
    // 2. 读取配置中心的配置,这里用Consul
    config := api.DefaultConfig()
    config.Address = "192.168.1.31:8500" // Consul 的地址
    client, _ := api.NewClient(config)
    kvPath := "config/golang_per_day/50"
    loadConfig(client, kvPath)
    go watchConfig(client, kvPath)
    // 3. 注册服务到 Consul
    registerToConsul()
    // 4. 启动 Gin 服务
    go func() {
        if err := r.Run(fmt.Sprintf(":%d", srvPort)); err != nil {
            log.Fatal("服务启动失败: ", err)
        }
    }()
    // 5. 优雅退出:监听信号注销服务
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit
    // 退出前注销服务
    deregisterFromConsul()
    log.Println("服务已退出并从 Consul 注销")
}
// 注册逻辑
func registerToConsul() {
    config := api.DefaultConfig()
    config.Address = fmt.Sprintf("%s:%d", appConfig.Consul.Host, appConfig.Consul.Port) // Consul 的地址
    client, _ := api.NewClient(config)
    registration := &api.AgentServiceRegistration{
        ID:      srvID,
        Name:    srvName,
        Address: srvHost,
        Port:    srvPort,
        Check: &api.AgentServiceCheck{
            HTTP:     fmt.Sprintf("http://%s:%d/health", srvHost, srvPort),
            Interval: "5s", // 每 5 秒检查一次
            Timeout:  "3s", // 超时时间
        },
    }
    err := client.Agent().ServiceRegister(registration)
    if err != nil {
        log.Fatal("注册失败: ", err)
    }
    log.Println("服务注册成功!")
}
// 注销逻辑
func deregisterFromConsul() {
    config := api.DefaultConfig()
    client, _ := api.NewClient(config)
    _ = client.Agent().ServiceDeregister(srvID)
}
// 读取配置中心的 Redis 配置
func loadConfig(client *api.Client, path string) {
    pair, _, err := client.KV().Get(path, nil)
    if err != nil {
        log.Fatal("读取配置失败: ", err)
    }
    v := viper.New()
    v.SetConfigType("yaml")
    err = v.ReadConfig(bytes.NewBuffer(pair.Value))
    if err != nil {
        log.Fatal("读取配置失败: ", err)
    }
    newConfig := Config{}
    err = v.Unmarshal(&newConfig)
    if err != nil {
        log.Fatal("解析配置失败: ", err)
    }
    lock.Lock()
    defer lock.Unlock()
    appConfig = &newConfig
    log.Println("Redis 配置更新: ", appConfig)
}
// 监听 Consul K/V 变化
func watchConfig(client *api.Client, path string) {
    var lastIndex uint64
    for {
        // Consul 的 WaitIndex 机制:如果有变化会立即返回,否则阻塞直到超时
        pair, meta, err := client.KV().Get(path, &api.QueryOptions{
            WaitIndex: lastIndex,
        })
        if err != nil {
            log.Printf("监听出错: %v", err)
            continue
        }
        if pair != nil && meta.LastIndex > lastIndex {
            lastIndex = meta.LastIndex
            loadConfig(client, path)
        }
    }
}

3. 运行程序

$ go run .
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] GET    /health                   --> main.main.func2 (3 handlers)
2025/12/25 00:00:58 Redis 配置更新:  &{{127.0.0.1 8500} { 6379 2 123456}}
2025/12/25 00:00:59 Redis 配置更新:  &{{127.0.0.1 8500} { 6379 2 123456}}
2025/12/25 00:00:59 服务注册成功!
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8080
[GIN] 2025/12/25 - 00:00:59 | 200 |            0s |    192.168.1.31 | GET      "/health"

4. 在Consul中修改“config/golang\_per\_day/50”的值为

consul: 
 host: 127.0.0.1
 port: 8500
redis:
 addr: 192.168.1.31
 port: 6379
 password: "123456"
 db: 22

5. 程序里立马就热更新了配置

图片

三、Consul做配置中心的优缺点

1. 优点:

  • 架构极简:如果你已经用了 Consul 做服务发现,不需要再引入新组件。
  • 强一致性(CP):Consul 基于 Raft 协议,确保所有实例拿到的配置都是一致的。
  • 原子性更新:支持 Check-And-Set (CAS) 操作,防止配置并发冲突。
  • 原生健康检查:配置分发可以与节点的健康状态挂钩。

2. 缺点:

  • 缺少可视化版本管理:Consul 默认的 UI 只能改 K/V,没有 Nacos 那种“发布历史”、“回滚”、“灰度发布”的现成功能(需要自己二开或配合 Git 使用)。
  • 权限细粒度一般:虽然有 ACL,但相比 Apollo 那种精确到字段的权限控制,显得比较粗糙。

四、比喻

人生,本质上是一套 Go 程序 + Consul 配置中心

Go 代码,是你真正掌握的东西。它决定了你能不能跑、会不会 panic、有没有并发安全。

Consul 配置,是你对现实的妥协方案。它不提升你的能力,只决定你在什么条件下不至于崩溃

*源码地址*

1、公众号“Codee君”回复“每日一Go”获取源码

2、https://pan.baidu.com/s/1B6pgLWfSgMngVeFfSTcPdg?pwd=jc1s 


如果您喜欢这篇文章,请您(点赞、分享、亮爱心),万分感谢!

Hermes 搭建可视化 web-dashboard 界面

官网升级版本配置解决通过 nginx 代理

Hermes 搭建可视化 web-dashboard 界面官网 hermes【https://hermes-agent.nousresearch.com/docs/user-guide/feature...

升级版本

查询当前版本是否和官网一致

hermes version

图片

升级版本

hermes update

配置 hermes dashboard

http://192.168.0.107:9119/

图片

hermes dashboard --host 0.0.0.0

图片

原因是 hermes 安全控制不允许本机之外访问,解决通过 nginx 代理。

安装 nginx

curl -o nginx-1.26.2.tar.gz http://nginx.org/download/nginx-1.26.2.tar.gz
tar -zxvf nginx-1.26.2.tar.gz
cd nginx-1.26.2

编译环境

# 安装开发工具组(包含 gcc、make 等所有编译必需工具)
sudo yum groupinstall "Development Tools" -y

编译

./configure --prefix=/usr/local/nginx --with-http_ssl_module
make
sudo make install

启动

sudo /usr/local/nginx/sbin/nginx

图片

配置代理

cd /usr/local/nginx/conf/
vim nginx.conf
server {
    listen 9118;
    #server_name 你的内网IP;
    server_name 192.168.0.107

    location / {
        proxy_pass http://127.0.0.1:9119;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        # 注意:此处已移除 auth_basic 相关配置
    }
}

重启 nginx 服务

./nginx -s reload

访问如下地址

http://192.168.0.107:9118/

图片

如果不能访问确认端口是否启用

netstat -tlnp | grep 9119

重启 hermes dashboard 后台启动命令

nohup hermes dashboard > /tmp/hermes-dashboard.log 2>&1 &

从零跑通这个GitHub 55k星项目,到底能学到什么?

一、为什么我非要试试这个项目

GitHub Trending 上突然冒出一个叫 ai-hedge-fund 的项目。点进去一看:54.9k stars,14 位传奇投资大师 + 5 位专业分析师,全部封装成 AI Agent,还开源。

这让我想起了自己亏掉的那只新能源股票——当时如果能听听巴菲特怎么说、木头姐怎么看,也许结果会不一样。这个项目似乎给了普通人一个「召唤大师」的机会。

于是,我决定花一个周末,把它跑起来,真实地感受一遍。

本文所有操作均在 macOS + Python 3.11 环境下完成,无任何真实资金交易。

二、使用过程:从克隆到第一次决策

2.1 安装与配置(≈15 分钟)

项目安装不算复杂,但有几个关键坑需要留意:

# 1. 克隆项目
git clone https://github.com/virattt/ai-hedge-fund.git
cd ai-hedge-fund

# 2. 后端安装(Python)
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# 3. 前端安装(可选,建议装)
cd ../frontend
npm install

环境变量是第一个坑:项目需要 OpenAI / Anthropic / DeepSeek 等 API Key。我只申请了 DeepSeek(便宜且国内友好),在 backend/.env 中写入:

LLM_PROVIDER=deepseek
DEEPSEEK_API_KEY=sk-xxxxx

如果你完全不想花钱,可以用 --ollama 跑本地模型,但推理速度会慢很多。

2.2 跑通第一个回测(≈3 分钟)

第一次运行,我选了最简单的单股票回测模式,测试标的:NVDA(英伟达),时间跨度 2026-03-01 到 2026-03-31。

backend 目录下执行:

python main.py --ticker NVDA --start-date 2026-03-01 --end-date 2026-03-31

终端开始疯狂输出日志——14 位大师 Agent 逐一被唤醒

[Agent: Warren Buffett] 开始分析 NVDA...
  估值:PE 偏高,但护城河极宽(CUDA生态),建议持有。
[Agent: Cathie Wood] 开始分析 NVDA...
  认为 AI 芯片需求爆发,未来 5 年 CAGR 超 30%,强烈买入。
[Agent: Michael Burry] 开始分析 NVDA...
  发现机构持仓过度集中,存在拥挤交易风险,建议减仓。
[Agent: Nassim Taleb] 开始分析 NVDA...
  警告供应链地缘政治风险,建议买入价外看跌期权对冲。
...
[Portfolio Manager] 汇总所有信号:
  买入: 6 票 | 持有: 8 票 | 卖出: 0 票
  最终决策:HOLD(持有)
  建议仓位:当前持仓的 15%

整个过程大约 2 分半钟,不用写一行代码,就把一整套多 Agent 投资决策流程跑通了。

2.3 可视化界面:拖拽一个投资委员会

如果嫌终端不够直观,可以启动前端:

cd frontend
npm run dev

打开 http://localhost:5173,你会看到一个流程图编辑器(React Flow)。每个 Agent 都是一个可拖拽的节点,你可以:

  • 把「巴菲特」和「芒格」串联起来,让芒格复核巴菲特的结论;
  • 插入「风险经理」节点,强制每个决策必须经过风控;
  • 甚至禁用木头姐(如果你不看好成长股)。

我试着搭建了一个「保守派委员会」:格雷厄姆(估值)+ 巴菲特(护城河)+ 塔勒布(风险),然后回测可口可乐(KO)。结果 Portfolio Manager 给出的「买入」置信度只有 42%——确实很保守。

2.4 跑通多股票 + 实盘模拟(更接近真实)

项目还支持一次性分析多只股票(通过 --tickers 参数),以及接入实时数据(需配置 yfinance 或 Alpha Vantage)。

我试了一个小组合:AAPL, MSFT, TSLA, META,回测过去 6 个月。最终 Portfolio Manager 给出的结论是增持 MSFT、减持 TSLA。虽然这只是一个模拟,但看着 19 个 Agent 一步步推理出这个结论的过程,比直接看 K 线图有意思多了。


三、真实感受:三个惊喜 + 两个遗憾

✅ 惊喜 1:Agent 的「思考过程」比结论更值钱

过去我用过的 AI 投资工具,绝大多数是黑盒——输入股票代码,输出「买入/卖出」。但这个项目会把每一位大师的判断依据全部打印出来。

比如巴菲特 Agent 对 NVDA 的完整推理(简化版):

  1. ROE 连续 5 年 > 20% ✅
  2. 毛利率 > 60%,定价权强 ✅
  3. PE 高于历史 80% 分位 ⚠️
  4. 管理层持股比例充足 ✅
    最终:持有,等待估值回归

你可以像审阅实习生作业一样去检查每个 Agent 的逻辑。这种透明度,让学习投资知识的过程变得异常高效。

✅ 惊喜 2:跑本地模型也能用,成本极低

我试了 --ollama 模式(用的 llama3.2 量化版),单次分析耗时从 2 分钟变成了 8 分钟,但结论基本一致。这意味着完全不花一分钱 API 费用,就能在家里跑一个「虚拟投资委员会」。

对于那些只想学习多 Agent 架构、不想绑定付费 API 的人来说,这是个巨大的加分项。

✅ 惊喜 3:回测模块出乎意料地严谨

项目内置了 backtest.py,不仅记录每次决策的信号,还会计算:

  • 累计收益率(与买入持有对比)
  • 夏普比率、最大回撤
  • 每笔交易的胜率

我回测了巴菲特 Agent 单独决策 vs. 全体 Agent 投票决策。结果显示:全体投票的夏普比率更高,但最大回撤也更大(因为塔勒布 Agent 会引入对冲策略,在下跌市场中反而增加波动)。这种反直觉的结果,只有跑过回测才能发现。

❌ 遗憾 1:无法处理「非财务信息」

所有 Agent 的输入都来自公开财务数据、技术指标和新闻情绪。如果你问它:「某公司 CEO 今天发了一条奇怪的推文,该怎么办?」——它做不到。项目目前没有接入实时社交媒体流或非结构化事件数据。

❌ 遗憾 2:容易让人「过度信任」

这是一个心理层面的遗憾。当 14 位大师同时给出结论时,你很难不产生「这一定是对的」的错觉。项目作者已经在 README 里写了三次「仅供教育研究」,但我还是看到有人问「可以用真钱吗?」——这很危险。


四、一点不成熟的建议

如果你也想玩这个项目,我的建议是:

  1. 先别想赚钱。把它当成一个「投资哲学模拟器」来用,重点看每个 Agent 的推理逻辑。
  2. 从单股票 + 短回测开始。比如 --ticker KO --start-date 2026-03-01 --end-date 2026-03-01,跑通了再玩复杂的。
  3. 一定要打开可视化界面。当你拖拽着把巴菲特和塔勒布连在一起时,那种「设计自己的投资策略」的感觉,是终端无法替代的。
  4. 接受不同 Agent 之间的冲突。巴菲特说买,木头姐说卖,这很正常——真实世界里基金经理们也是吵架的。PM Agent 会帮你做最终裁决。

写在最后

跑完这个项目的那天晚上,我没有去开任何模拟交易。反而花了两个小时,仔细读了格雷厄姆的《聪明的投资者》——因为巴菲特 Agent 在分析时引用了书里的一句话:「市场短期是投票机,长期是称重机。」

也许,这才是 AI Hedge Fund 最大的价值:它不是在帮你赚钱,而是在逼你去理解,那些真正赚到钱的人,到底是怎么想的。


项目地址:https://github.com/virattt/ai-hedge-fund

⚠️ 本文仅为技术体验分享,不构成任何投资建议。实盘交易有风险,请自行承担后果。

前言

上篇文章中提到的OpenWebUI它仅提供网页端使用方式(无独立 APP)。本文将介绍如何通过桌面客户端连接部署在本地的大模型。

关于OpenWebUI的基本使用和开发环境搭建,可参考文章《Ollama+OpenWebUI 最佳组合:本地大模型可视化交互方案》

若需通过OpenWebUI手机网页端连接本地大模型,可参考文章《不花一分钱!把本地大模型装进手机,全家共享+权限管控全攻略》

若需通过手机APP连接本地大模型,可参考文章《手机直连本地大模型!不用云服务、不花一分钱,全家都能用》

ChatWise

ChatWiseOpenWebUI类似,均为AI聊天交互工具,不同的是ChatWise是一款桌面客户端,提供图形化操作界面。ChatWise基于Tauri框架开发,属于桌面图形化应用,无法在无图形化界面的系统中运行。

ChatWise的高级功能需付费使用,基础功能则完全免费,满足日常连接本地大模型的需求已足够。

ChatWise官网

安装ChatWise

下载Windows版本的安装包

访问ChatWise官网,点击“Download 26.4.3”按钮下载安装包(注:ChatWise为桌面图形化应用,无图形化界面的系统无法运行)。本文以Windows系统为例,下载对应版本的安装包并完成安装。

下载Windows版本的安装包

安装ChatWise

安装包下载完成后,右键点击安装包文件,选择“以管理员身份运行”。

右键以管理员身份运行

点击更多信息进行安装

点击仍要运行

点击下一步进行安装

点击安装

完成安装

使用ChatWise

选择本地大模型

使用ChatWise跟本地大模型聊天

设置大模型的参数

设置大模型的参数

常用功能

常用功能

配置MCP

点击界面右下角的设置按钮,还可配置MCP功能。

配置MCP

配置常用提示词

配置常用的提示词

点击命令中心

选择常用提示词

输入特殊要求

输入特殊要求发送问题

特殊要求示例

其他类似ChatWise的软件

ChatWise外,同类工具还有Cherry StudioAnythingLLM

浏览器插件类可选择Page Assistollama-client

若以上工具均无法满足需求,也可借助gradio自行开发专属的WebUI界面。

gradio工具

面向对象包括封装、继承、组合、多态,其中最不好理解,也最强悍的就是多态。可以说掌握了多态就掌握了面向对象以及设计模式的精髓。

但是 java 里面的多态实现太过于严苛,以致于其他语言都无法完全模拟。请看下面的代码,用其他语言实现的时候总难以达到类似效果。

/*
多态:即同一个行为具有多个不同表现形式或形态的能力。
表现形式为,子类重写父类方法,实现类实现接口方法,子类重写抽象类方法等。
多态三个必要条件:继承、重写、父类引用指向子类对象。多态有效消除类型之间的耦合,并提供灵活的可扩展方案。
本例子简单清晰明了的 Java 多态,能看懂这个例子就懂了什么是多态。
*/

// 父类 A
class A {
    public String show(D object) {
        return ("A and D");
    }

    public String show(A object) {
        return ("A and A");
    }

    // 默认注释掉。可开关注释测试下
    // public String show(B object) {
    // return ("A and B");
    // }
}

// 子类 B
class B extends A {
    public String show(B object) {
        return ("B and B");
    }

    public String show(A object) {
        return ("B and A");
    }
}

// 孙子类 C
class C extends B {
}

// 孙子类 D
class D extends B {
}

// 测试验证
public class PolymorphismSimple {
    public static void main(String[] args) {
        // 父类声明自己
        A a = new A();
        // 父类声明子类
        A ab = new B();
        // 子类声明自己
        B b = new B();
        C c = new C();
        D d = new D();

        // 1) A and A 。b 的类型是 B ,也是 B 的实例,A 里没有 show(B)方法,但有 show(A)方法。B 的父类是 A ,因此定位到 A.show(A)。
        System.out.println("1) " + a.show(b));

        // 2) A and A 。c 的类型是 C ,也是 C 的实例,C 继承 B ,B 继承 A 。A 里没有 show(C)方法,也没有 show(B)方法,最后指向 A.show(A)。
        System.out.println("2) " + a.show(c));

        // 3) A and D, d 的类型是 D ,也是 D 的实例,D 继承 B ,B 继承 A 。A 里有 show(D)方法,直接定位到 A.show(D)。
        System.out.println("3) " + a.show(d));

        // 4) B and A, ab 是 B 的实例,但用 A 声明,即向上转型得到的类型是 A ,运行时才能确定具体该调用哪个方法。
        // ab 是 B 的实例对象,但引用类型是 A 。类型是在编译时确定,因此从类型开始定位方法。
        // A 类中没有 show(B)方法,但有 show(A)方法,因为 A 是 B 的父类,ab 也是 A 的实例,于是定位到 A.show(A)方法。
        // 由于 B 是 A 的子类,且 B 重写了 A 的 show(A),A 的方法被覆盖了,于是定位到 B.show(A),这就是动态绑定。
        // 虽然 B 中有 show(B)方法,但是因为 ab 的类型是 A ,编译时根据类型定位到 A 的方法,而不是 B 。

        // 以下几种可开关打开/注释代码测试下。
        // -
        // 若 A 里有 show(A)和 show(B),B 里有 show(B)有 show(A),则编译时关联到 A.show(B),因 B 覆盖了 A.show(B),动态绑定到 B.show(B)。
        // -
        // 若 A 里有 show(A)和 show(B),B 里无 show(B)有 show(A),则编译时关联到 A.show(B),因 B 无覆盖,则直接调用 A.show(B)。
        // -
        // 若 A 里有 show(A)无 show(B),B 里无 show(B)有 show(A),则编译时关联到 A.show(A),因 B 覆盖了 A.show(A),动态绑定到 B.show(A)。
        // -
        // 若 A 里有 show(A)无 show(B),B 里无 show(A)有 show(B),则编译时关联到 A.show(A),因 B 无覆盖,则直接调用 A.show(A)。
        // 查找顺序为:编译时根据引用类型确定所属类 -> 根据重载参数类型定位(类型按子->父->祖逐级往上查找)到类的具体方法(包括继承的方法) ->
        // 运行时实例对象覆盖(覆盖只有子->父一层)了引用类型的同名方法 -> 定位到实例对象的方法。
        System.out.println("4) " + ab.show(b));

        // 5) B and A 。ab 是 B 的实例,类型是 A 。从 A 类没找到 show(C)方法,也没找到 A.show(B)方法,找到 A.show(A)方法。A.show(A)被 B.show(A)覆盖,因此调用 B.show(A)。
        System.out.println("5) " + ab.show(c));

        // 6) A and D 。A 里面有 show(D)的方法,直接定位到。
        System.out.println("6) " + ab.show(d));

        // 7) B and B 。B 里面有 show(B)的方法,直接定位到。
        System.out.println("7) " + b.show(b));

        // 8) B and B 。B 没有 show(c)方法,但有 show(B)方法。C 继承自 B ,父类型是 B ,因此调用 B.show(B)。
        System.out.println("8) " + b.show(c));

        // 9) A and D 。B 中没有 show(D)方法,B 继承 A ,A 里有 show(D), 故调用 A.show(D)方法。
        System.out.println("9) " + b.show(d));

        // 10) B and A 。父类声明子类,存在向上转型。A 里有 show(A),被 B.show(A)覆盖了,因此定位到 B.show(A)。
        System.out.println("10) " + ab.show(a));

    }
}

/**
 * 测试结果
 * 1) A and A
 * 2) A and A
 * 3) A and D
 * 4) B and A
 * 5) B and A
 * 6) A and D
 * 7) B and B
 * 8) B and B
 * 9) A and D
 * 10) B and A
 */

其他语言模拟实现: https://github.com/microwind/design-patterns/tree/main/programming-paradigm/object-oriented-programming/polymorphism

.net >> java/ webpack >> vite(顺带着)

大方向是 springboot/人大金仓(postgresql)

主要是业务层面:

ORM/权限控制/轻量 OA/多租户(可能还涉及业务定制) 都有什么选项?

之前了解过 renren ,看过代码感觉质量一般,而且是 MySQL native 的,有点负担

2026 年当下,还需不需要找此类框架,还是直接 Vibe coding ?

如果是 vibe coding ,也要有个参考的架构,我水平有限问问大家

————————————————————————

关于前端,目前心仪 TDesign ,有没有生产深度用过的 V 友,有没有坑?