<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0"><channel><title>乱谈府</title><link>https://laffitto.xyz</link><atom:link href="https://laffitto.xyz/feed.xml" rel="self" type="application/rss+xml"/><description>也扯淡，也思考，也学习，也生活</description><generator>Halo v2.22.14</generator><language>zh-cn</language><image><url>https://laffitto.xyz/upload/round_head_compress.png</url><title>乱谈府</title><link>https://laffitto.xyz</link></image><lastBuildDate>Sun, 8 Mar 2026 23:17:00 GMT</lastBuildDate><follow_challenge><feedId>67377598479158275</feedId><userId>44561358151908352</userId></follow_challenge><item><title><![CDATA[2025年终总结]]></title><link>https://laffitto.xyz/archives/2025review</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=2025%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93&amp;url=/archives/2025review" width="1" height="1" alt="" style="opacity:0;">
<p>2025 年用关键词去形容，就是死线逼近前的一搏。死线这个概念通常是在工作中，那是让你在临近期限爆发的动力。今年目标中虽然没有直接去设立这个期限，但是回首在潜移默化中，自己用这个理念去推进达成了一些事情，顺其自然也要适可而止，确实是需要切实的目标去激励自己。</p>
<h2 id="%E5%A4%A7%E4%BA%8B%E8%AE%B0" tabindex="-1">大事记</h2>
<h3 id="%E5%B7%A5%E4%BD%9C%E7%9A%84%E5%8F%98%E6%9B%B4" tabindex="-1">工作的变更</h3>
<p>今年生活中的最大一个变化就是开始极强规律性的工作。在经过漫长的寻找学习和死线逼近之后，终于在五月初找到了一个算法工程师的职位，并且实现了原先从偏向科研方面的工作转向偏向工程方面的工作。前者虽然能带来写名面上的荣耀，但纸上谈兵落于实践还是有所差距。后者工程上的研究虽然少了点想法，但日常中能积累更多实战的经验。从科研算法专家到算法工程师过程，联合两者的特点，在不断吸收思考新的论文/知识的基础上，再深耕于实践应用并落地，于我而言更具挑战性与成就感。
 <br>
 当前这个转型过程中也收益于 AI 的飞速发展。在日新月异的大模型加持下，想法的调研并验证效率得到了至少 5 倍的提高。之前自己从来没有用 python 独立编写过后端，但在 AI 的协助下，已经独立开发出联合深度学习算法推断的完整的后端项目，并且学会了很多生产部署的工作流。然而，并不满足。</p>
<h3 id="%E6%88%90%E4%B8%BA%E6%88%BF%E5%A5%B4" tabindex="-1">成为房奴</h3>
<p>为了结婚的目标，还是需要买个房子的。尽管房价在下跌，入手便是亏，但实际由于是自己住本身就还是刚需。看了将近半年的二手房，期间和中介沟通，和家人沟通。一次次失望，一次次等待。感觉事情不能再拖，心理的死线划定下，终于在 12 月份偶然机缘拿下了合肥瑶海老城区的一处新房，精装修，主要也省下了一部分中介与装修需要耗费的金钱和精力。家人给付了一部分的首付，自己和女友再去背一部分还债。不知不觉已然成为了房奴，明年开始就是负债之路了。有期待，也有压力，一切才是开始。</p>
<h2 id="%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0%E4%B8%8E%E9%81%97%E6%86%BE" tabindex="-1">具体实现与遗憾</h2>
<h3 id="%E8%AF%BB%E4%B9%A6%E4%B8%8E%E8%BE%93%E5%87%BA" tabindex="-1">读书与输出</h3>
<p>今年只系统性的看了 4 本书，发表博客文章 8 篇，memos 26 条。不能把原因归咎为太忙，纯粹是因为懒惰和没有养成习惯。感悟是经常有，写起来也很方便，之后要多多分享轻量化的体验。下班回家只想沉迷于奶头乐的内容，实际还是要控制度。娱乐至死的内容太多了，虽然早就知道危害与应对方法，但之后还是要应用起来。</p>
<h3 id="%E5%81%A5%E8%BA%AB" tabindex="-1">健身</h3>
<p>头 4 个月还经常跑步锻炼身体，体重最低降至 68 kg。入职新工作后由于通勤时间，只是偶尔进行身体锻炼，而且不知为何经常感冒嗓子痛，就这 8 个月嗓子痛了 4 次，一折腾就是 2 周，明显感觉体质大不如以前。久坐也导致体重当前变化为 74 kg，惰性增加。需要重新将健身列入计划内，保持充足的体力与精力应对不同的生活。</p>
<h3 id="%E4%BA%A4%E9%99%85" tabindex="-1">交际</h3>
<p>交际方面没有什么大的突破，还是周围较为熟悉的那些人和事。陪家人聚餐 9 次，和朋友聚会 6 次，和女友约会 39 次。外出旅行 2 次，简单去转了转常州和河南周边。</p>
<h3 id="%E7%8E%B0%E9%87%91%E6%B5%81" tabindex="-1">现金流</h3>
<p>今年赚的钱一般般，坚持了几年的记账也已经成为了习惯，能够合理控制自己的开支与预算。投资系统由于太忙还是没有建立起来，当前的自己还是相信时间的沉淀，明年希望被动投资为主，主动投资体系不断摸索为辅。况且现在加上了房产的负债，核心精力还是应该在提高自己的竞争力上，并且更加深入并利用 AI 去构建自己的产品。</p>
<h3 id="%E7%89%A9%E8%B4%A8%E6%9B%B4%E6%96%B0" tabindex="-1">物质更新</h3>
<p>国补入手了 macbook air M4， 16+512 版本，并将之前的 windows 本子闲鱼处理掉了。体验极好相见恨晚，macos系统的应用确实有一种统一的美感。目前带到公司作为私人查阅资料电脑。</p>
<p>入手了二手文石 leaf 3，安卓系统的墨水瓶阅读器，且可以使用 google play，主要使用 Reader 和微信读书。虽然暂时用的不多，但相较于 kindle 系统开放太多，挺跟手的。</p>
<p>入手了一只金太阳鹦鹉，不出意外可以陪伴 20 多年。目前很亲人，每天回家都会扑着飞你身上，情绪价值提供很足，以后再做文章介绍。</p>
<p>整体的 2025 推进了很多，但是仍然并不满足，最后几天默默制定了 2026 的 OKR，希望明年的年终复盘时能看到满意的自己。</p>]]></description><guid isPermaLink="false">/archives/2025review</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20251227225122521.png%3FimageSlim&amp;size=m" type="image/jpeg" length="2607978"/><pubDate>Tue, 30 Dec 2025 15:03:00 GMT</pubDate></item><item><title><![CDATA[河南短旅]]></title><link>https://laffitto.xyz/archives/henan-journey</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E6%B2%B3%E5%8D%97%E7%9F%AD%E6%97%85&amp;url=/archives/henan-journey" width="1" height="1" alt="" style="opacity:0;">
<p>国庆期间没在家闲着，去河南那边转了一圈。实际主要是女朋友为了参加好朋友位于河南焦作的婚礼，顺便去了云台山和郑州逛了逛。整体下来就是吃吃喝喝外加景区的人挤人。至于为什么现在才发，就是拖延症一直拖延，再不写再不发，记忆就模糊了，回忆就淡忘了。</p>
<h2 id="总体行程梳理">总体行程梳理</h2>
<p>由于没抢到直达焦作的票，只能先去郑州再中转。</p>
<p>9 月 31 日晚上，高铁抵达郑州。
 <br>
 10 月 1 日，上午郑州蜜雪冰城总部扫荡，中午抵达焦作，受到朋友招待，吃了羊肉烩面，武陟砂锅等等。
 <br>
 10 月 2 日，上午陪新娘整理东西，参加婚礼，晚上新郎新娘单独请了远道而来朋友吃饭，多是河南特色。
 <br>
 10 月 3 日，清晨约车出发去往云台山景区，游览了众多景点，下午排队太久实在太累，晚上在云台山居住一晚。
 <br>
 10 月 4 日，上午从景区前往修武西，做高铁返回郑州，下午逛了郑州的如意湖，打卡五月天的 q 版人偶。晚上打卡金融岛的五月天五球，品尝了葛记焖饼。
 <br>
 10 月 5 日，早上品尝方中山胡辣汤最老店，参观了河南博物院，品尝了惠丰源烩面馆，下午随便逛逛高铁返程。</p>
<h2 id="吃吃喝喝">吃吃喝喝</h2>
<p>去一个地方，品尝当地的美食总是必不可少。河南主要是面食大省，从焦作到郑州，从朋友宴请到自己探店，这一路上我们吃到了很多当地特色菜，武陟砂锅，羊肉烩面，道口烧鸡，汴京烤鸭，蒸菜，焖饼，胡辣汤，山药炖鸡，荆芥菜品饮品，很多东西确实第一次吃，惊喜连连。
 <br>
 羊肉烩面每一家味道都不太一样，口味受众也不同，一般都是烩面配上一些凉菜，不过感觉在郑州吃的惠丰源烩面馆甚至没有在焦作吃的朋友推荐的小馆香。
 <br>
 方中山胡辣汤让人印象难忘，极其重口的胡椒甚至连本地人也不是都能完全接受，喝多了嗓子眼都感觉在冒烟，两个人配合其他早点吃着喝一碗倒是不成问题。
 <br>
 武陟砂锅带给我最大的惊喜，一碗小小的砂锅，可以选择羊肉，牛肉，三鲜，小酥肉等等食材，旁边配着青菜。砂锅上来，青菜手动下锅烫熟，再浇上现炸的香辣椒，味道简直美美桑内😋。
 <br>
 在我们乘车去往各个馆子的过程中，刚好遇到一个吃货司机，热情的向我们介绍了他心目中郑州当地的特色美食，很多都是有十几甚至二十年的老店，可惜我们没有充足时间都去品尝一遍。对话过程中也是体会到他作为一个土生土长的郑州人对当地的热爱。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20251108180319995.jpg%3FimageSlim&amp;size=m" alt=""></p>
<h2 id="特色景点">特色景点</h2>
<p>景点的好不好玩，在景点自身的素质之上，还叠加了参观人群质量这个重大影响因素。</p>
<h3 id="云台山景区">云台山景区</h3>
<p>云台山作为国家级 AAAAA 级风景区还是值得一看的。园区很大分为几大块，区间内有大巴车接送。我们作为特种兵早上 7 点半就进入景区，那时候还没什么人。第一站先前往红石峡景区，那边是由红岩绝壁构成的峡谷，一条小路在岩壁内测打通一路往上，期间你可以看到水流的落差和狭窄的岩壁，每每走过先是闻水声，然后一片豁然开朗。我在这里大受震撼，因为就仿佛我小时候看的鬼吹灯巫峡棺山那种场景身临其境一般。上到顶是一片湖水，微波荡漾下感觉到自己的渺小。
 <br>
 之后乘坐大巴车前往茱萸峰缆车的地方，乘坐大巴车这段路途也是蜿蜒曲折，中途会进单行隧道，各个大巴车会在隧道口鸣笛提醒，光在车上都行驶了有 20 min，我感觉也能当做一个独特的风景线。乘坐缆车上山可以看到整个景区的一个大致全貌，直达峰顶。茱萸峰峰顶有着王维大名鼎鼎的"遥知兄弟登高处，遍插茱萸少一人"的题词。山上有道观和道士，加上早上的一些云雾，颇有一种飘飘欲仙的感觉。下山途中看到爬上山的人气喘吁吁而且队伍浩浩荡荡，而下山的人零零星星，不由得感叹缆车上山然后步行下山真的是明智之举。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20251108180352422.jpg%3FimageSlim&amp;size=m" alt=""></p>
<p>以上两块游览体验都是比较好的，接下来我们又去往了小寨沟景区，那时大概 12 点多，人员已经很多了，接下来才是真正体会到十一出行人群的威力。
 <br>
 小寨沟里十几有三个独立的景点：泉瀑峡，潭瀑峡和猕猴谷。当时恰逢潭瀑峡限流刚开放一波进入，我们也就先跟着进去了，其核心看点是一个巨大的瀑布。进去后先看到一个牌子显示终点位于前方 3 公里处，当时就心里一惊，不过这时候路还比较宽敞也只是觉得会有点累没啥。但通过在山间小路穿梭后，我们发现路开始堵住了。原来由于前面的下雨和道路本身设计，很长一段路都只能并行一个人单独通过。其中有一段水路，必须踩在摆放的沙袋上通过，导致大量人群的挤压。本来都是三四个人并行的路，突然就变成了单行通路，而且因为旁边有非水泥的小路，还有大量人群插队，引发大量人员不满，还好景区工作人员及时来拉起界限，引导大家排队。走走停停等等，当我们到达最深处的云台天瀑时已经差不多过去了两个多小时。但是瀑布那种飞流直下三千尺的震撼，还是让人感觉前面的辛苦还是值得的。返程我们途中我们发现，景区工作人员及时分流规划路线，回去并不用走之前的路，导致路线顺畅许多。回到小寨沟下面已经 4 点多了，而我们实在太累，也没有再逛剩下的景点，直接回去民宿休息了。
 <br>
 因为云台山景区的票可以进来三天，本来计划第二天大清早再进来一次，但奈何实在太累，起床后浑身酸痛，外加有点感冒，也就上午直接离开返回郑州了。
 <br>
 总体来说在人少的时候，这个景区是非常有看头的，路线规划好，体验感极佳。景区的保护和工作人员都很尽责，景区收拾的干干净净，垃圾也专人在分类捡取。而且在遇到人流问题时园区反映及时，重新规划路线给游客很好的疏导，给他们点个大大的赞👍。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20251108180410160.jpg%3FimageSlim&amp;size=m" alt=""></p>
<h3 id="河南博物院">河南博物院</h3>
<p>每个地方的博物院还是非常值得看看的，但是国庆最大的问题在于人太多了，而且没做好功课。这种最好的就是提前预约个讲解，不然就像我们进去之后人挤人，像个无头苍蝇一样，最终连九大镇馆之宝都没看全😭。</p>
<h3 id="五月天打卡">五月天打卡</h3>
<p>小徐作为一名合格的 WMLS（五迷老师），在得知郑州有五月天的应援场景后那就不可能不打卡。在郑州如意湖附近有五月天的 q 版人偶，而在金融岛旁边有巨大的五球，在晚上还会放出灯光，甚至在特定机位还可以看到与雪王的联动。10 月 4 日晚上，甚至在五球前方有歌迷自发组织的张韶涵粉丝应援会，大家打伞在雨中唱歌，氛围拉满了🌹。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20251108180422991.jpg%3FimageSlim&amp;size=m" alt=""></p>
<h3 id="雪王降临">雪王降临</h3>
<p>郑州有着冰雪冰城最大的总部，其坐落于郑州东站附近，里面有很多限定款的玩具零食冰淇淋等等。一个冰淇淋才 2 块，入口即化，甜味十足。蜜雪带给人的情绪价值很高，在里面兜兜转转买了半天各种小零食小玩具，满满一大堆，最终一结账才不到 100 块，有种回到小时候的钱根本花不完的感觉💰。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20251108180856804.jpg%3FimageSlim&amp;size=m" alt=""></p>
<h2 id="难忘的旅程">难忘的旅程</h2>
<p>整体来说，国庆出游主要就是人多，即便是河南郑州这种非旅游城市，是个景点人就不少。虽说我们累的够呛，回来后因为又冷又热感冒了，但其实做足攻略，还是能够得到一个相对较好的体验。河南的饮食和安徽这边差距还是大，我感觉不喜欢面食的人待不下去，但他是一个好城市。小徐千里迢迢去参加朋友的婚礼，而她的朋友也给我们安排的井井有条，大家都是很好的人，大学时代的朋友相隔异地还能齐聚，属实是弥足珍贵。</p>]]></description><guid isPermaLink="false">/archives/henan-journey</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20251108181605094.jpg%3FimageSlim&amp;size=m" type="image/jpeg" length="1242662"/><pubDate>Sun, 12 Oct 2025 15:02:00 GMT</pubDate></item><item><title><![CDATA[Docker环境开发部署流程]]></title><link>https://laffitto.xyz/archives/docker-environment-development</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=Docker%E7%8E%AF%E5%A2%83%E5%BC%80%E5%8F%91%E9%83%A8%E7%BD%B2%E6%B5%81%E7%A8%8B&amp;url=/archives/docker-environment-development" width="1" height="1" alt="" style="opacity:0;">
<p>之前一直在 windows 环境中编写基于 python 算法和后端，初期开发的时候没遇到啥问题。但随着后面部署和环境兼容性的需求的出现，windows 环境中各种依赖的复杂项和一些本身系统的缺陷让我产生了迁移开发环境的想法。虽然 windows 上面的 wsl 用起来也不赖，不过考虑到终究是要使用 docker 部署的，为何不直接在 docker 环境中开发，还可以测试环境的独立性。
 <br>
 本文是自己在使用 docker 进行开发环境和部署环境构建的一些经验总结，可能有不对的地方，仅作记录和抛砖引玉。</p>
<h2 id="环境需求">环境需求</h2>
<p>虽然我最开始是做算法相关的，但是手头的项目慢慢变成了一个基于 python 做后端的复杂项目。其中包含数据库的构建，各种方法 API 的调用，异步任务，在线读图功能，深度学习模型推断功能等等。前三点都可以找到比较合适的 python 库中的框架，例如我选择的是 Flask + Flask-SQLAlchemy + Celery 组合，本质上只要安装对应的包即可。但后面两点对环境的要求极高，首先是在线读图功能，它需要兼容多种不同的切片格式的读取分析，而这其中不同的格式会依赖于不同底层的 C++封装的库，进而导致 windows 和 linux 环境依赖不同。深度学习模型推断更不用说，pytorch 对不同架构不同 cuda 版本都有严格的限制。结合平台间路径读取的不一致，选用 docker 将环境统一再开发是一件省时省力的事。</p>
<p>Windows 安装 docker 这件事就不赘述了，主要是安装 docker-desktop，wsl 2 和 wsl 环境（如 Ubuntu 22.04 LTS）。并在 docker-desktop 设置中 Resources-WSL integration 中打开对应的环境。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F1755853005510.png&amp;size=m" alt=""></p>
<h2 id="开发环境">开发环境</h2>
<p>整体分为构建镜像和开发环境启动两部分。</p>
<h3 id="构建镜像">构建镜像</h3>
<p>由于需要适配 gpu，所以开发环境选择有 cudnn 环境的镜像，这里基础镜像选择 <a href="https://hub.docker.com/layers/nvidia/cuda/12.6.3-cudnn-runtime-ubuntu22.04/images/sha256-46cb48a4abfbc40c836fe57bc05a07101b6458fffc63bbdfd6a50db98c9358bd">12.6.3-cudnn-runtime-ubuntu22.04</a>，开发阶段构建的镜像仅包含基础的软件环境，用于开发调试。这里我将 torch 相关的依赖都下载到了本地 dependence/torch 文件夹下，采取分阶段构建的方式，不然会在镜像中留存复制操作的所有文件，导致镜像增大。示例代码 Dockerfile-dev 如下</p>
<pre><code class="language-shell"># 阶段1：构建和安装依赖 无copy层 减少镜像大小
FROM nvidia/cuda:12.6.3-cudnn-runtime-ubuntu22.04 AS builder

ENV DEBIAN_FRONTEND=noninteractive

# 安装构建所需的依赖（与最终镜像保持一致很重要）
RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends \
    build-essential \
    libopenslide-dev \
    libgl1-mesa-glx \
    libglib2.0-0 \
    python3.10 \
    python3.10-dev \
    python3-pip \
    git \
    libnuma1 \
    tzdata \
    &amp;&amp; rm -rf /var/lib/apt/lists/*

# 设置 Python 别名
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 &amp;&amp; \
    update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1

# 升级 pip
RUN python -m pip install --upgrade pip

# 安装所有 torch 相关的包
COPY dependence/torch/*.whl /tmp/wheels/
RUN pip install --no-cache-dir /tmp/wheels/*.whl &amp;&amp; \
    pip cache purge

# 验证安装
RUN pip list | grep torch

# 阶段2：最终镜像
FROM nvidia/cuda:12.6.3-cudnn-runtime-ubuntu22.04

ENV TZ=Asia/Shanghai
ENV DEBIAN_FRONTEND=noninteractive

# 安装运行时依赖（必须与 builder 保持一致）
RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends \
    build-essential \
    libopenslide-dev \
    libgl1-mesa-glx \
    libglib2.0-0 \
    python3.10 \
    python3.10-dev \
    python3-pip \
    git \
    libnuma1 \
    tzdata \
    &amp;&amp; rm -rf /var/lib/apt/lists/*

# 配置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &amp;&amp; echo $TZ &gt; /etc/timezone

# 设置 Python 别名
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 &amp;&amp; \
    update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1

# 升级 pip 到相同版本
RUN python -m pip install --upgrade pip

# 完整复制 Python 环境
COPY --from=builder /usr/local/lib/python3.10 /usr/local/lib/python3.10
COPY --from=builder /usr/local/bin /usr/local/bin

# 验证 torch 是否正确复制
#RUN pip list | grep torch &amp;&amp; \
#    python -c "import torch; print('PyTorch version:', torch.__version__); print('CUDA available:', torch.cuda.is_available())"

WORKDIR /app

# 安装其他依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple &amp;&amp; \
    pip cache purge
</code></pre>
<p>使用命令进行构建</p>
<pre><code class="language-shell">docker build -f Dockerfile-dev -t docker-dev:1.0 .
</code></pre>
<p>之后可以在 docker desktop 中看到构建的镜像文件。</p>
<h3 id="环境启动">环境启动</h3>
<p>启动开发时，直接使用 docker compose 配置文件启动，示例代码 docker-compose-dev.yml 如下</p>
<pre><code>version: '3.8'

services:
  # 服务名可以任意，比如 app, dev, my_env...
  app:
    image: docker-dev:1.0
    container_name: docker-dev

    ports:
      - "8098:8098"

    # 启用GPU！这套新的标准语法可以确保容器能访问到GPU资源
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ['0'] # 明确指定ID为0的GPU
              capabilities: [gpu]

    # 共享内存,用于控制pytorch推断过程中workers的内存大小,仅workers&gt;0需调整
    shm_size: '4gb'

    # 环境变量配置
    environment:
      # --- 数据库配置 ---
      - DATABASE_URL=xxxx
  
  

      # C依赖库
      - LD_LIBRARY_PATH=/app/dependence/xx

      # huggingface配置
      - HF_HOME=/app/dependence/hf_cache


    # 项目文件夹映射
    volumes:
      - .:/app

    # 启动主应用
    command: python app.py
</code></pre>
<p>使用命令启动：</p>
<pre><code class="language-shell">## 启动特定的docker-compose文件
docker compose -f docker-compose-dev.yml up -d

## 停止服务
docker compose -f docker-compose-dev.yml stop

## 删除服务
docker compose -f docker-compose-dev.yml down
</code></pre>
<p>如果你使用 pycharm 作为 ide，可以在 Services 选项栏中看到对应 docker 的镜像和正在运行容器，查看对应 log 并对程序进行运行调试等操作。开发流程基本和 windows 原生开发差不多，就是每次程序启动可能稍慢，体验还是不错的。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F1755851695245.png&amp;size=m" alt=""></p>
<h2 id="部署环境">部署环境</h2>
<p>部署环境基本就是开发环境的延续，本质上就是将项目文件夹中必要的东西也打包进去。不过因为有了开发环境，可以在这个基础上直接进行打包。打包示例代码 Dockerfile-prob 如下：</p>
<pre><code># 使用开发环境构建的 torch 基础镜像
FROM wsi-docker-dev:1.0 AS base

WORKDIR /app

# 复制应用代码（这里会用到 .dockerignore排除特定文件）
COPY . .

# 声明应用将要监听的端口
EXPOSE 8098
</code></pre>
<p>构建后进行启动，对应的 docker-compose-prob.yml 和开发环境基本一致，注意修改挂载的数据即可。</p>
<p>当然，部署环境应该还要做更多的改动，例如加密和一些部署的专业性调整，后续变化了继续补充。</p>]]></description><guid isPermaLink="false">/archives/docker-environment-development</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250822232346347.png&amp;size=m" type="image/jpeg" length="1324827"/><pubDate>Mon, 8 Sep 2025 15:03:00 GMT</pubDate></item><item><title><![CDATA[让写博客成为一种自然的习惯]]></title><link>https://laffitto.xyz/archives/easy-blog</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E8%AE%A9%E5%86%99%E5%8D%9A%E5%AE%A2%E6%88%90%E4%B8%BA%E4%B8%80%E7%A7%8D%E8%87%AA%E7%84%B6%E7%9A%84%E4%B9%A0%E6%83%AF&amp;url=/archives/easy-blog" width="1" height="1" alt="" style="opacity:0;">
<p>不知不觉，这个博客已经维护有五六年了，期间也断断续续写了不少文章。起初写作主要是为了对抗枯燥的生活，也督促自己两周更新一篇。但那时难免有时候没什么灵感，一些文章都是在第二周的周末灵机一动，天马行空完成。后来毕业后时间变少，博客更新变得不再规律，更多是经历了值得记录的事情才会记录发表，所以近期的内容偏向生活记录。</p>
<h3 id="旧流程与困扰">旧流程与困扰</h3>
<p>我之前的写作流程大致如下：
 <br>
 有了大致想法，很多时候是一种灵感迸发，先在待办软件里简单记录。然后在特定时间，进入博客文件夹新建一个 Markdown 文件，完成写作后同步发表。</p>
<p>但这些流程存在多处痛点：</p>
<ol>
 <li><strong>灵感记录难以扩展</strong>​灵感记录本质上是选题的收集，难点在于后续的扩充。一个点的灵感往往需经过网状思考，再用线性语言组织并不容易。即使有卡片笔记法等方法，但实际操作起来仍有难度。</li>
 <li><strong>新建文章流程生硬</strong>​在一个特定的时间段，新建一个 markdown 文件，依据之前的记录从 0 开始完成写作，这是一套流程特别生硬的行为。从我以往的经验看，这套流程特别不顺手，稍有一些外事干扰就会被打断。</li>
 <li><strong>附件整理与发表繁琐</strong>
  <br>
  我markdown 中的图像链接都是借助图床而非存在本地，这就涉及一个上传动作。文章完成后最开始甚至要把本地内容复制，粘贴到博客系统中，再在博客中补充特有的元信息再发表。外部系统迁移这个动作重复多了同样会造成负担。</li>
</ol>
<p>长此以往，写博客逐渐变成了一件有压力的事情。前置条件太多、准备流程太长、操作太繁琐。几年前因同步问题还切换到动态博客系统，但静态博客依然保留了备份，所以每次写完还要再复制一份到静态博客，流程繁杂导致更新也越来越少。</p>
<p>过程中虽然附件整理发表流程有所优化，但其他问题几乎没有改善。直到最近一次经历，带来了新的启发。</p>
<h3 id="新契机与流程优化">新契机与流程优化</h3>
<p>起因是前不久找新工作面试时，面试官问我简历中的博客都写些什么，我回答主要是生活，思考，分享之类的。但是他问有没有技术方面分享，我说也有一些，他说是你自己的技术吗，我说是我学习的技术记录，他说哦那比较少不是你自己的。当时想反驳，但出于礼貌没继续辩解啥。面试结束后我复盘，由于自己这两年开始使用 obsidian 构建个人知识库，里面积累了大量经验和笔记。之前可能觉得这些笔记比较私人，但回顾后发现其实很多内容完全可以分享。于是想到何不直接基于 Obsidian 里有分享价值的笔记，修改后发表？这可以极大简化博客写作流程。</p>
<ol>
 <li><strong>灵感记录</strong>
  <br>
  obsidian 知识库中的记录就是<strong>输入</strong>的积累，这些笔记的形成就是基于一个点，然后一点点后续不断扩充成非结构化的经验。因此要作为博客发表，只需要稍作整合并厘清逻辑即可形成<strong>输出</strong>。</li>
 <li><strong>新建文章流程融合</strong>
  <br>
  该流程完全融入在 obsidian 中，输入与输出整合在一套系统中。新博客只需打上标签等元信息，便于后期统计。</li>
</ol>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250511213827336.png&amp;size=m" alt="image.png"></p>
<ol start="3">
 <li><strong>无缝的附件整理和发表</strong>
  <br>
  Obsidian 的强大插件系统让很多流程自动化。PicGo 插件可以直接粘贴图片自动上传图床并生成外链。我用的 halo 博客也有插件，一键同步本地文章到博客系统，后续更新也可随时拉取同步。至于原静态博客已可弃用，有 Obsidian 和 halo 定期备份就够了。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250511213933258.png&amp;size=m" alt="image.png"></li>
</ol>
<p>优化后的写博客流程明显流畅许多。平常在 Obsidian 里积累、更新各方面知识，写博客时只需在空闲时回顾、整理修改成文，一键同步到博客系统即可。内容不够完善可以本地随时修改、同步更新。就算当时内容不够全面，后续也可以本地修改随时同步。</p>
<p>诚然这个步骤还有继续改进的空间，但本人目前还是觉得是比较满意的，它主要是将我之前割裂的输入和输出系统整合了起来，减轻了我输出时各环节间的负担。流程变得顺畅了，博客的更新频率也就高了。</p>
<hr>
<p>喜欢我的文章吗？请不要吝啬自己的思考想法，欢迎在留言区讨论或提出建议。</p>
<ul>
 <li>如果您了解使用 RSS，可以使用 <a href="https://laffitto.xyz/feed.xml">https://laffitto.xyz/feed.xml</a> 订阅我的博客。</li>
 <li>另外我还通过 <a href="https://memo.laffitto.xyz/">memos詹詹碎言</a> 分享一些简短的生活记录和思考，可以使用 <a href="https://memo.laffitto.xyz/u/laffitto/rss.xml">https://memo.laffitto.xyz/u/laffitto/rss.xml</a> 订阅。</li>
 <li>如果您使用 Telegram，可以关注我的个人频道 <a href="https://laffitto.xyz/t.me/laffitto">TG 频道詹詹碎言</a>，里面同步了我上面两个部分内容。</li>
 <li>如果您使用 <a href="https://follow.is/">folo</a>，可以搜索点击<a href="https://app.follow.is/share/feeds/67377598479158275"><strong>乱谈府</strong></a> 订阅我的博客内容，感谢关注。</li>
</ul>]]></description><guid isPermaLink="false">/archives/easy-blog</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250511214430700.png&amp;size=m" type="image/jpeg" length="2033740"/><pubDate>Sat, 10 May 2025 15:06:00 GMT</pubDate></item><item><title><![CDATA[大模型框架]]></title><link>https://laffitto.xyz/archives/llm-framework</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E5%A4%A7%E6%A8%A1%E5%9E%8B%E6%A1%86%E6%9E%B6&amp;url=/archives/llm-framework" width="1" height="1" alt="" style="opacity:0;">
<p>本文是书籍 <a href="https://www.amazon.com/dp/B0DPLNK9GN?_encoding=UTF8&amp;qid=&amp;sr=&amp;linkCode=sl1&amp;tag=chiphuyen-20&amp;linkId=09d73f54fd16875a51c9c21b002626e0&amp;language=en_US&amp;ref_=as_li_ss_tl"># AI Engineering: Building Applications with Foundation Models</a> 读书笔记的另一部分。</p>
<p>相较与上篇博文聚焦于大模型的调优技术。本文是整体构建一个 AI 系统的框架，但有些知识点较为零散，随时同步笔记更新。</p>
<h2 id="整体-ai-框架">整体 AI 框架</h2>
<p>整个 AI 模型架构可以体现为：
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250410181222131.png&amp;size=m" alt="image.png"></p>
<p>从最基础的 query 和 response 流程开始，逐步增加不同的组件：</p>
<ul>
 <li>Enhance Context 增强上下文内容：包括 RAG，agent 等相关技术，加入各种数据库等，加强模型回复性能。</li>
 <li>Put in Guardrails 加入防护：包括输入和输出的防护，屏蔽输入的敏感信息，防止输出隐私泄露等问题，过程中要权衡好性能和延迟的关系。</li>
 <li>Add Model Router and Gateway 添加模型路由和网关：针对不同的提问，可以使用不同的模型进行回复。先使用模型（router）进行意图判断和下一步行动的预测，这里的模型可以使用一些基础模型或小的分类器模型，再分发给不同的模型进行后续处理。整个流程可以 routing - retrieval -&nbsp;generation&nbsp;- scoring 去理解。网关主要用于调用不同的模型（整合 API），有一些相关库例如：<a href="https://github.com/Portkey-AI/gateway">Portkey’s AI Gateway</a>,&nbsp;<a href="https://oreil.ly/D2X_Y">MLflow AI Gateway</a>,&nbsp;<a href="https://github.com/wealthsimple/llm-gateway">Wealthsimple’s LLM Gateway</a>,&nbsp;<a href="https://oreil.ly/ICRRA">TrueFoundry</a>,&nbsp;<a href="https://oreil.ly/St4W6">Kong</a>, and&nbsp;<a href="https://oreil.ly/0NuNb">Cloudflare</a>.</li>
 <li>Reduce Latency with Caches 使用缓存机制减少延迟。包含精确的缓存和语义缓存，用于快速响应。</li>
 <li>Add Agent Patterns 根据具体的需求添加不同的代理模式，由于实现整体的工作流。</li>
</ul>
<p>整个过程中需要用不同的监控指标去评估各个模块的性能，借助日志记录运行流程，以便快速排查问题。并且收集反馈的过程尽量做到无缝集成，例如 openai 主动询问哪个回复更好。</p>
<p>一些常见的模型框架包括 <a href="https://github.com/langchain-ai/langchain">LangChain</a>,&nbsp;<a href="https://github.com/run-llama/llama_index">LlamaIndex</a>,&nbsp;<a href="https://github.com/FlowiseAI/Flowise">Flowise</a>,&nbsp;<a href="https://github.com/langflow-ai/langflow">Langflow</a>,<a href="https://github.com/deepset-ai/haystack">Haystack</a> 等等。</p>
<h2 id="基本模型相关概念">基本模型相关概念</h2>
<h3 id="模型规模衡量">模型规模衡量</h3>
<p>大模型现在多以 Transformer 为基础架构，衡量模型大小的关键值如下：</p>
<ul>
 <li>The models dimension determines the sizes of the key, query, value, and output projection matrices in the transformer block. Q，K，V 值和输出投影矩阵的大小。</li>
 <li>The number of transformer blocks. Transformer 块的数量。</li>
 <li>The dimension of the feedforward layer.</li>
 <li>The vocabulary size.</li>
</ul>
<p>参数估算：例如，如果模型具有 70 亿个参数，并且每个参数使用 2 个字节（16 位）存储，则我们可以计算出使用此模型进行推断所需的 GPU 内存至少为 140 亿个字节（14 GB）。
 <br>
 但如果模型稀疏，参数估计会有偏差。例如MoE (mixture-of-experts) 技术，MOE 模型分为不同的参数组，每个组都是专家。只有一个专家的子集有效（用于处理每个令牌）。混合 8x7b 是八位专家的混合物，每个专家都有 70 亿个参数。如果没有两个专家共享任何参数，则其应有 8×70 亿个参数。但是，由于某些参数正在共享，它只有 467 亿参数。</p>
<p>模型计算要求的更标准化的单元是 FLOP (floating point operation)
 <br>
 FLOPs 测量一项任务的计算要求，FLOP/s 测量机器的峰值性能。两者写的比较相似，为避免混淆，OpenAI 等会用 FLOP/s-day 去衡量。</p>
<blockquote>
 <p>1 FLOP/s-day = 60 × 60 × 24 = 86,400 FLOPs</p>
</blockquote>
<p>总结，衡量模型的规模：</p>
<ul>
 <li>Number of parameters</li>
 <li>Number of tokens a model was trained on</li>
 <li>Number of FLOPs</li>
</ul>
<h3 id="post-training-训练后步骤">Post-Training 训练后步骤</h3>
<ul>
 <li>Supervised finetuning (SFT)：在高质量指令数据上对预训练模型进行微调，以优化对话模型而不是完成模型。</li>
 <li>Preference finetuning：进一步微调模型，以输出符合人类偏好的响应。偏好微调通常通过强化学习 (RL) 完成。
  <br>
  Techniques for preference finetuning include&nbsp;<a href="https://oreil.ly/iJG1q"><em>reinforcement learning from human feedback</em></a>&nbsp;(RLHF) (used by&nbsp;<a href="https://oreil.ly/tbgTi">GPT-3.5</a>&nbsp;and&nbsp;<a href="https://arxiv.org/abs/2307.09288">Llama 2</a>),&nbsp;<a href="https://arxiv.org/abs/2305.18290">DPO</a>&nbsp;(Direct Preference Optimization) (used by&nbsp;<a href="https://arxiv.org/abs/2407.21783">Llama 3</a>), and&nbsp;<a href="https://arxiv.org/abs/2309.00267"><em>reinforcement learning from AI feedback</em></a>&nbsp;(RLAIF) (potentially used by&nbsp;<a href="https://arxiv.org/abs/2212.08073">Claude</a>).</li>
</ul>
<blockquote>
 <p>关于 RLHF
  <br>
  RLHF 依靠奖励模型（reward model）。给定一对（提示，响应），奖励模型输出了响应效果的分数。独立评估每个样本也被称为点评估（pointwise&nbsp;evaluation）。
  <br>
  奖励模型可以在另一个模型（例如预训练或 SFT 模型）上从头开始训练或微调。</p>
</blockquote>
<h3 id="采样-sampling">采样 Sampling</h3>
<p>模型通过采样过程后进行构建输出。通常输出会取对数 logprobs</p>
<p>有如下多种采样策略：</p>
<ul>
 <li>Temperature：温度越高，选取最高 logit 值的可能性就越小。温度越低，模型输出值越一致（T=0）。通常建议使用0.7的温度用于创造性用例，因为它可以平衡创造力和可预测性。</li>
 <li>Top-k：为减少输出计算成本，仅选取前 k 个（50~500）logits 上计算 softmax 得出最终结果。</li>
 <li>Top-p：也称为核采样（nucleus sampling）。模型按降序对最可能的下一个值的概率求和，并在总和达到 p 时停止。仅考虑此累积概率内的值。语言模型中 top-p 采样的常见值通常在 0.9 到 0.95 之间。</li>
</ul>
<p>测试输出效果时，通常使用 logprobs，它可以将相乘概率转化为相加</p>
<div class="math math-display">p ( I l o v e f o o d ) = p ( I ) \times p ( I | l o v e ) \times p ( f o o d | I )</div>
<div class="math math-display">l o g p r o b ( I l o v e f o o d ) = l o g p r o b ( I ) + l o g p r o b ( I | l o v e ) + l o g p r o b ( f o o d | I , l o v e )</div>
<p>为了避免偏向短序列，通常对除以序列长度得到平均 logprob。</p>
<h3 id="结构化输出">结构化输出</h3>
<p>主要对以下两种情况至关重要：</p>
<ul>
 <li>需要结构化输出的任务。最常见类别是语义解析，涉及将自然语言转换为结构化的机器可读格式。</li>
 <li>下游应用程序使用其输出的任务。在这种情况下，任务本身不需要构造输出，但是由于其他应用程序使用了输出，因此需要通过这些应用程序来解析它们。</li>
</ul>
<h2 id="评估-ai-系统的方法">评估 AI 系统的方法</h2>
<p>评估基础模型有以下难点</p>
<ul>
 <li>越高质量的模型越难以评估</li>
 <li>基础模型的开放性质，无法同传统方法进行评估</li>
 <li>大多数模型都是黑匣子，不提供详细的模型结构。</li>
</ul>
<p>接下来列举一些开放性的评估方式</p>
<h3 id="语言模型指标">语言模型指标</h3>
<p>语言模型的指标，以下 4 个值密切相关。</p>
<ul>
 <li>cross entropy 交叉熵
  <br>
  用于衡量模型预测的概率分布与真实分布之间的差距，交叉熵越小，说明模型的预测越精准。
  <br>
  <span class="math math-inline">H(P, Q) = -\sum_{x} P(x) \log Q(x)</span></li>
</ul>
<ul>
 <li><span class="math math-inline">P(x)</span> 是真实分布（通常是训练数据中的分布）。</li>
 <li><span class="math math-inline">Q(x)</span> 是模型预测的分布。</li>
</ul>
<ul>
 <li>
  <p>perplexity, PPL 困惑度
   <br>
   困惑度是交叉熵的指数形式： <span class="math math-inline">PPL = 2^{H(P, Q)}</span>
   <br>
   同样可以使用自然对数：<span class="math math-inline">PPL = e^{H(P, Q)}</span>
   <br>
   模型在预测下一个 token 时的平均不确定性。<strong>PPL 越小，模型越确定</strong>，越能准确预测下一个 token。</p>
 </li>
 <li>
  <p>BPC (bits-per-character)
   <br>
   <span class="math math-inline">BPC=H(P,Q)</span>，<strong>H (P, Q)</strong> 以<strong>2 为底</strong>的对数计算。
   <br>
   衡量的是<strong>编码每个字符所需的平均信息量</strong>。如果 BPC = 1.5，则表示每个字符平均需要 1.5 个比特来表示。BPC 越小，说明模型的预测越精准。</p>
 </li>
 <li>
  <p>BPB (bits-per-byte)
   <br>
   与 BPC 类似，字节（byte）而非字符（character）为单位。<span class="math math-inline">BPB = 8 \times BPC</span></p>
 </li>
</ul>
<table>
 <thead>
  <tr>
   <th><strong>概念</strong></th>
   <th><strong>定义</strong></th>
   <th><strong>单位</strong></th>
   <th><strong>计算公式</strong></th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><strong>交叉熵 (H)</strong></td>
   <td>衡量模型预测的概率分布与真实分布的差距</td>
   <td>bits/token（如果以 2 为底）</td>
   <td><span class="math math-inline">-\sum P(x) \log Q(x)</span></td>
  </tr>
  <tr>
   <td><strong>困惑度 (PPL)</strong></td>
   <td>交叉熵的指数形式，表示平均不确定性</td>
   <td>无单位</td>
   <td><span class="math math-inline">2^{H(P, Q)}</span></td>
  </tr>
  <tr>
   <td><strong>BPC（每字符比特数）</strong></td>
   <td>交叉熵的另一种表示方式（以 2 为底）</td>
   <td>bits/character</td>
   <td><span class="math math-inline">-\sum P(x) \log _2 Q(x)</span></td>
  </tr>
  <tr>
   <td><strong>BPB（每字节比特数）</strong></td>
   <td>BPC 的 8 倍，以字节为单位衡量信息量</td>
   <td>bits/byte</td>
   <td><span class="math math-inline">8 \times BPC</span></td>
  </tr>
  <tr>
   <td></td>
   <td></td>
   <td></td>
   <td></td>
  </tr>
 </tbody>
</table>
<blockquote>
 <p>关于 Perplexity 的解释：</p>
 <ul>
  <li>数据结构化越高，perplexity 越低。</li>
  <li>词汇量越高，perplexity 越高</li>
  <li>上下文长度越长，perplexity 越低</li>
 </ul>
</blockquote>
<h3 id="相似度测算">相似度测算</h3>
<p>需要评估响应与参考数据的相似性，可以使用以下方法：</p>
<ul>
 <li>让评估者做出判断</li>
 <li>Extra match 确切匹配，生成与参考是否完全相同。</li>
 <li>Lexical similarity 词汇相似性，生成与参考词汇外观相似度。
  <br>
  使用 N-gram similarity，基于 N 个词汇序列而不是单个单字计算相似度。通常的指标为 BLEU, ROUGE, METEOR++, TER,&nbsp;and CIDEr。</li>
 <li>Semantic similarity 语义相似性，生成与参考含义的相似程度。
  <br>
  需借助 embedding，将文本转化为数值表示，这也是最常见的方法。通常指标为 <a href="https://arxiv.org/abs/1904.09675">BERTScore</a>&nbsp;(embeddings are generated by BERT) and&nbsp;<a href="https://oreil.ly/v2ENK">MoverScore</a>&nbsp;(embeddings are generated by a mixture of&nbsp;algorithms).</li>
</ul>
<p>相似度测算是一个重要的评估过程，包含在 AI 系统的多种流程中。</p>
<ul>
 <li>Retrieval and search 查找类似查询的项目，包含直接和嵌入方法。</li>
 <li>Ranking 排行：基于与查询的相似程度对项目进行排名。</li>
 <li>Clustering 聚类：聚类彼此相似的数据。</li>
 <li>Anomaly detection 异常检测：检测与其余的最小相似的项目。</li>
 <li>Data deduplication 数据删除：删除与其他项目太相似的项目。</li>
</ul>
<h3 id="借助-ai-进行评估">借助 AI 进行评估</h3>
<p>很多情况下可以借助 AI 进行评估工作，此时 AI 评估的 prompt 需要符合以下标准：</p>
<ul>
 <li>模型要执行的任务，例如评估生成的答案与问题之间的相关性。</li>
 <li>模型应遵循的标准进行评估，例如“你的主要关注点是确定生成的答案是否包含足够的信息，以根据标准答案来回答所提出的问题。”指令越详细，越好。</li>
 <li>设置评分系统（scoring system），例如：
  <ul>
   <li>分类，例如好/坏或相关/无关/中性。</li>
   <li>离散的数值，例如 1 到 5。离散的数值可以被视为分类的特殊情况，其中每个类具有数值解释而不是语义解释。</li>
   <li>连续数值，例如 0 到 1 之间。评估相似度可以用到。</li>
  </ul></li>
</ul>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250402162350541.png&amp;size=m" alt="image.png"></p>
<p>AI 评估的不足之处：</p>
<ul>
 <li>Inconsistency 不一致性。</li>
 <li>Criteria ambiguity 标准歧义。不同工具模型的评分系统和定义是不统一的。因此如果无法看到对应的 prompt 不要去轻信 AI 评估</li>
 <li>Increased costs and latency 增加成本和延迟。实际上可以使用与被评判模型性能较低的模型用作评判，因为判断比生成更加简单。</li>
 <li>Biases of AI AI 判断有偏差。很多 AI 会倾向于第一个答案，而人类更会倾向于最后一个答案。有些时候也会偏向于更长的答案，尽管很多时候表达结果是冗余的。</li>
</ul>
<p>常用的 AI 评估方法：</p>
<ul>
 <li>Reward model 奖励模型</li>
 <li>Reference-based judge 基于参考的评估。基于正常的参考评估其相似性。</li>
 <li>Preference model 偏好模型。给定 prompt 和多个不同的回答结果，判断哪个回答更加符合用户的偏好。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250402164324025.png&amp;size=m" alt="image.png"></li>
</ul>
<p>AI 基础模型最终目标是为了下游的应用服务。</p>
<h2 id="评估-ai-系统">评估 AI 系统</h2>
<p>具体的实践过程可以如下参考</p>
<h3 id="评估标准">评估标准</h3>
<p>评估 AI 系统可以从以下几方面进行评估：</p>
<ul>
 <li>domain-specific capability 特定领域的能力
  <ul>
   <li>是否有在目标领域中实现该功能的能力。</li>
  </ul></li>
 <li>generation capability 生成能力
  <ul>
   <li>Factual consistency 事实一致性，包括上下文内容的一致和全局知识一致，注意幻觉的产生。同时注意 Knowledge-augmented verification 即知识调查的验证能力。其验证能力可拆解为如下四个步骤：
    <ul>
     <li>使用 AI 将回答分为单个语句。</li>
     <li>修改每个语句使其独立（消除上下文的指代与歧义）</li>
     <li>对于每个语句进行检索操作（内部 or 外部开放 API 检索）</li>
     <li>借助 AI 确定语句与检索内容是否一致。</li>
    </ul></li>
   <li>事实一致性是针对 RAG 系统的关键评估标准。</li>
  </ul></li>
 <li>instruction-following capability 遵循指导能力
  <ul>
   <li>按照要求进行输出是很重要的能力。不同基准测试有着不同的标准，常见的有 <a href="https://arxiv.org/abs/2311.07911">IFEval</a>&nbsp;and&nbsp;<a href="https://arxiv.org/html/2401.03601v1">INFOBench</a>
    <ul>
     <li>Google 基准 IFEVAL（Instruction-Following Evaluation）的重点是该模型是否可以按照预期格式产生输出。</li>
     <li>Infobench，对跟随指令的含义有更广泛的看法。除了评估模型遵循 IFEVAL 这样的预期格式的能力外，InfoBench 还评估了模型遵循内容限制的能力</li>
    </ul></li>
   <li>Roleplaying 角色扮演，扮演虚构假定的角色完成对应任务。评估角色扮演能力的基准包括 RoleLLM (<a href="https://arxiv.org/abs/2310.00746">Wang et al., 2023</a>) 和 CharacterEval (<a href="https://arxiv.org/abs/2401.01275">Tu et al., 2024</a>)</li>
  </ul></li>
 <li>cost and latency 成本和延迟
  <ul>
   <li>评估模型时，重要的是平衡质量，延迟和成本三个方面。</li>
  </ul></li>
</ul>
<h3 id="模型选择">模型选择</h3>
<p>选择一个合适的模型至关重要，模型可以分为硬属性（模型无法更改的部分，例如使用许可，训练数据，模型大小等）和软属性（可以自我更改的部分，例如准确率，模型毒性，事实一致性等）
 <br>
 模型选择评估可包含如下 4 个步骤：</p>
<ol>
 <li>根据硬属性过滤出不合适的模型。</li>
 <li>使用公开可用的信息，例如，基准性能和排行榜排名，缩小尝试，寻找合适模型，平衡不同的目标。</li>
 <li>使用自己的 pipeline 进行评估，找到最佳模型。</li>
 <li>不断监视生产中的模型以检测故障并收集反馈以改善应用程序。</li>
</ol>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250402213526842.png&amp;size=m" alt="image.png"></p>
<p>关于使用自托管模型还是 API，可以从如下几点考虑：</p>
<ul>
 <li>Data privacy 数据隐私</li>
 <li>Data lineage and copyright 数据来源和版权</li>
 <li>Performance 性能表现</li>
 <li>functionality 功能，例如 Scalability，功能调用，结构化输出，输出保护等等。</li>
 <li>costs API 成本</li>
 <li>control, access, and transparency 可控制程度和透明度</li>
 <li>on-device deployment 设备部署问题</li>
</ul>
<p>公开的模型基准榜
 <br>
 Huggingface 排行榜 <a href="https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard#/">Open LLM Leaderboard - a Hugging Face Space by open-llm-leaderboard</a></p>
<h3 id="如何设计评估-pipeline">如何设计评估 pipeline</h3>
<p>遵循以下内容：</p>
<ol>
 <li>Evaluate All Components in a System 评估系统中所有的组件。独立判断出各个组件的功能性，保证都能在要求中运行。</li>
 <li>Create an Evaluation Guideline 创建评估指南
  <ul>
   <li>定义评估标准（相关性，事实一致性，安全情况等等）。</li>
   <li>创建带有具体示例的评分系统。</li>
   <li>与真实世界的具体业务相互联系。</li>
  </ul></li>
 <li>Define Evaluation Methods and Data 评估方法和数据。选择合适的具体的方法和对应的数据进行效果评估。针对模型性能，OpenAI 的经验是，对于分数差的每 3 倍降低，所需的样本数量增加 10 倍。</li>
</ol>
<h2 id="数据集工程">数据集工程</h2>
<p>在数据规划上，数据需遵循以下标准：</p>
<ul>
 <li>数值质量：少量的高质量数据可以胜过大量嘈杂的数据。数据一般要求以下特征：相关，与任务要求保持一致，持续性高，格式统一正确，数据不重复和合规。</li>
 <li>数据覆盖范围：数据尽可能广泛，例如能够理解错别字，那么训练数据就应该包含错别字。</li>
 <li>数据数量：从小数据集开始测试，预估需要多少数据。如果有少量数据，则可能需要在更高级的模型上使用 PEFT。如果有大量数据，可以使用较小的模型进行完整的 finetuning。</li>
</ul>
<p>数据增强与合成
 <br>
 对于有限的数据，可以用同义词的词典找到类似的单词，也可以通过在单词嵌入空间中彼此接近嵌入的词来找到类似的单词。数据合成的步骤可以使用 AI 模型实现，并可以像真实数据一样使用启发式方法过滤</p>
<p>数据处理
 <br>
 优化数据处理效率的方法：</p>
<ul>
 <li>首先对数据进行观察，选择合适的处理顺序以节省时间。</li>
 <li>批量数据脚本运用到数据之前保持进行充分的测试。</li>
 <li>所有的数据处理保留原始的副本。</li>
</ul>
<p>处理过程包括:</p>
<ul>
 <li>检查数据：评估其质量，获取相关信息和统计方面数据，是否应符合某种分布等。</li>
 <li>避免重复数据：重复数据会引发模型的偏见。删除重复数据的方案可以考虑相似度测量等技术。一些删除重复数据的项目&nbsp;<a href="https://github.com/arsenetar/dupeguru">dupeGuru</a>,&nbsp;<a href="https://github.com/dedupeio/dedupe">Dedupe</a>,&nbsp;<a href="https://github.com/ekzhu/datasketch">datasketch</a>,&nbsp;<a href="https://github.com/life4/textdistance">TextDistance</a>,&nbsp;<a href="https://github.com/seatgeek/thefuzz">TheFuzz</a>, and&nbsp;<a href="https://github.com/google-research/deduplicate-text-datasets">deduplicate-text-datasets</a>.</li>
 <li>清洗数据：制定流程，保持模型的安全性。</li>
 <li>格式化数据：保持数据统一的格式化输入用于后续训练等操作。</li>
</ul>]]></description><guid isPermaLink="false">/archives/llm-framework</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250412162126395.png&amp;size=m" type="image/jpeg" length="2092683"/><pubDate>Sat, 12 Apr 2025 15:05:47 GMT</pubDate></item><item><title><![CDATA[大模型调优技术]]></title><link>https://laffitto.xyz/archives/LLM-optimization-methods</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E5%A4%A7%E6%A8%A1%E5%9E%8B%E8%B0%83%E4%BC%98%E6%8A%80%E6%9C%AF&amp;url=/archives/LLM-optimization-methods" width="1" height="1" alt="" style="opacity:0;">
<p>本文是书籍 <a href="https://www.amazon.com/dp/B0DPLNK9GN?_encoding=UTF8&amp;qid=&amp;sr=&amp;linkCode=sl1&amp;tag=chiphuyen-20&amp;linkId=09d73f54fd16875a51c9c21b002626e0&amp;language=en_US&amp;ref_=as_li_ss_tl"># AI Engineering: Building Applications with Foundation Models</a> 读书笔记的一部分。结合个人知识的经验思考摘录，体系很庞大，随时同步笔记更新。</p>
<p>大模型不能直接运用于实际生产，通常需要加上或多或少的操作。即便是最简单的问答，本质上也可以理解为简化的有 prompt 的<code>提问</code>(query)，在经过大模型后得到对应<code>响应</code>(response)。为了实现复杂的功能或者工作流，不同的调优技术需要添加到基础大模型上。
 <br>
 每种不同的技术都有着海量的细节，钻研细节固然重要，但是自上而下梳理整体的框架更为重要，接下来是我做一些简短的思路梳理。</p>
<h2 id="prompt-engineering-提示词工程">Prompt Engineering 提示词工程</h2>
<p>Prompt 基本上是最简单的调优方法，通过添加合适的提示词，让模型实现较为复杂的功能。
 <br>
 Prompt 通常由以下一个或多个部分组成：</p>
<ul>
 <li>Task description 任务说明。希望模型实现的功能，包括模型扮演的角色和输出格式等。</li>
 <li>Example (s) of how to do this task 任务的示例。一个或多个具体的例子。</li>
 <li>Task 具体的任务。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250406164643876.png&amp;size=m" alt="image.png"></li>
</ul>
<blockquote>
 <p>Zero-shot 和 few-shot：在 prompt 中提示的例子称为 shot，zero-shot 表示没有提示示例。过多的示例会增加响应延迟和成本。</p>
</blockquote>
<p>Prompt 分为 system prompt 和 user prompt。通常会制定模板，将应用程序开发人员提供的说明放入 system prompt 中，而用户提供的说明则放入 user prompt 中。</p>
<p>精心制作的 system prompt 可以提高性能。可能原因如下：</p>
<ul>
 <li>system prompt 通常第一个出现，而模型会更好处理第一个说明。</li>
 <li>模型可能经过 post-train，本身会更加关注 system prompt。
  <br>
  研究表明 (<a href="https://arxiv.org/abs/2307.03172">Liu et al., 2023</a>)，一个模型在理解开始和结束时的 prompt 要好得多。</li>
</ul>
<h3 id="如何写更好的-prompt">如何写更好的 Prompt</h3>
<ol>
 <li>写出清晰明确的说明：
  <ul>
   <li>在没有歧义的情况下解释希望模型做什么：比如明确的评分标准（离散值）等等</li>
   <li>要求模型扮演的角色</li>
   <li>提供完整的例子</li>
   <li>指定的输出格式：结构化输出</li>
  </ul></li>
 <li>提供足够的上下文知识，或者限定特定的上下文知识，不过这需要借助 RAG 和 Web 搜索等技巧。</li>
 <li>将复杂的任务分解为更为简单的子任务：例如针对一个聊天机器人，先进行意图分类，再针对不同的意图，根据不同的 prompt 生成对应响应。对于具体的分类和操作方法，需要根据<strong>成本和延迟</strong>进行测试权衡。可以使用较弱的模型进行意图分类，较强的模型进行后续生成响应。</li>
 <li>给模型更多思考的时间：chain-of-thought (CoT) 明确要求模型进行逐步思考以达到更好的性能。最简单的方法是在 prompt 中加入 <code>think step by step</code> 或 <code>explain your decision</code> ，以鼓励模型进行深度思考。</li>
 <li>不断更新迭代模型的 Prompt：每个模型的 prompt 都会不一致。</li>
</ol>
<h3 id="评估-prompt-的工具">评估 Prompt 的工具</h3>
<p>旨在自动化整个自动化工程流程的工具包括&nbsp;OpenPrompt (<a href="https://arxiv.org/abs/2111.01998">Ding et al., 2021</a>) and DSPy (<a href="https://arxiv.org/abs/2310.03714">Khattab et al., 2023</a>) 。任务指定输入和输出格式，评估指标和评估数据。这些提示优化工具会自动找到提示或提示链，以最大程度地提高评估数据的评估指标。这个过程类似于一般模型中的超参数调参。</p>
<p>有些工具用于快速构建 prompt，例如 <a href="https://github.com/guidance-ai/guidance">Guidance</a>,&nbsp;<a href="https://github.com/outlines-dev">Outlines</a>,&nbsp;<a href="https://github.com/instructor-ai/instructor">Instructor</a> 指导模型进行结构化输出。</p>
<p>一些 prompt 分享网站：<a href="https://oreil.ly/q1EHt">PromptHero</a>&nbsp;and&nbsp;<a href="https://oreil.ly/J3Crv">Cursor Directory</a>。</p>
<p>建议将 prompt 和代码分开，这样利于复用，测试，可读性也更高。有些工具提出了特殊的格式来存储 Prompt，例如 <a href="https://oreil.ly/ceZLs">Google Firebase’s Dotprompt</a>,&nbsp;<a href="https://oreil.ly/FuBEI">Humanloop</a>,&nbsp;<a href="https://oreil.ly/nriHw">Continue Dev</a>, and&nbsp;<a href="https://github.com/promptfile/promptfile">Promptfile</a>。</p>
<h3 id="prompt-安全性防御">Prompt 安全性防御</h3>
<p>有时候模型可能会收到攻击导致如下影响：</p>
<ul>
 <li>prompt 提取：应用被复制复用。</li>
 <li>越狱（Jailbreaking and prompt injection）：让模型做坏事。</li>
 <li>信息提取：上下文信息和训练数据被提取泄露。`</li>
</ul>
<p>许多攻击被串联为大量的指令，导致模型无法区分系统指令和恶意指令。OpenAI 在这篇论文“The Instruction Hierarchy: Training LLMs to Prioritize Privileged Instructions” (<a href="https://arxiv.org/abs/2404.13208">Wallace et al., 2024</a>) 中提出一个包含四个优先级的指令层次结构。
 <br>
 System prompt - User prompt - Model outputs - Tool outputs
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250406175602806.png&amp;size=m" alt="image.png"></p>
<p>在对模型进行安全性微调时，重要的不仅是训练模型识别恶意提示，还要训练它在处理边缘请求时生成安全的回复（所谓边缘请求，是指那些可能引发安全或不安全回复的请求）。</p>
<p>如何进行防御：</p>
<ul>
 <li>Prompt 级别防御：创建一些鲁棒性更强的 system prompt，明确禁止某些行为。一个简单方法是在 user prompt 之前和之后都重复一次 system prompt。</li>
 <li>系统级别防御：尽可能的孤立特定数据间的联系。MCP 逐渐可以做到这些事情。</li>
</ul>
<p>对于需要较为复杂的上下文构建工作，2 个主导的模式是 <code>RAG</code> 和 <code>Agent</code>。</p>
<ul>
 <li>RAG (retrieval-augmented generation)：让模型从外部数据源检索相关信息。</li>
 <li>Agent：构建大的工作流，让模型使用 Web 搜索和新闻 API 等工具来收集信息。</li>
</ul>
<h2 id="rag-检索增强生成">RAG 检索增强生成</h2>
<p>RAG 主要目的是克服模型上下文限制。但即便模型上下文信息逐渐变大，RAG 依旧很重要，原因如下：</p>
<ul>
 <li>无论模型上下文多大，总会有需要更长上下文的存在。</li>
 <li>即便能够处理更多的上下文，但不一定能很好的使用，一些冗余或者格式的偏差会导致性能骤降，依旧需要借助其他技术改进。</li>
</ul>
<blockquote>
 <p>your knowledge base is smaller than 200,000 tokens (about 500 pages of material), you can just include the entire knowledge base in the prompt that you give the model, with no need for RAG or similar methods” (<a href="https://oreil.ly/v-T_4">Anthropic, 2024</a>)</p>
</blockquote>
<h3 id="rag-的架构">RAG 的架构</h3>
<p>RAG 主要由 2 部分组成：</p>
<ul>
 <li>retriever 检索器：用于从外部存储器检索信息。RAG 的好坏取决于检索器功能的质量，可分为以下 2 个步骤：
  <ul>
   <li>indexing 索引：涉及数据处理，以便之后可以快速检索</li>
   <li>querying 查询：发送查询内容以检索相关数据</li>
  </ul></li>
 <li>generator 生成器：基于检索到的信息生成对应响应。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250407180824716.png&amp;size=m" alt="image.png"></li>
</ul>
<p>Retrieval 算法可分为两个方面：</p>
<ol>
 <li>Term-based retrieval 基于术语的检索
  <br>
  给定查询，查找相关文档的最直接方法是找到与其相关的关键词。
  <br>
  文档中一个项出现的次数称为术语频率 (TF, term frequency)。同时一个术语的重要性与它出现的文档数量成反比，称为逆文档频率 (IDF, inverse document frequency）。TF-IDF 是一种结合这两个指标的算法。</li>
</ol>
<p>两个常见的基于术语的检索解决方案是 <code>Elasticsearch</code> 和 <code>BM25</code>。</p>
<ol start="2">
 <li>Embedding-based retrieval 基于嵌入的检索
  <br>
  主要基于嵌入后语义信息对目标查询进行查询，也可以称为 semantic retrieval。
  <br>
  该种方法的 index 需要将原始数据块进行嵌入，存储为<code>矢量数据库</code> (vector database)。Query 过程需要将查询先转化嵌入，后检索与原始数据嵌入最接近的 K 个数据块进行后续操作。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250407181028980.png&amp;size=m" alt="image.png"></li>
</ol>
<p>这个过程会涉及到 vector search，对于大型数据集，通常使用 <strong>近似最近邻</strong> (ANN, approximate nearest neighbor) 算法，该类算法专门用于在<strong>高维空间中高效查找近似最近邻</strong>的数据点。</p>
<p><a href="https://ann-benchmarks.com/index.html">ANN-Benchmarks</a> 展示了在多个数据集上比较了不同的 ANN 算法，并考虑了索引和查询之间的权衡。具体参考实现：<em>FAISS</em>&nbsp;(Facebook AI Similarity Search) (<a href="https://arxiv.org/abs/1702.08734">Johnson et al., 2017</a>), Google’s&nbsp;<em>ScaNN</em>&nbsp;(Scalable Nearest Neighbors) (<a href="https://oreil.ly/faJqj">Sun et al., 2020</a>),&nbsp;<a href="https://github.com/spotify/annoy">Spotify’s&nbsp;<em>Annoy</em></a>&nbsp;(Bernhardsson, 2013), and&nbsp;<a href="https://oreil.ly/4ATBC"><em>Hnswlib</em></a>&nbsp;(<a href="https://github.com/nmslib/hnswlib">Hierarchical Navigable Small World</a>) (Malkov and Yashunin, 2016).</p>
<p>用于评估 RAG 性能的指标如下：</p>
<ul>
 <li>context precision : 在所有检索到的文件中，与查询有关的百分比。即正确使用的上下文数/模型使用所有上下文数。</li>
 <li>context recall：在所有与检索有关的文件中（对比参考），与查询有关的百分比。即正确使用的上下文数/所有应使用的上下文数（参考标准）。</li>
</ul>
<p>对于嵌入检索，同样需要评估嵌入的质量。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250407200306764.png&amp;size=m" alt="image.png"></p>
<p>通常以上两种方法可以结合起来一起使用用于提高性能，统称为<code>混合搜索</code> (hybrid search)。用于组合不同排名的算法称为 <a href="https://oreil.ly/3xtwh">reciprocal rank fusion (RRF)</a>&nbsp;(Cormack et al., 2009).</p>
<h3 id="retrieval-优化">Retrieval 优化</h3>
<ol>
 <li>Chunking strategy 分块策略
  <br>
  最简单的是基于特定单元长度将文档分为相同长度的块。或者使用越来越小的单元长度来递归拆分文档。注意拆分的时候需要设定一定部分的重叠块，以免在关键上下文处丢失信息。例如如果将块大小设置为 2,048 个字符，则可以将重叠大小设置为 20 个字符。</li>
</ol>
<p>更多的块会给模型提供更好的信息，但同时可能因为单个块字符减少而丢失信息，所有参数设置都需要实验尝试。</p>
<ol start="2">
 <li>
  <p>Reranking
   <br>
   对于特定任务，重排可以优化性能。文档也可以根据时间来重新排序，从而使更新的数据给予更高的权重。</p>
 </li>
 <li>
  <p>Query rewriting
   <br>
   查询重写有时候也被称为 query reformulation, query normalization 或 query expansion。主要是防止在上下文分块过程中语句产生歧义。在传统的搜索引擎中，查询重写通常是使用启发式方法完成的。在 AI 应用程序中，还可以使用其他 AI 模型进行查询重写。</p>
 </li>
 <li>
  <p>Contextual retrieval
   <br>
   上下文检索背后的想法是增加具有相关上下文的每个块，以使检索相关的块更容易。例如分块后可以增加原始文档的上下文（例如原始文档的标题和摘要）增强每个块。
   <br>
   <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250407203135918.png&amp;size=m" alt="image.png"></p>
 </li>
</ol>
<p>评估 retrival 方法需要考虑但不限于以下几点：</p>
<ul>
 <li>支持哪些检索机制，是否支持混合检索。</li>
 <li>如果使用了矢量数据库，支持哪些嵌入模型和矢量搜索算法。</li>
 <li>在数据存储和查询方面是否有扩展性。</li>
 <li>索引数据需要多长时间，一次可以批处理多少数据。</li>
</ul>
<h3 id="结合多种模式的-rag">结合多种模式的 RAG</h3>
<p>图像：如果图像元数据（例如标题，标签和字幕），则可以使用元数据检索。或者使用 <code>CLIP</code> (<a href="https://arxiv.org/abs/2103.00020">Radford et al., 2021</a>) 作为多模态的嵌入模型。
 <br>
 表格数据：需要模型有着生成和查询 SQL 的能力 (Text-to-SQL)</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250407205406657.png&amp;size=m" alt="image.png"></p>
<h2 id="agent">Agent</h2>
<p>代理 (Agent) 是由它所处的环境和它能执行的动作决定的。代理两个重要的概念是<code>工具</code>（Tools）和<code>计划</code>（Planning），借助这些概念根据不同需求制造复杂的程序。</p>
<p>这个概念总体来说比较宽泛且抽象，在我看来实际上你构建的每个任务和程序一定程度上都可以理解为 Agent，这里不做过多的展开。</p>
<h3 id="tool-工具能力">Tool 工具能力</h3>
<p>工具主要是一些可以让大模型与其他各流程交互的能力。
 <br>
 最近火热的 MCP (Model Context Protocal) 概念可以理解为 LLM 到 Agent 中间的协议层，一方面更利于模型与具体不同程序的交互，而这其中也可以避免数据的影响，这点和 Agent 的 Tools 思想是相符合的。越来越多的 MCP 开源项目表明大模型与万物互联的能力大大增加，不用重复去造轮子。</p>
<h3 id="planning-计划能力">Planning 计划能力</h3>
<p>计划是 Agent 在处理过程中的尝试。通常实施一项任务，为了避免无效的执行而浪费资源，应该将 <code>计划</code> 过程和 <code>执行</code> 过程解耦。先让 Agent 生成计划，验证后再继续执行，通常可以使用启发式算法进行验证。</p>
<p>如果一个计划评估后是不成功的，可以要求 <code>计划者</code>（planner）再生成一个计划，最后进行执行。而这个 <code>计划者</code> 是可以要求模型自己生成。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250411203002679.png&amp;size=m" alt="image.png"></p>
<h2 id="finetuning-微调">Finetuning 微调</h2>
<p>Finetuning 是迁移学习的一种技术，旨在提高模型在特定领域的功能性与质量。与以往简单 CNN 等模型不同的是，大模型的 inetuning 需要耗费大量的资源。很多情况下，进行 finetuning 只会提供一个很小的增量改进，但实际任务的优先级可能并不值得这样做。</p>
<h3 id="finetuning-技术">Finetuning 技术</h3>
<p>大模型中通常使用 <code>PEFT</code> (parameter-efficient finetuning) 技术进行实现。通过将其他参数插入正确的位置中，可以使用少量可训练的参数实现强大的微调性能。使模型的原始参数保持不变，并且仅更新适配器 (adapter) 的参数（可训练参数）。</p>
<p>PEFT 方法分为多种：</p>
<ul>
 <li>Adapter-based methods 通常指所有涉及模型权重附加模块的方法，增加可训练参数，其中 <code>LoRA</code> 最为突出也最常用。</li>
 <li>Soft prompt-based methods 通过引入特殊的、可训练的 token（类似于向量嵌入），改变模型对输入的处理方式。</li>
</ul>
<p>更多不同的 finetuning 策略可以参考 <a href="https://docs.google.com/document/d/1rqj7dkuvl7Byd5KQPUJRxc19BJt8wo0yHNwK84KfU3Q/edit?tab=t.0">OpenAI’s finetuning best practices document</a>，可以采取 progression path 和 distillation path。</p>
<h3 id="模型合并">模型合并</h3>
<p>针对不同任务，finetuning 后可能会达到众多模型，模型合并的目的是创建一个单个模型，该模型比单独使用所有组成模型提供了更多的价值。本质上是联合学习 (federated learning) 的一种方式。不同的组合方法如下：</p>
<ol>
 <li>Sum 加法
  <br>
  将模型输出的权重值求和，注意需要先进行维度的统一。组合方法可以通过线性组合或球形线性差值 (Spherical LinEar inteRPolation, SLERP)。合并过程中考虑修剪掉冗余特定任务参数。</li>
 <li>Layer Stacking 层堆叠
  <br>
  通常选用一个或多个模型中不同的层，将其堆叠起来，通常之后还需进行 finetuning 以达到更好的效果。该种方法可以用于训练 MoE (mixture-of-experts) 模型，参考“Sparse Upcycling: Training Mixture-of-Experts from Dense Checkpoints” (<a href="https://arxiv.org/abs/2212.05055">Komatsuzaki et al., 2022</a>).</li>
 <li>Concatenation
  <br>
  同一般深度学习的 concat，是在某个维度的堆叠。不过实际上不推荐使用这种方法，因为会增加模型的参数，增加的性能可能不足以额外的参数量。</li>
</ol>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250409155721092.png&amp;size=m" alt="image.png"></p>
<p>一些 finetuning 的框架：<a href="https://github.com/hiyouga/LLaMA-Factory">LLaMA-Factory</a>,&nbsp;<a href="https://github.com/unslothai/unsloth">unsloth</a>,&nbsp;<a href="https://github.com/huggingface/peft">PEFT</a>,&nbsp;<a href="https://github.com/axolotl-ai-cloud/axolotl">Axolotl</a>,&nbsp;<a href="https://github.com/Lightning-AI/litgpt">LitGPT</a>.</p>
<h2 id="关于-memory">关于 Memory</h2>
<h3 id="memory-mechanisms-记忆机制">Memory mechanisms 记忆机制</h3>
<p>Memory mechanisms 是指允许模型保留和利用信息的机制。AI 模型有三种记忆机制：</p>
<ul>
 <li>Internal knowledge：AI 模型自身训练学习的知识。</li>
 <li>Short-term memory：将以往对话的消息添加到模型上下文，以生成后续的响应。通常不会跨任务存在。</li>
 <li>Long-term memory：通过 RAG 等技术，模型可以检索外部的数据来源，可跨任务持续存在。</li>
</ul>
<p>AI 模型的存储系统主要有两个方面组成：</p>
<ul>
 <li>记忆管理：控制在 Short-term memory和 Long-term memory 中应该存储哪些信息。通常需要增加和删除操作，最简单的方法是 <code>FIFO</code> (first in, first out)，仅保存特定个数最近的消息。或者使用各种策略消除之前的冗余，例如用大模型对之前的消息做总结摘要。</li>
 <li>记忆检索：从 Long-term memory中检索与任务相关的信息。该流程类似与 RAG 检索。
  <br>
  ``</li>
</ul>
<h3 id="memory-bottlenecks">Memory Bottlenecks</h3>
<p>在 Finetuning过程中涉及训练，相较于一般的推断过程，需要耗费更多的计算资源。</p>
<h4 id="内存计算">内存计算</h4>
<p>推断过程参数计算，加载模型所需内存为 N × M，N 为模型的权重大小 (model weights)，M 为每个参数所需的内存。实际中 Transformer 中 key-value vectors 需要额外数值，外加激活函数值，通常可以认为这两部分所需内存为模型权重的 20%。因此推断模型所需内存为 $$ N \times M \times 1 . 2$$
 <br>
 考虑一个 13B 参数模型。如果每个参数需要 2 个字节，则模型内存将需要 13b×2bytes= 26 GB。推理的总内存将为 26 GB×1.2 = 31.2 GB。</p>
<p>而训练过程中，所需内存会增加，可以理解为Training memory = model weights + activations + gradients + optimizer states。一个简单的估算，这几个部分为模型权重的 3 倍。此时 13B 参数模型，若每个参数需要 2 个字节，训练总内存为 13b×3×2bytes=78 GB。</p>
<h4 id="内存数值表示">内存数值表示</h4>
<ul>
 <li>FP32 使用 32bits（4bytes）代表一个浮点，称为单精度。</li>
 <li>FP64 使用 64bits（8bytes）代表一个浮点，称为双精度。</li>
 <li>FP16 使用 16bits（2bytes）代表一个浮点，称为半精度。</li>
</ul>
<h4 id="quantization-量化">Quantization 量化</h4>
<p>量化的目的主要是减少模型的内存（减少精度），更易于推断和训练。有些模型也会使用混合精度 (mixed precision)，在减少精度的情况下同时保持较高的精度。
 <br>
 一般量化模型有 q2、q3、q4、q5、q6 和 q8。数字越小同样可以简单理解模型压缩率更高。模型名称中也有「K_M」或 「K_S」，其中是 K 量化，S 代表“小”，M 代表“中”，L 代表“大”。</p>
<h2 id="如何选择合适的技术">如何选择合适的技术</h2>
<p>通常来说如果如要改进某项任务的性能，先进行 Prompt，达到最大性能后，再考虑使用 RAG 或 Finetuning。如何选择需要判断模型现存的问题是 <code>information-based</code> 或 <code>behavior-based</code>。</p>
<ul>
 <li>若模型是 information-based 的问题，可以使用 RAG 方法。这里主要原因是模型输出是错误或过时的，由于没有足够的信息最终会导致幻觉等问题。</li>
 <li>若模型是 behavior-based 的问题，可以考虑 finetuning 方法。这个时候模型的输出大体内容通常是正确的，但是基础模型训练时缺少相关细节，导致输出细节与预想不符合。再有就是一些需要特定而小众的语法输出（包括对话语言，编程语言等），由于训练样本较少导致输出不好。</li>
</ul>
<p>简而言之，Finetuning 是用于形式的，RAG 是用于事实的。如果同时存在这两种问题，可以先从最基础的 term-based 的 RAG 开始尝试（例如 BM25）。
 <br>
 整体调节模型的工作流如下（来自&nbsp;<a href="https://oreil.ly/Ny1WI">OpenAI</a>&nbsp;(2023)），不过要注意每个步骤都要进行评估：</p>
<ol>
 <li>使用单独的 Prompt 执行任务，评估效果。</li>
 <li>在 prompt 中加入更多的示例，示例数在 1~50。</li>
 <li>如果此时模型由于缺少相关信息而效果不好，使用 RAG 连接到相关信息的数据源，并从简单的检索方法开始尝试。</li>
 <li>根据不同的效果展示，进行后续操作：
  <ul>
   <li>如果仍然是由于缺少信息而效果不好，尝试更好的 RAG 技术，例如嵌入工程。</li>
   <li>如果模型存在行为问题，例如生成无关，畸形或不安全的响应，可以尝试 finetuning。注意 finetuning 的工作和计算资源要求是巨大的。</li>
  </ul></li>
 <li>结合 RAG 和 Finetuning 技术以达到更好的效果。</li>
</ol>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250409104555097.png&amp;size=m" alt="image.png"></p>
<hr>
<p>喜欢我的文章吗？请不要吝啬自己的思考想法，欢迎在留言区讨论或提出建议。</p>
<ul>
 <li>如果您了解使用 RSS，可以使用 <a href="https://laffitto.xyz/feed.xml">https://laffitto.xyz/feed.xml</a> 订阅我的博客。</li>
 <li>另外我还通过 <a href="https://memo.laffitto.xyz/">memos詹詹碎言</a> 分享一些简短的生活记录和思考，可以使用 <a href="https://memo.laffitto.xyz/u/laffitto/rss.xml">https://memo.laffitto.xyz/u/laffitto/rss.xml</a> 订阅。</li>
 <li>如果您使用 Telegram，可以关注我的个人频道 <a href="https://laffitto.xyz/t.me/laffitto">TG 频道詹詹碎言</a>，里面同步了我上面两个部分内容。</li>
 <li>如果您使用 <a href="https://follow.is/">follow</a>，可以搜索点击<a href="https://app.follow.is/share/feeds/67377598479158275"><strong>乱谈府</strong></a> 订阅我的博客内容，感谢关注。</li>
</ul>]]></description><guid isPermaLink="false">/archives/LLM-optimization-methods</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250411212617866.png&amp;size=m" type="image/jpeg" length="2351025"/><pubDate>Fri, 11 Apr 2025 13:15:00 GMT</pubDate></item><item><title><![CDATA[「不止金钱」笔记]]></title><link>https://laffitto.xyz/archives/beyond-money-note</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E3%80%8C%E4%B8%8D%E6%AD%A2%E9%87%91%E9%92%B1%E3%80%8D%E7%AC%94%E8%AE%B0&amp;url=/archives/beyond-money-note" width="1" height="1" alt="" style="opacity:0;">
<p>不止金钱是生动活泼推出的一款<a href="https://www.xiaoyuzhoufm.com/podcast/65a625966d045a7f5e0b5640">播客栏目</a>，前些日子<a href="https://sspai.com/series/378/list">文字版</a> 上线少数派，作为老观众支持了一波。最近一段时间抽空看完了。栏目分为正篇和番外部分，正篇内容主要分为两块结构：</p>
<ul>
 <li>阐述投资思想：这里会分章节介绍投资中的概念与观念，包含从机构到散户的一些举动。</li>
 <li>延伸到生活中：将章节的具体投资思想应用到实际生活中，做到举一反三。
  <br>
  这些观念我基本看过大部分，有点面向小白，不过读下来还是有所收获。毕竟阅读东西也不能希望全书都能带给你新理解，但有一些新的认知就是难得可贵的。</li>
</ul>
<p>为了方便阅读，我把文字版自制成了电子书，有兴趣的可以读一读。链接如下：<a href="https://picgo-1306089623.cos.ap-nanjing.myqcloud.com/blog/2025-03-02-ovfeqq.epub">不止金钱20250302.epub</a>
 <br>
 📢 <strong>免责声明</strong> 📢
 <br>
 本电子书仅供学习交流使用，严禁用于商业用途或长期保存。请在<strong>24小时内自行删除</strong>，如果您喜欢本书，请<strong>购买正版</strong>以支持作者和出版商！如因下载或使用本文件产生任何后果，均由使用者自行承担，本人不对其负任何责任。</p>
<p>以下为一些自己感悟的画线内容收集与思考：</p>
<h2 id="正篇">正篇</h2>
<h3 id="情绪控制">情绪控制</h3>
<blockquote>
 <p>一个投资决策等于专业的认知和良好的情绪，并且排除风险。
  <br>
  投资应该是情绪和认知的变现。</p>
</blockquote>
<blockquote>
 <p>回到普通人的投资上，就一个建议：做投资的时候，我们要时刻标注自己的情绪。
  <br>
  但不幸的是，在投资中，压力是长期存在的。就像我陷入中度焦虑症时，每一天、每一刻，压力都不曾消失。在所有的投资落袋为安之前，都充满了不确定性。</p>
</blockquote>
<blockquote>
 <p>无论面对什么样的不确定性，<strong>我们都可以做一下拆分，看一下哪些元素不在我们的掌控范围之内，又有哪些是我们可以掌控的</strong>。这就像看待投资一样，乍一看全是运气，但仔细一想，又有可以应对的着力点。即使是七分天注定，三分靠努力，我们也要找出这三分来。有了这样的思路，我们就能降低一些茫然无措的状态，找到生活中的小确幸。</p>
</blockquote>
<p>以上几点都是关于情绪的说明。恐慌与贪婪，究竟是随波逐流还是逆向前行都来自于投资理念和认知。大环境的情绪对个人的影响是至关重要的，当你看到 app 中普天盖地的新闻，如何理性看待他们。说着容易，意识到容易，但做起来难。</p>
<blockquote>
 <p>用颜色标记情绪的工具有扎实的理论基础，是由耶鲁大学教授马克·布莱克特 (Marc Brackett) 和波士顿一位教授罗素 (James Russell) 共同开发的。
  <br>
  这个坐标图里，人的情绪分为两个维度，分别是「能量」和「愉悦」。横轴代表「愉悦」，从「极度不愉悦」到「极度愉悦」，简单来说也就是从很不开心到很开心。纵轴代表「能量」，代表你精神够不够，有没有活力。同样也是从极低到极高。</p>
</blockquote>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250301180257094.png&amp;size=m" alt="image.png"></p>
<p>在原点附近的情绪，<strong>其实是比较适合投资的稳定情绪状态</strong>。情绪不在原点附近，我们宁愿不做。这里就在控制自己的情绪，保持心态平稳在合适的范围去判断，才能减少头脑一热的事情发生。</p>
<blockquote>
 <p>一位朋友和我讲过自己在日常生活中进行情绪觉察的案例。有一天她突然意识到自己和伴侣吵架的时间，大部分都发生在睡觉前。她觉得可能是和能量值有关，因为睡前又累又困，能量值非常低，并不适合进行沟通，沟通中的一点点小摩擦就会让情绪失控。
  <br>
  所以她后来和伴侣商量了一个方法，就是晚上睡觉前禁止讨论正事，只有在吃饱喝足之后，也就是情绪相对良好的时候，才沟通严肃的事。不仅如此，他们还定了一个暗号，用来告诉对方：「我的能量值很低了」。这样对方就会明白自己并不是故意闹别扭，也不是真的生气，只是此时此刻情绪不在原点的中心范围内，可以先放下争论。所以，有意识地觉察情绪，对我们自己、我们的家人和周围的朋友而言，都很有帮助，可以避免很多不必要的误会。</p>
</blockquote>
<p>非常好的应用在日常中的情绪管理技巧。</p>
<h3 id="认知增加">认知增加</h3>
<blockquote>
 <p>「有效认知」= 证据+逻辑。否则可能只是一个观点、感觉，或是一种猜测。
  <br>
  第一个方法是：对我们听到的、媒体上看到的信息，督促自己区分事实和观点。只有事实、证据和数据才能组成「有效认知」，观点并没有那么重要。
  <br>
  第二个方法是：持续多问几个「为什么」，直到问出证据来。</p>
</blockquote>
<p>面对各种新闻时可以采取的行动。往往多问问，多想几步，很多情绪化的煽动内容就不攻自破了。</p>
<blockquote>
 <p>普通人不可能像机构一样砸钱，但是可以用客观、可靠、多元这三个要素去过滤信息。
  <br>
  <strong>尽量找一手信息</strong>。在没有一手信息的情况下，尽可能只参考严肃的信息源。
  <br>
  如果想投资一个具体的行业，也有一些比较方便的获取途径，这些研究不再是专业机构的特供产品。一个比较简单易得的方法是，注册一个第三方研究报告系统，这些研究报告名义上不针对个人投资者，只提供给机构，但我们可以以公司做研究的名义去开通相关账号。</p>
</blockquote>
<p>普通人面对信息噪音的一些经验。</p>
<blockquote>
 <p>一切投资研究都必须指向结论，而不是堆噪音。
  <br>
  所以前辈给我的建议就是「三七开」：70% 的精力放到微观上，把一个具体的公司研究清楚，剩下 30% 的时间跟踪宏观即可。
  <br>
  我们要用少量时间关注宏观变化。即使关注，也只关注事实和数字。这样下来，30% 的时间绰绰有余，同时情绪也留在了舒适区。我知道大家喜欢看、喜欢讨论宏观的内容，但把它们当作故事来听就足够了，最好不要作为决策依据。
  <br>
  芒格说过的一句话，很值得我们琢磨。他说：宏观是我们必须接受的，微观才是我们可以有所作为的。</p>
</blockquote>
<p>大量的信息没用，不断的筛掉噪音，有最终的结论才重要。每天打开各种新闻或者交易 app 都有各种普天盖地的新闻。不要将重点放在宏观叙事，问问和自己有啥关系。真正有讲的那么好还能感受不到？多关注可以参与决策的东西。</p>
<h3 id="止损">止损</h3>
<blockquote>
 <p>无论如何，一定要在自己的心理账本中设置一条止损线。
  <br>
  机构通常达到 30% 的损失后才会强制止损。但对于个人来讲，我观察到的现象是，亏损达到 30% 后，你就会灰心丧气，直接躺平了，这也符合正常人的情绪。因此，控制风险就是要尽量缩小心理账本。
  <br>
  把止损控制在更小的范围内，比如 10% 或 15%。我在量化投资策略里见过更严格的：只要下跌到了成本线，即使还没有产生亏损，也照样把投资标的清仓。当然，这只是个参考，我们肯定不会这么严格。不过尽量缩小心理账本之后，负面情绪和心理负担会降低很多。</p>
</blockquote>
<p>止损非常重要，因为投资简单来说就是何时买卖。一旦亏损热情会消耗，躺平会将这件事无限延期和自我麻痹。</p>
<blockquote>
 <p>分享一个概念叫做「情绪止损」，因为情绪也是资源，用光了就没了。
  <br>
  我从前对自己非常苛刻，一旦犯错就反复责问自己。事情过去没过去不重要，关键是要自责、要反思。这也和我们之前提到的教育经历有关，「吾日三省吾身」不够，恨不得「三十省吾身」，觉得自己不该这么做，进入持续的内耗和负反馈。后来，我把止损的想法用到自己的情绪上，只要自责超过一天，我就会提醒自己：情绪消耗已经到 -10% 了，这就是止损线，就此打住。因为情绪是有限的，剩下的能量要用到下一件事情上。
  <br>
  当然，说起来好像特别简单，实际做起来，<strong>需要持续不断给自己心理暗示，才能养成习惯。</strong></p>
</blockquote>
<p>生活中情绪的及时止损，很有用，停止自我内耗。</p>
<h3 id="分散和对冲">分散和对冲</h3>
<blockquote>
 <p>相关性是一个非常重要的因素。
  <br>
  什么情况下相关性比较低呢？比如，一部分投资在科技行业，另一部分投资到奢侈品行业。科技行业不景气的时候，芯片股票也会跌，但并不影响奢侈品行业，要买包、买珠宝黄金的人还会继续买。专业机构会用严谨的统计学方法来计算相关性，然后再做配置。</p>
</blockquote>
<p>寻找相关性低的资产降低风险。</p>
<blockquote>
 <p>这种市场整体都在波动的情况下，一种常见的应对策略就是「对冲」。
  <br>
  实话实说，没有人能预测会发生什么。但是基于宏观风险的对冲，在投资中持有一部分黄金是没毛病的，这一定是不二选择。
  <br>
  我们用巴菲特来举例，他 2023 年买了很多日本的股票，但同时做空了日元，这样就可以防范日元贬值的风险，这就是一个典型的不同资产的对冲策略。
  <br>
  找相反的东西是控制风险的很好手段。</p>
</blockquote>
<p>对冲策略之前确实没有考虑过。我甚至在近期才知道期权包括做空这种概念，感到十分震惊，仿佛打开了新世界的大门。</p>
<blockquote>
 <p>保险本身就是一种对冲。
  <br>
  但很多人有一个误区，就是把保险当作理财来买，所谓的「理财险」也被推销得很厉害。这是一种有偏差的想法，因为保险是对冲工具，不是奔着理财去的。
  <br>
  如果是为了对冲生活中的意外，那我们就奔着合格的保险去。如果是为了收益，那我们就奔着更专业的投资机构去。
  <br>
  对冲的底层逻辑就是要考虑小概率事件，有没有方法能减少相应的损失。如果我们把生活看成一个投资组合——就像我们说「生活处处是投资」，理念也是类似的。</p>
</blockquote>
<p>生活中的对冲方式：保险。不过要注意需求，真想对冲要选择合适的保险。</p>
<h3 id="止盈">止盈</h3>
<blockquote>
 <p>我们的确可以像投资机构一样，给自己画一道线。这条线怎么画？我们需要有一个参照物，这个参照物就是我们之前讨论过的「长期复合收益率」，它会让我们的参考更加客观。我们之前聊「投资预期和长期主义」的时候讨论过，如果拉长到十年的周期，不同的投资标的，会对应有不同的投资回报率。
  <br>
  当市场极度火热时，我们应该做什么呢？其实是应该止盈，而不是在市场最疯狂的时候依旧继续买入。</p>
</blockquote>
<p>与止损对应，指定合适的止盈目标也是同样重要的选择。合理退出，保证胜率，如何不能够战胜情绪，就设定强制止盈线。</p>
<h3 id="减少路径依赖">减少路径依赖</h3>
<blockquote>
 <p>「路径依赖」是投资中隐藏最深的坑。它不像风险、亏损，能一眼看出。
  <br>
  但是当外界环境发生变化时，各种外部信息、证据都变了，我们原本的「舒适能力圈」可能会阶段性失效，如果我们不及时更新，就会变成那个固执己见的人。</p>
</blockquote>
<p>保持终身学习的能力，对新事物保持好奇心并去接触。不要抵触改变。</p>
<blockquote>
 <p>普通人如何做到：
  <br>
  一个方法是从投资机构的做法里总结出来的，就是刻意找反对意见。我们去找的不是简单的对立观点，而是对立观点背后的证据和逻辑。如果奔着证据去，阅读效率会非常高，一旦发现是在兜售观点而不是证据时，我们都可以直接略过。</p>
</blockquote>
<p>找寻事实而非观点。</p>
<h2 id="番外">番外</h2>
<h3 id="个人养老金">个人养老金</h3>
<blockquote>
 <p>养老金账户必须投到指定的产品范围内，而这些指定的产品大多数都是风险比较低的理财和基金，但低风险不等于零风险，一样有亏损的可能。</p>
</blockquote>
<p>个人养老金的性质</p>
<h3 id="保险">保险</h3>
<blockquote>
 <p>保险分为两个主要类别，一类是保障型保险，另一类是理财型保险。
  <br>
  保障型的保险是指，一旦发生意外，我们能够获得相应的理赔，这是最典型、最传统，也是我们最常接触到的保险。比如常见的疾病类保险，就是可以通过保险理赔去医院看病的花销。
  <br>
  另外一种理财型保险，顾名思义，同时兼顾一部分保障功能和理财功能。比如曾经很热门的「万能险」就是其中一种，在发生人身意外时，这种保险会在一定条件下给予理赔，同时投入的保费也可以用来赚利息。就像投资理财一样，最终本金和利息都会返还给我们。听起来似乎是一个两全其美的事情，也吸引了不少人投资，但是其中踩坑的人也不在少数，包括我自己的家人。
  <br>
  保险的作用毕竟是保障，其次才是理财。</p>
</blockquote>
<p>同上面，保险的分类，需要明确需求与性质。</p>
<blockquote>
 <p>当我们去看一款理财保险产品的时候，真正需要关心的是它给我们保证的最低收益是多少，至于预期收益一定不能太当真。
  <br>
  理财保险的本质，就是超长期的储蓄，用于做低风险的投资。
  <br>
  保险的本质，就是保障我们免受意外风险的冲击。所以当我们考虑保险产品的时候，优先考虑那些保障我们免于疾病或者人身意外伤害的保险，而不是首先追逐那些带有比较高收益目标的理财保险。</p>
</blockquote>
<p>理财型保险需要谨慎，更像是陷阱。</p>
<h3 id="黄金投资">黄金投资</h3>
<blockquote>
 <p>黄金价格的变化周期非常长，远比股票市场的股价周期要长</p>
</blockquote>
<p>这两年金价的上涨或只是特殊形势下的上升趋势。</p>
<h3 id="债券基金">债券基金</h3>
<blockquote>
 <p>债券基金都有封闭期的差异。有的债基是买了一段时间之后才能够赎回，比如它的封闭期可能是一个月、3 个月或 6 个月。
  <br>
  债基底层的资产略有差异。意思就是每支债券基金投资的债券种类不一样。这个数据在哪儿能看到呢？一般在销售这些基金的软件里面都会有「基金持仓」这个栏目，在这里能看到细项。
  <br>
  除了底层资产和封闭期的差异之外，还有一类债券基金，大家一定要非常注意。它其实更像是股票基金，在它的名字里一般都会出现「可转债」三个字。「可转债」就是「可转换债券」的简称。它是一种特殊的债券，在一定的条件下，这些债券可以转化成发行方的股票。这样说你就懂了，它是可以变成股票的，所以它的收益比普通的债券确实高一些，但相应风险也同样会被股票的风险所传导。</p>
</blockquote>
<p>债基和可转债的相关概念。</p>
<blockquote>
 <p>债券的期限越长，价格波动的弹性越大。所以在上涨的时候， 30 年期的国债就会比 5 年期的表现更好。反过来下跌的时候也是这样。
  <br>
  国债的投资风险主要还是利率变化的风险。有一个简单的公式，大家只要知晓就可以了。利率下降，国债价格上涨；反之，它就会下跌。所以，哪怕是国家发行的债券在二级市场交易的时候，也会有价格波动。</p>
</blockquote>
<p>国债波动的逻辑。</p>
<h3 id="量化">量化</h3>
<blockquote>
 <p>量化是在找大样本下面的统计学规律，主观投资是在找小样本下确定性比较高的大机会规律。
  <br>
  因子失效，一种就是刚才说的其实是你挖得不对，这个因子在历史上，也就是某一些时间段或某些市场环境下起效，但未来比如说 6 个月市场环境变了，它就没有那么有效。第二种就是各家可能挖掘到类似的规律，都在用这个因子，这个因子的有效性会逐步变低，最后这个因子就变得不挣钱了。<strong>做量化其实是一件蛮苦的事，永远都要挖一些新的规律，永无止境。</strong>
  <br>
  <strong>量化最大的风险就是历史规律不再有效了。</strong>
  <br>
  我们最终还是要了解净值曲线背后的风险和收益来源，要心中有数，不能盲目只看净值曲线，否则就有可能掉进隐含的风险里了。</p>
</blockquote>
<p>大型量化机构会去从市场和论文中寻找合适的因子进行量化，但因子是有时效性的。虽然自己还没深入研究，但看很多人的经验叙述，A 股中很多逻辑貌似都行不通。</p>
<p>以上为一些简短的画线，回过头看很多内容还是很精彩的。可以在不同的时段多读几遍，有些东西你以为知道，但其实并不如此。以为烂熟于胸不会踩坑，但实际踩了坑也不一定能长记性下次避免。多看多实践，学无止境。</p>
<hr>
<p>喜欢我的文章吗？请不要吝啬自己的思考想法，欢迎在留言区讨论或提出建议。</p>
<ul>
 <li>如果您了解使用 RSS，可以使用 <a href="https://laffitto.xyz/feed.xml">https://laffitto.xyz/feed.xml</a> rss订阅我的网站。</li>
 <li>另外我还通过 <a href="https://memo.laffitto.xyz/">memos詹詹碎言</a> 分享一些简短的生活和思考，可以使用 <a href="https://memo.laffitto.xyz/u/laffitto/rss.xml">https://memo.laffitto.xyz/u/laffitto/rss.xml</a> rss 订阅它。</li>
 <li>如果您使用 Telegram，可以订阅我的个人频道 <a href="https://laffitto.xyz/t.me/laffitto">TG 频道詹詹碎言</a>，里面直接同步了我上面两个部分内容。</li>
 <li>您使用 <a href="https://follow.is/">follow</a>，可以搜索<strong>乱谈府</strong>订阅我的网站，欢迎大家的关注。</li>
</ul>]]></description><guid isPermaLink="false">/archives/beyond-money-note</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250302225932176.webp&amp;size=m" type="image/jpeg" length="456300"/><pubDate>Sun, 2 Mar 2025 14:49:00 GMT</pubDate></item><item><title><![CDATA[基于Obsidian记录回顾系统]]></title><link>https://laffitto.xyz/archives/DailyNoteReview</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E5%9F%BA%E4%BA%8EObsidian%E8%AE%B0%E5%BD%95%E5%9B%9E%E9%A1%BE%E7%B3%BB%E7%BB%9F&amp;url=/archives/DailyNoteReview" width="1" height="1" alt="" style="opacity:0;">
<p>自己看过很多方法论的文章，其中记录每一天的生活，发生的事情与所思所感这件事非常有意义。最直接的一方面你可以依据模糊的检索到当时实际的情景，他们可能是一件事情阐述，一段当时心情的记录。<strong>借助定期回顾也会让你有目标性并系统性的进行反思改进，催进后续的目标制定和习惯的养成</strong>。在过去大概一年时间里，我逐渐使用 Obsidian 构建了这套记录回顾系统，收获颇丰，故分享之，希望共同进步。</p>
<h2 id="记录的契机">记录的契机</h2>
<p>为什么是 Obsidian？自己把它作为主力笔记软件也两年有余了。在接连尝试过为知笔记，印象笔记，但因为后续维护和定价带来的失望后，不会再去考虑使用依赖云端环境的笔记软件作为主力，以前里面的内容记录也因为导出后格式等问题基本烂尾了。我承认 Notion 这类 All in one 的软件非常方便，但是五年，十年后谁也无法承诺这些产品还会存在在这个世界上。Obsidian 作为一个纯本地软件，虽然 md 格式无法优雅的实现某些特定功能（如表格，图片嵌入），但胜在可以自主把控文件，配合 Remotely Save 等同步插件，同样可以做到在多端同步的同时完全把控自己的数据。并且单单每日记录加上周回顾这些内容，一年就大概有 420 个左右的文件，纯 md 格式也易于整合管理。</p>
<p>在大概去年 4 月的时候，我偶然刷到一个使用每日笔记 obsidian 记录生活的视频。本身 obsidian 这个软件最开始推出的时候，每日笔记就是作为一个官方模块集成在应用中的。但看了他们的操作思路后，才让我明白了这个模块真正的意义。说实话我对每日记录并不陌生，从很久之前我是使用 journey（一个日记 app）专门做<a href="https://laffitto.xyz/archives/journey">晨间日记</a>。每天早上起来按照一个模板，回顾昨天的事情。但是后续因为 app 模板功能还要订阅，外加记录内容和其他内容有所割裂，频率也逐渐变少了。</p>
<p>由此为契机，在吸取多方的经验和自己生活的魔改之后，我重新基于 obsidian 构建了一套记录系统，并不断改进达到目前的状态。系统依赖于 Calendar，Periodic Notes，Linter，Dataview 和 Templater 插件。在开始熟悉的时候可能需要折腾适应一下，但后面基本上是一劳永逸。记录分为三个大块 DailyNote，WeeklyReview 和 MonthlyReview，以下我逐一介绍，用作抛砖引玉。</p>
<h3 id="dailynote">DailyNote</h3>
<p>顾名思义，该模块记录每天的日常。通过模板创建后，会自动显示今天的日期和昨天明天每日笔记的短链接。笔记的正式内容分为三个部分。
 <br>
 第一部分为 Daily Questions，即每日的自我问答。这里主要是起到每日日记的作用。<strong>我会根据模板记录当日发生的事情，并记录回答自己这些问题。</strong>
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203174633368.png&amp;size=m" alt="image.png"></p>
<p>第二部分为 Notes。这里主要需要是记录下来每天看到的一些有趣内容或项目，它们通常可能会十分短小，单独记录成一篇笔记又会过于零散。但是你可能会在某个时候回想起它们，这里时候借助搜索功能就是快速的调用。例如如下：
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203174838384.png&amp;size=m" alt="image.png"></p>
<p>第三部分为 Files Overview，是基于 obsidian 所有文件的一个筛选。它通过 dataview 自动构建，主要向我展示每天新建的笔记，每天修改的笔记和往年今日的笔记。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203175004546.png&amp;size=m" alt="image.png"></p>
<p>在新一天开始时，点击日历图表的对应日子会自动创建当日日记。首先回顾一下昨晚发生了什么，通常是前一天记录后发生的事情和夜间睡眠的情况，然后正常开始崭新的一天。中途看见了一些有趣的文章或事情，可以摘录在 Notes 部分下面。晚上结束后再把深入思考的东西填充一下。这里可以事无巨细，想写什么写什么。</p>
<h3 id="weeklyreview">WeeklyReview</h3>
<p>该部分为每周的回顾，一般我会当周的周日晚上进行。通过模板创建后会显示上周、本月、下周的短链接。笔记的正式内容同样分为三个部分。
 <br>
 第一部分为周计划。这里为双周为单位制定，<strong>这两周内的关键目标是什么，同时依据这个目标制定合适的任务推进。</strong>
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203175045195.png&amp;size=m" alt="image.png"></p>
<p>第二部分为本周回顾。借助 dataview 会自动将该周的 DailyNote 进行汇总，方便我们回顾一周的内容和反思。并回答下面的问题。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203175114114.png&amp;size=m" alt="image.png"></p>
<p>第三部分为本周笔记。同样使用 dataview自动构建汇总，以周为单位展示该周新建和修改的笔记。</p>
<p>在新一周的开始时, 点击日历图标的对应周数会根据模板自动创建。在回顾当周发生的事情同时，总结一下该周的情况，并制定下周的目标。</p>
<h3 id="monthlyreview">MonthlyReview</h3>
<p>该部分为每月的回顾总览，在当月特定的时间点创建都可以。通过模板创建后会显示上月和下月的短链接。目前每月回顾较简单，包含两个部分。
 <br>
 第一部分为月计划。这里以双月为单位制定，<strong>这两个月的关键目标是什么</strong>。这里制定的计划要为后续的周计划和每日任务搭建好基础。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203175207659.png&amp;size=m" alt="image.png"></p>
<p>第二部分为本月回顾。仅汇总了每周周回顾，当月的新建和修改的笔记。由于每周会进行回顾，故没有进行每月的问题提问。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203175241508.png&amp;size=m" alt="image.png"></p>
<p>在新月份开始时，点击日历图标对应月份会总动创建笔记。更多时时候时给一个目标导向和查询的作用。不太经常在此记录。</p>
<p>有些人可能会疑问，记录和回顾目标设定都会涉及任务处理，但在这里没有体现。我只能说确实是的，虽然 obsidian 可以完成这件事情，但是依赖其他插件会显得过于复杂了，我是另外一个软件滴答清单去实现任务的制定。正所谓术业有专攻，后面会再出文章展示滴答清单的系统，两个部分合二为一才是我目前完整的记录回顾系统。</p>
<h2 id="模板配置展示">模板配置展示</h2>
<p>如果你喜欢我的系统，有所启发且想自己尝试，这里我会把上述内容用到的插件配置和三个模板文件在这里分享给大家。</p>
<h3 id="templater">Templater</h3>
<p><a href="obsidian://show-plugin?id=templater-obsidian">Templater</a> 插件用于直接调用模板创建笔记。安装后需要注意设置 <code>Template folder location</code> 为模板文件夹的位置，另外把 <code>Trigger Templater on new file creation</code> 选项打开。</p>
<h3 id="dataview">Dataview</h3>
<p><a href="obsidian://show-plugin?id=dataview">Dataview</a> 插件主要是可以方便以类型表格的形式展示数据，安装后即可，无需特别调整。</p>
<h3 id="linter">Linter</h3>
<p><a href="obsidian://show-plugin?id=obsidian-linter">Linter</a> 插件主要可以对文章进行一些格式化的操作。其功能很强大，我们主要是用来规范特定的字段设定文章的创建和修改时间，防止在各种设备同步后因为时间不统一导致的显示不一致问题。
 <br>
 主要设置如下：将日期相关设置确定下来，创建日期键名和修改日期键名要注意，不然后期使用 dataview 判断时间段会出错。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203172910247.png&amp;size=m" alt="image.png"></p>
<h3 id="calendar">Calendar</h3>
<p>Calendar 插件已经很久没更新了，但是我也没找到其他趁手合适的替代品，这里建议去 github 上下载它的 <a href="https://github.com/liamcain/obsidian-calendar-plugin/releases/tag/2.0.0-beta.2">2.0.0beta</a> 版本，需要手动进行安装。其他设置无需改动。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203220732844.png&amp;size=m" alt="image.png"></p>
<h3 id="periodic-notes">Periodic Notes</h3>
<p><a href="obsidian://show-plugin?id=periodic-notes">Periodic Notes</a> 插件用于基于设定模板的格式直接创建每日，每周，每月笔记。
 <br>
 我的 Dailynote 设置如下。Format 为 YYYY/MM-MMMM/YYYY-MM-DD-dddd
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203173209689.png&amp;size=m" alt="image.png">
 <br>
 这样每次新建笔记位于 0-Daily_Note 文件夹下, 后续以年/月份/具体日期命名。</p>
<p>WeeklyNote 设置如下：
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203173430427.png&amp;size=m" alt="image.png"></p>
<p>MonthlyNote 设置如下：
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203173532796.png&amp;size=m" alt="image.png"></p>
<p>每周笔记以年份/Periodic/W 周数命名，每月笔记以年份/Periodic/M 月份命名。</p>
<p>如下为文件格式展示
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203174500017.png&amp;size=m" alt="image.png"></p>
<h2 id="模板文件">模板文件</h2>
<p>在选定的模板文件下下新增模板，设定模板文件时候需要打开 md 文件为源码模式，注意各种缩进。中途一些时间模板和 dataview 的语句修改可以直接询问 AI，做出合适自己模板。</p>
<h3 id="dailynote-1">DailyNote</h3>
<pre><code class="hljs language-text">---
createDate: &lt;% tp.file.creation_date("YYYY-MM-DD HH:mm") %&gt;
modifyDate: &lt;% tp.file.last_modified_date("YYYY-MM-DD HH:mm") %&gt;
tags:
  - DailyNote
---

# &lt;% moment(tp.file.title,'YYYY-MM-DD').format("dddd, MMMM DD, YYYY") %&gt;

&lt;&lt; [[0-Daily_Note/&lt;% tp.date.now("YYYY", -1) %&gt;/&lt;% tp.date.now("MM-MMMM", -1) %&gt;/&lt;% tp.date.now("YYYY-MM-DD-dddd", -1) %&gt;|Yesterday]] | [[0-Daily_Note/&lt;% tp.date.now("YYYY", 1) %&gt;/&lt;% tp.date.now("MM-MMMM", 1) %&gt;/&lt;% tp.date.now("YYYY-MM-DD-dddd", 1) %&gt;|Tomorrow]] &gt;&gt;

---
## 📅 Daily Questions
### 🌜 昨晚发生了什么
- 

### 🙌 深入思考
#### 今日回顾
&gt; 今天发生了什么？完成了什么？值得感激的事情是什么？
- 

####  面对挑战 
&gt; 今天我遇到的挑战是什么？我是如何应对的？
- 

#### 情绪反思 
&gt; 今天我经历的主要情绪是什么？这些情绪背后的原因是什么？
- 

#### 人际互动
&gt; 今天的人际互动中，有哪些是积极的？有哪些是我希望改进的？
- 

---
## 📝 Notes
- &lt;% tp.file.cursor() %&gt;





---

## Files Overview

&gt; [!example]+ 今日创建
&gt; ```dataview
&gt; table without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; createDate as "Created"
&gt; FROM ""
&gt; where 
&gt; 	date(split(createDate," ")[0]) = date("&lt;%tp.date.now("YYYY-MM-DD")%&gt;") 
&gt; 	AND file.path != this.file.path
&gt; sort createDate desc
&gt; ```

&gt; [!example]+ 今日修改
&gt; ```dataview
&gt; table without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; modifyDate as "Last Modified"
&gt; FROM ""
&gt; where 
&gt; 	date(split(modifyDate," ")[0]) = date("&lt;%tp.date.now("YYYY-MM-DD")%&gt;") 
&gt; 	AND date(split(createDate," ")[0]) != date("&lt;%tp.date.now("YYYY-MM-DD")%&gt;") 
&gt; 	AND file.path != this.file.path
&gt; sort modifyDate desc
&gt; ```

&gt; [!tldr]+ 往年今日
&gt; ```dataview
&gt; table without id
&gt; file.link as Note,
&gt; createDate as "Created"
&gt; FROM "0-Daily_Note"
&gt; where 
&gt; 	dateformat(date(split(createDate," ")[0]),"MM-dd") = dateformat(date("&lt;%tp.date.now("YYYY-MM-DD")%&gt;"),"MM-dd")
&gt; 	AND file.path != this.file.path
&gt; sort createDate desc
&gt; ```
</code></pre>
<h3 id="weeklyreview-1">WeeklyReview</h3>
<pre><code class="hljs language-text">---
createDate: &lt;% tp.file.creation_date("YYYY-MM-DD HH:mm") %&gt;
tags:
  - WeeklyReview
---
&lt;&lt; [[0-Daily_Note/&lt;% tp.date.now("YYYY", -7)%&gt;/Periodic/W&lt;% tp.date.now("WW", -6) %&gt;|LastWeek:W&lt;% tp.date.now("WW", -6) %&gt;]] | [[0-Daily_Note/&lt;% tp.date.now("YYYY") %&gt;/Periodic/M&lt;% tp.date.now("MM") %&gt;|MonthlyReview:M&lt;% tp.date.now("MM") %&gt;]] | [[0-Daily_Note/&lt;% tp.date.now("YYYY", +7) %&gt;/Periodic/W&lt;% tp.date.now("WW", +8)%&gt;|NextWeek:W&lt;% tp.date.now("WW", +8) %&gt;]] &gt;&gt;

---

# 周计划（双周为单位）
- [ ] 



---

# 本周回顾

&gt; [!info]+ DailyNote 回顾
&gt; ```dataview  
&gt; TABLE without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; createDate as "Created"
&gt; FROM "0-Daily_Note"
&gt; WHERE 
&gt; 	contains(tags, "DailyNote") 
&gt; 	AND date(split(createDate," ")[0]) &lt;= date({{date:YYYY-MM-DD}}) 
&gt; 	AND date(split(createDate," ")[0]) &gt;= date({{date:YYYY-MM-DD}}) - dur(6days)
&gt; SORT createDate ASC
&gt; ```

## 本周完成了什么事情？学习到了什么？
- 

## 本周出现了哪些问题？原因是什么？
- 

## 我应该开始做哪些事情
- 

## 我应该停止做哪些事情
- 

---

# 本周笔记

&gt; [!example]+ 本周制作笔记
&gt; ```dataview  
&gt; TABLE without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; createDate as "Created"
&gt; FROM ""
&gt; WHERE 
&gt; 	!contains(tags, "DailyNote") 
&gt; 	AND !contains(tags, "WeeklyReview") 
&gt; 	AND date(split(createDate," ")[0]) &lt;= date({{date:YYYY-MM-DD}}) 
&gt; 	AND date(split(createDate," ")[0]) &gt;= date({{date:YYYY-MM-DD}}) - dur(6days)
&gt; SORT createDate ASC
&gt; ```

&gt; [!example]+ 本周修改笔记
&gt; ```dataview  
&gt; TABLE without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; modifyDate as "Modified",
&gt; createDate as "Created"
&gt; FROM ""
&gt; WHERE 
&gt; 	date(split(modifyDate," ")[0]) &lt;= date({{date:YYYY-MM-DD}}) AND 
&gt; 	date(split(modifyDate," ")[0]) &gt;= date({{date:YYYY-MM-DD}}) - dur(6days) AND 
&gt; 	date(split(createDate," ")[0]) &lt; date({{date:YYYY-MM-DD}}) - dur(6days)
&gt; SORT modifyDate ASC
&gt; ```
</code></pre>
<h3 id="monthlyreview-1">MonthlyReview</h3>
<pre><code class="hljs language-text">---
createDate: &lt;% tp.file.creation_date("YYYY-MM-DD HH:mm") %&gt;
tags:
  - MonthlyReview
---
&lt;&lt; [[0-Daily_Note/&lt;% tp.date.now("YYYY", "P-1M") %&gt;/Periodic/M&lt;% tp.date.now("MM", "P-1M") %&gt;|LastMonth:M&lt;% tp.date.now("MM", "P-1M") %&gt;]] | [[0-Daily_Note/&lt;% tp.date.now("YYYY", "P+1M") %&gt;/Periodic/M&lt;% tp.date.now("MM", "P+1M") %&gt;|NextMonth:M&lt;% tp.date.now("MM", "P+1M") %&gt;]] &gt;&gt;

---

# 月度计划KR（双月为单位）






# 本月回顾

&gt; [!info]+ WeeklyNote 回顾
&gt; ```dataview  
&gt; TABLE without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; createDate as "Created"
&gt; FROM "0-Daily_Note"
&gt; WHERE 
&gt; 	contains(tags, "WeeklyReview") 
&gt; 	AND date(split(createDate," ")[0]) &gt;= date({{date:YYYY-MM-DD}}) 
&gt; 	AND date(split(createDate," ")[0]) &lt;= date({{date:YYYY-MM-DD}}) + dur(1months)
&gt; SORT createDate ASC
&gt; ```

&gt; [!example]+ 本月制作笔记
&gt; ```dataview  
&gt; TABLE without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; createDate as "Created"
&gt; FROM ""
&gt; WHERE 
&gt; 	!contains(tags, "DailyNote") 
&gt; 	AND !contains(tags, "WeeklyReview") 
&gt; 	AND !contains(tags, "MonthlyReview") 
&gt; 	AND date(split(createDate," ")[0]) &gt;= date({{date:YYYY-MM-DD}}) 
&gt; 	AND date(split(createDate," ")[0]) &lt;= date({{date:YYYY-MM-DD}}) + dur(1months)
&gt; SORT createDate ASC
&gt; ```

&gt; [!example]+ 本月修改笔记
&gt; ```dataview  
&gt; TABLE without id
&gt; file.link as Note,
&gt; file.folder as Folder,
&gt; modifyDate as "Modified",
&gt; createDate as "Created"
&gt; FROM ""
&gt; WHERE 
&gt; 	date(split(modifyDate," ")[0]) &gt;= date({{date:YYYY-MM-DD}}) AND 
&gt; 	date(split(modifyDate," ")[0]) &lt;= date({{date:YYYY-MM-DD}}) + dur(1months) AND 
&gt; 	date(split(createDate," ")[0]) &lt; date({{date:YYYY-MM-DD}})
&gt; SORT modifyDate ASC
&gt; ```
</code></pre>
<h2 id="结语">结语</h2>
<p>以上是我目前的基于 Obsidian 的记录回顾系统。我感觉最妙的一点在于他可以把我每天的日常和情绪等各种事项都记录下来，并进行定期回顾。你可以说记录的是流水账，<strong>但要相信习惯养成后时间的力量</strong>。同时这套系统完全是构建在我的笔记系统之上的，极大的减少了记录的割裂感，后续可以通过 AI 插件实现全文本库的向量构建，达成更高层次的知识库。</p>
<p>缺点可能就是插入图片比较麻烦，因为我喜欢用图床而非本地存储。不过这种情况更多是分享，我会把他记录在我的日常唠嗑<a href="https://memo.laffitto.xyz/">詹詹碎言</a> 中，同步到 <a href="https://laffitto.xyz/t.me/laffitto">TG 频道</a>里面，欢迎大家订阅关注。</p>
<p>每个人的生活都不一样，系统的构建也会随着生活不断变化改进。虽然这里我自认为呈现了一个较为完备的方案，但是更多的细节和构筑都需要依据每个人的情况去自适应改变。在日常不断的使用中，你会发现系统问题，可能你有更多的记录需求，可能某项完全是冗余，这时候大胆的删掉并改变吧。不断的调整改变找到合适自己的就是最好的。</p>
<hr>
<p>喜欢我的文章吗？请不要吝啬自己的思考想法，欢迎在留言区讨论或提出建议。</p>
<ul>
 <li>如果您了解使用 RSS，可以使用 <a href="https://laffitto.xyz/feed.xml">https://laffitto.xyz/feed.xml</a> rss订阅我的网站。</li>
 <li>另外我还通过 <a href="https://memo.laffitto.xyz/">memos詹詹碎言</a> 分享一些简短的生活和思考，可以使用 <a href="https://memo.laffitto.xyz/u/laffitto/rss.xml">https://memo.laffitto.xyz/u/laffitto/rss.xml</a> rss 订阅它。</li>
 <li>如果您使用 Telegram，可以订阅我的个人频道 <a href="https://laffitto.xyz/t.me/laffitto">TG 频道詹詹碎言</a>，里面直接同步了我上面两个部分内容。</li>
 <li>您使用 <a href="https://follow.is/">follow</a>，可以搜索<strong>乱谈府</strong>订阅我的网站，欢迎大家的关注。</li>
</ul>]]></description><guid isPermaLink="false">/archives/DailyNoteReview</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F20250203224754530.png&amp;size=m" type="image/jpeg" length="43824"/><category>默认分类</category><pubDate>Mon, 3 Feb 2025 14:42:00 GMT</pubDate></item><item><title><![CDATA[2024总结]]></title><link>https://laffitto.xyz/archives/2024review</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=2024%E6%80%BB%E7%BB%93&amp;url=/archives/2024review" width="1" height="1" alt="" style="opacity:0;">
<p>如果说2024用一个词去总结，我只能用这个稍显遗憾的词去表达：停滞。 不是说没有任何的进展，只是从广义上是没有什么物质的收获。</p>
<h2 id="遗憾">遗憾</h2>
<p>这两年吃了一个大亏，有的人我恨不得指着鼻子破口大骂。但同时我不得不感叹，多亏了这些，真的给我人生好好的上了一课。下面是我领悟出的道理，虽然听起来只是一些比较正常的建议，但是你要小心<strong>事物是变化的，初期展现的和后面发展呈现的可能不是一个东西，随时保持观察，评估利弊</strong>。</p>
<h3 id="要正视并小心那些处理各种人际关系的人">要正视并小心那些处理各种人际关系的人</h3>
<p>这些人在外面表现的很厉害，仿佛有各种头衔，跟你讲起东西来是来夸夸其谈，好像什么东西都知道一点。「我有个什么什么，我知道个什么什么，我跟那个谁什么什么」。你可能一开始会被糊弄到，<strong>但保持平常心看待就好</strong>，因为时间会让你看清对面究竟是否有能耐。而且对面表现其实和你是无关的，本质上不过是让自己装起来更厉害而已。地位不过是祖上传下来的，关系也只是位于那里而自然而然的接触到。你只需要保证好自己的教养平常面对就好，不要被影响。</p>
<h3 id="要小心满嘴答应的人和他们的承诺">要小心满嘴答应的人和他们的承诺</h3>
<p>满嘴答应只是敷衍，这些人通常办不成他们想做的事且眼高手低。事物的发展是复杂的，很多都需要评估并推进才能有结果，如果别人给了你一些条件但需要等待。<strong>请在自己内容设定死线，最多两个月</strong>。事件推动不了无疑是受到了阻碍，即便回复你原因，但只要你产生一丁点的怀疑那就可以表明就是拖延敷衍，及时止损收手。这些人说的话听一半可以了。要相信自己而不是寄托于他人。</p>
<h3 id="要慎重选择合作伙伴谨慎接受好意并评估">要慎重选择合作伙伴，谨慎接受好意并评估</h3>
<p>在现实中如果一个人对你表示好意，首先以坏事态度去评估：他是有目的的所以才接近我，他能给我什么利益，我能给他什么利益。即便达成了利益关系，<strong>请签订明确的合同</strong>。不要去用道德评估这些人，人不要脸，天下无敌。如果没有履行职责或内容，同上设定死线，及时止损。只需要一点点的试探就能知道对方靠不靠谱，不靠谱赶紧结束合作关系，不要有任何牵连。</p>
<h2 id="收获">收获</h2>
<p>不过这一年也是有一些收获的，人生总是需要去不断去探索。下面我列举一些个人觉得有意义的成就：</p>
<h3 id="daliynote-记录">DaliyNote 记录</h3>
<p>使用obsidian去进行模块化的每日记录，并进行每周回顾。我相信记录是有意义的，简单的记录一天干了什么，看了什么，有什么想法，能够帮我进行回忆和改进。虽然看起来短期影响不大，但后续的日积月累应该会引发质变。从去年约二季度开始坚持，已经成为我的习惯。同时整个流程我也在不断优化，看似很折腾，但是配置一次就基本能一直用，还是比较轻松。后面会专门出一篇文章去介绍详细的内容。</p>
<h3 id="量化交易">量化交易</h3>
<p>构建自己的量化投资系统。我从来没有奢求自己能够通过完全通过工作去实现财富自由，也还没有足够的眼界和勇气去进行创业，但我相信投资可以钱生钱。之前基本都是跟着投，也没有太多的思考和感悟。现在开始让自己用代码去进行一些量化和进一步的主动学习。虽然还是个新手，但我已将其列入需要终身学习的领域，慢慢积攒经验吧。</p>
<h3 id="跑步锻炼">跑步锻炼</h3>
<p>从上次体验感觉有轻微脂肪肝开始，大为震惊，决定要好好锻炼身体。在控制饮食的基础上开始跑步，中间一点一点加强，目前是每次跑5公里。2024 年总跑量有 535 千米，不过最后会多一公里恢复慢走，手表也记录进去了，真实跑量应该是 400 多千米。但是我也发现自己的心肺功能是真的差，跑了大概快大半年了，配速也才到 6 分半，再一快心率直接 170 往上了，希望能把这个习惯一直保持，跑步的时候很容易进入心流状态，保持身体的活性。</p>
<h2 id="具体实现">具体实现</h2>
<p>自己经常会把发生的一些事情记录下来，但是回顾下来还是不够。</p>
<h3 id="写作输出方面">写作输出方面</h3>
<p>2024 年<a href="https://laffitto.xyz/">博客长文</a>输出仅仅 9 篇，<a href="https://memo.laffitto.xyz/">memos短篇</a> 输出 54 项。个人觉得还是太少了，长文写作还是有点压力，自己还是需要再优化简化这个流程。短篇分享也需要增多，下一年争取做到更多的输出。</p>
<h3 id="读书输入方面">读书输入方面</h3>
<p>仅仅读了三本书，而且还没有整理出读书笔记，有点失败，倒是看了不少漫画。新年读书这方面还是需要多加强，因为之前看到一个说法觉得很有道理，大概是：你读好的短博文，那可能是作者花费了几天的心血所创作的，但读一本好书，可能是作者花费了几年甚至毕生精力创作的。所以拥抱长内容吧，那些破短视频也尽量少刷。</p>
<h3 id="旅行方面">旅行方面</h3>
<p>芜湖，香港，苏州，常州，大部分都是陪伴小徐的工作，忙里偷闲个一两天，但是也算是走了走。新年也希望能够做到行万里路。</p>
<h3 id="交际方面">交际方面</h3>
<p>和朋友聚会 6 次，和家人聚会 9 次，和小徐约会 34 次，中途可能有漏记但大概是这样。新年希望继续多多增加社交，今年把结婚的各种前置事项安排好，切勿辜负对方。</p>
<h3 id="其他方面">其他方面</h3>
<p>去年也没添啥东西，3 月时候把三星 S22U 换成了 Fold5，折叠屏使用感极佳，用了就回不去。12 月继承了小徐的 iphone14，替代了之前的备用机 iphoneX。这两个电子设备带给我极好的使用体验，安卓折腾苹果养老，相辅相成。游戏也玩了一些，比较喜欢的单机有黑神话悟空，动物井和小丑牌。不过最喜欢的还是游戏王大师决斗，打牌真的太快乐了。</p>
<p>2024 已然度过，2025 开始，但昨天和今天没有什么两样，后悔都已是过去，把握当下，靠自己强化自己的能力与视野才是王道，加油吧少年！2024 的最后最后，跨年听了五月天的线上演唱会，发现我还是很喜欢他们。他们的专辑创作歌曲还是令人动容，会给我一种在低谷时依旧想向前的力量，<strong>逐渐变得愈发平和的面对每一天，内生出一股坚毅的力量，面对这个世界。</strong></p>]]></description><guid isPermaLink="false">/archives/2024review</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202501011820363.jpg&amp;size=m" type="image/jpeg" length="118386"/><category>默认分类</category><pubDate>Wed, 1 Jan 2025 13:01:07 GMT</pubDate></item><item><title><![CDATA[网格交易]]></title><link>https://laffitto.xyz/archives/StrategyGridv1</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E7%BD%91%E6%A0%BC%E4%BA%A4%E6%98%93&amp;url=/archives/StrategyGridv1" width="1" height="1" alt="" style="opacity:0;">
<p>本文所有内容均为个人见解。仅表示自己在当前认知情况下自认为正确的观点所作出的行为，如有异议还请谅解与提出交流。头图来自 <a href="https://invest101.com.hk/grid-trading">https://invest101.com.hk/grid-trading</a></p>
<h2 id="心路历程">心路历程</h2>
<p>自己也算是投资市场多少年的韭菜了，虽然玩的都是小钱，最后统计下来还是亏多赢少。以前读了点小书，看了点小文章，立马自信心爆棚，觉得其他交易者都是定力不行，自己不会被市场的情绪左右。交易过程天天说定投，相信时间的力量，投到后面资金不够，也不知道何时止盈止损，看着赚了以为自己牛逼，看着跌了就闭嘴装死。当然我这里不是指一些会发出信号的主动型基金，而是纯粹自己自我感知良好的操作，现在回首看过去，没有明确的系统与目的，进入投资市场无异于赌博。</p>
<p>近几个月决定自己做一点量化的尝试，毕竟一个东西门槛越高，越少的人会去尝试。赛道越少，竞争越少。虽然大的机构也会有专门的量化投资部门，但毕竟会顾虑到资金和面向市场等多方面因素，和个人投资者要考虑的东西完全不一样。况且人家也不会分享给你他们的策略。投资要趁早，既然自己有一定的能力与基础，早点研究就当是玩玩也是有趣的。</p>
<p>量化过程，简化来说大体可以分为如下几部分：数据收集，策略构建和策略回测。数据收集就是选择合适的平台，能够持续稳定准确的给你提供想要研究市场的数据。策略构建是选择合适的策略或是通过机器学习/深度学习训练得到策略。不同的策略同样有着众多的超参数，构建一个合适的模型同样需要考虑其准确性和泛化性。回测过程考虑最终的指标，可能是夏普比率，又可能仅是利润率，具体情况具体分析。本质上和众多科研流程类似，有科学研究内味了。</p>
<p>对于一个策略来说，核心关键点就是信号（何时交易）和数量。在什么时间买入或卖出，交易的过程具体数量是多少。一步步拆解下来就是：构建好自己的框架，模拟这个过程，选择好合适的品种，同时保证准确性和泛化性。</p>
<p>有些人相信价值投资，进行基本面的研究，但是我感觉自己的认知和眼光还是不够，况且我也拿不到单一公司真正内部的资料，又何来了解一说。现阶段不如交给机器去选择，少一点自己的主观能动性吧。</p>
<h2 id="网格交易策略">网格交易策略</h2>
<p>经过一段时间的探索，掌握了一些皮毛，目前仍然有许多知识盲点与专业性的东西需要慢慢领会。这里先从简单的入手复现一个以前使用过的网格交易策略。</p>
<p>网格交易主要是在震荡环境中非常有效的策略。随着设定合适的买入卖出网格区间，在区间中做到低价买入，高价卖出，赚一点点中间的波动价格差。</p>
<p>在进行网格交易中有以下关键的点：</p>
<ol>
 <li>选定合适的品种。例如指数类 ETF（沪深 300，中证 500，兴全趋势混合，创业板指），财务稳定的（银行，保险），可以长期持有的股票等等。</li>
 <li>选定好合适的价格区间。等差区间，等比区间，或是其他更多的策略。</li>
 <li>做好压力测试，提前明确定好上下区间进行止盈止损。以及超出区间后如何进行后续操作。</li>
</ol>
<h2 id="策略编写">策略编写</h2>
<p>这里选择之前实战中使用过的万马股份 (SZSE:002276) 作为研究对象。后续会对更多的品种进行测试。</p>
<p>回测框架经过多方面对比，我选择了现在在持续维护且运行效率较高的 vectorbt 的付费版本 <a href="https://vectorbt.pro/">VectorBT PRO</a>。当然也可以选择一些免费的框架如 <a href="https://github.com/vnpy/vnpy">vnpy</a>。</p>
<p>如下代码在jupyter notebook中运行，暂不考虑优化效率和面向对象编程，仅初步展示和参考。
 <br>
 导入相关库</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">import</span> vectorbtpro <span class="hljs-keyword">as</span> vbt  
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np  
<span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
</code></pre>
<p>从 tradingview 抓取相关数据，以天为单位的K线</p>
<pre><code class="hljs language-python">list_name = vbt.TVData.list_symbols(symbol_pattern=<span class="hljs-string">"002276"</span>)  
data = vbt.TVData.pull(<span class="hljs-string">"SZSE:002276"</span>)
data.stats()

输出
Start Index            <span class="hljs-number">2009</span>-07-<span class="hljs-number">10</span> 01:<span class="hljs-number">30</span>:<span class="hljs-number">00</span>+<span class="hljs-number">00</span>:<span class="hljs-number">00</span>
End Index              <span class="hljs-number">2024</span>-<span class="hljs-number">11</span>-<span class="hljs-number">13</span> 01:<span class="hljs-number">30</span>:<span class="hljs-number">00</span>+<span class="hljs-number">00</span>:<span class="hljs-number">00</span>
Total Duration                <span class="hljs-number">3623</span> days <span class="hljs-number">00</span>:<span class="hljs-number">00</span>:<span class="hljs-number">00</span>
Total Symbols                                  <span class="hljs-number">1</span>
Null Counts: 002276                            <span class="hljs-number">0</span>
Name: agg_stats, dtype: <span class="hljs-built_in">object</span>
</code></pre>
<p>选取特定时间段并可视化K线</p>
<pre><code class="hljs language-python">close = data.get(<span class="hljs-string">'Close'</span>)
data=data.loc[<span class="hljs-string">'2018-01-01'</span>:]
data.plot().show()
</code></pre>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202411281614777.png&amp;size=m" alt="image.png"></p>
<p>定义一个等差网格区间</p>
<pre><code class="hljs language-python"><span class="hljs-comment"># 等差计算 输入上下区间，目标投入金额，计划网格数 得到每格买入价格间隔，每格买入数量  </span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">arithmetic_grid</span>(<span class="hljs-params">price_low, price_high, initial_fund, grid_num</span>):  
    <span class="hljs-comment"># 计算每格价格的差价  </span>
    grid_price_interval = <span class="hljs-built_in">round</span>((price_high - price_low) / (grid_num-<span class="hljs-number">1</span>),<span class="hljs-number">4</span>)  
    <span class="hljs-comment"># 等差数列计算公式  </span>
    total_multiplier = grid_num * (price_low + price_high) / <span class="hljs-number">2</span>  
    <span class="hljs-comment"># 计算每格的交易数量，使得总和符合初始资金  </span>
    share_number = <span class="hljs-built_in">int</span>(initial_fund / total_multiplier)  
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f"每格交易价格间隔: <span class="hljs-subst">{grid_price_interval}</span>，每格交易数量: <span class="hljs-subst">{share_number}</span>"</span>)  
    <span class="hljs-comment"># 交易间隔  </span>
    grid_interval = [<span class="hljs-built_in">round</span>(price_low + i * grid_price_interval, <span class="hljs-number">4</span>) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(grid_num)]  
    <span class="hljs-keyword">return</span> grid_price_interval,share_number,grid_interval
</code></pre>
<p>设定网格最低价价为 6，最高价格 12，总计划投入金额 10000，网格数量 10</p>
<pre><code class="hljs language-python">grid_price, grid_amount, grid_interval = arithmetic_grid(price_low=<span class="hljs-number">6</span>, price_high=<span class="hljs-number">12</span>, initial_fund=<span class="hljs-number">10000</span>, grid_num=<span class="hljs-number">10</span>)  
grid_interval

输出：
每格交易价格间隔: <span class="hljs-number">0.6667</span>，每格交易数量: <span class="hljs-number">111</span>
[<span class="hljs-number">6.0</span>,
 <span class="hljs-number">6.6667</span>,
 <span class="hljs-number">7.3334</span>,
 <span class="hljs-number">8.0001</span>,
 <span class="hljs-number">8.6668</span>,
 <span class="hljs-number">9.3335</span>,
 <span class="hljs-number">10.0002</span>,
 <span class="hljs-number">10.6669</span>,
 <span class="hljs-number">11.3336</span>,
 <span class="hljs-number">12.0003</span>]

</code></pre>
<h4 id="gridv1">Gridv1</h4>
<p>定义最基本简单的网格交易策略：采用每次交易相同数额，输出 direction 表示买卖信号，输出 grid_interval 表示网格间隔，仅用于可视化。</p>
<pre><code class="hljs language-python"><span class="hljs-comment">## 针对股票买入特定份数  </span>
<span class="hljs-comment">## 每一次买入卖出都会重置基准单位  </span>
  
<span class="hljs-comment"># 策略在执行之前先买入一定比例，后续使用网格进行交易测算。如果基金呈现上涨趋势，建仓比例较大可以吃到更多利润  </span>
<span class="hljs-comment"># init_position 初始建仓份数  </span>
<span class="hljs-comment"># init_price 建仓时价格  </span>
<span class="hljs-comment"># position_size 已建仓的金额  </span>
<span class="hljs-comment"># remain_cash 用于执行网格的金额  </span>
<span class="hljs-comment"># units 持有的仓位  </span>
<span class="hljs-comment"># base_unit_price 基准买入价格  </span>
<span class="hljs-comment"># today_unit_price 当日价格  </span>
  
<span class="hljs-keyword">def</span> <span class="hljs-title function_">stock_grid_line_v1</span>(<span class="hljs-params">close, remain_cash, init_position,price_low=<span class="hljs-number">6</span>, price_high=<span class="hljs-number">12</span></span>):  
      
    init_price = close.iloc[<span class="hljs-number">0</span>]  
    units = init_position    
      
    base_unit_price = close.iloc[<span class="hljs-number">0</span>]  
    direction = pd.Series(np.full(data.shape[<span class="hljs-number">0</span>], <span class="hljs-number">0</span>), index=data.index)  
    <span class="hljs-comment"># size = pd.Series(np.full(data.shape[0], 0), index=data.index)  </span>
    <span class="hljs-comment"># 计算网格大小和每格交易数量，采用等差方式  </span>
    grid_price, grid_amount,grid_interval = arithmetic_grid(price_low=price_low, price_high=price_high, initial_fund=remain_cash, grid_num=<span class="hljs-number">10</span>)  
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f"初始买入价格<span class="hljs-subst">{init_price}</span>"</span>)  
      
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, close.shape[<span class="hljs-number">0</span>]):  
        today_unit_price = close.iloc[i]  
          
        <span class="hljs-comment"># 超出交易区间不做交易  </span>
        <span class="hljs-keyword">if</span> today_unit_price&lt;price_low <span class="hljs-keyword">or</span> today_unit_price &gt; price_high:  
            <span class="hljs-keyword">continue</span>  
        <span class="hljs-comment">## sold operation  </span>
        <span class="hljs-comment"># 当日价格高于网格价，且手里有持仓有剩余  </span>
        <span class="hljs-keyword">if</span> today_unit_price &gt;= base_unit_price+grid_price <span class="hljs-keyword">and</span> units &gt;= grid_amount:  
            units -= grid_amount  
            remain_cash += grid_amount*today_unit_price  
            direction.iloc[i] = -<span class="hljs-number">1</span>  
            <span class="hljs-comment">#重置基准单位  </span>
            base_unit_price = today_unit_price  
              
        <span class="hljs-comment">## buy operation  </span>
        <span class="hljs-comment"># 当日价格低于网格价，且手里有现金  </span>
        <span class="hljs-keyword">if</span> today_unit_price &lt;= base_unit_price-grid_price <span class="hljs-keyword">and</span> remain_cash &gt;= grid_amount*today_unit_price:  
            units += grid_amount  
            remain_cash -= grid_amount*today_unit_price  
            direction.iloc[i] = <span class="hljs-number">1</span>  
            <span class="hljs-comment">#重置基准单位  </span>
            base_unit_price = today_unit_price  
  
                         
    <span class="hljs-keyword">return</span> direction,grid_interval
</code></pre>
<p>设定总计划最多投入金额 10000，初始建仓 400 股</p>
<pre><code class="hljs language-python">direction,grid_interval = stock_grid_line_v1(close,<span class="hljs-number">10000</span>,<span class="hljs-number">400</span>)

输出：
每格交易价格间隔: <span class="hljs-number">0.6667</span>，每格交易数量: <span class="hljs-number">111</span>
初始买入价格<span class="hljs-number">8.7</span>
</code></pre>
<p>可视化</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">plot_entry_exit</span>(<span class="hljs-params">close, entries, exits, basic_line, grid_interval</span>):  
    fig = close.vbt.plot()  
    entries.vbt.signals.plot_as_entries(close, fig=fig)  
    exits.vbt.signals.plot_as_exits(close, fig=fig)  
    fig.add_shape(  
        <span class="hljs-built_in">type</span>=<span class="hljs-string">"line"</span>,  
        x0=<span class="hljs-number">0</span>, x1=<span class="hljs-number">1</span>,  <span class="hljs-comment"># 横坐标范围，0到1表示整个x轴的宽度  </span>
        y0=basic_line, y1=basic_line,  <span class="hljs-comment"># y0=y1=7 表示水平线位置  </span>
        xref=<span class="hljs-string">'paper'</span>,  <span class="hljs-comment"># 使用 'paper' 参考系确保线条延伸到整个图宽  </span>
        line=<span class="hljs-built_in">dict</span>(color=<span class="hljs-string">"Red"</span>, width=<span class="hljs-number">2</span>, dash=<span class="hljs-string">"dash"</span>)  <span class="hljs-comment"># 设置线条颜色、宽度和样式  </span>
    )  
    <span class="hljs-keyword">for</span> interval <span class="hljs-keyword">in</span> grid_interval:  
        fig.add_shape(  
        <span class="hljs-built_in">type</span>=<span class="hljs-string">"line"</span>,  
        x0=<span class="hljs-number">0</span>, x1=<span class="hljs-number">1</span>,  <span class="hljs-comment"># 横坐标范围，0到1表示整个x轴的宽度  </span>
        y0=interval, y1=interval,  <span class="hljs-comment"># y0=y1=7 表示水平线位置  </span>
        xref=<span class="hljs-string">'paper'</span>,  <span class="hljs-comment"># 使用 'paper' 参考系确保线条延伸到整个图宽  </span>
        line=<span class="hljs-built_in">dict</span>(color=<span class="hljs-string">"Blue"</span>, width=<span class="hljs-number">2</span>, dash=<span class="hljs-string">"dash"</span>)  <span class="hljs-comment"># 设置线条颜色、宽度和样式  </span>
    )  
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f'买入点数量<span class="hljs-subst">{entries.vbt.signals.total()}</span>,卖出点数量<span class="hljs-subst">{exits.vbt.signals.total()}</span>'</span>)  
    <span class="hljs-keyword">return</span> fig.show()
</code></pre>
<p>由于时间有一定滞后性，默认为得到交易信号后一天才开始交易。</p>
<pre><code class="hljs language-python"><span class="hljs-comment"># 实际操作买入卖出时间向后推迟一个单位</span>
entries = (direction == <span class="hljs-number">1</span>).vbt.signals.fshift() 
exits = (direction == -<span class="hljs-number">1</span>).vbt.signals.fshift()
plot_entry_exit(close,entries,exits,basic_line=close.iloc[<span class="hljs-number">0</span>],grid_interval=grid_interval)
</code></pre>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202411281645243.png&amp;size=m" alt="image.png"></p>
<p>进行实际回测，这里主要依赖vectorbt自带的回测方法，直接调用即可。忽略手续费。</p>
<pre><code class="hljs language-python">pf = vbt.Portfolio.from_signals(  
    close=close,   
    entries=entries,   
    exits=exits,   
    init_cash=<span class="hljs-number">10000</span>, <span class="hljs-comment"># 初始资金  </span>
    init_position= <span class="hljs-number">400</span>, <span class="hljs-comment">#初始仓位  </span>
    init_price = close.iloc[<span class="hljs-number">0</span>], <span class="hljs-comment">#初始建仓金额  </span>
    size=<span class="hljs-number">111</span>, <span class="hljs-comment"># 使用amount类型，每次进行固定股数的交易  </span>
    size_type=<span class="hljs-string">"amount"</span>,  
    <span class="hljs-comment"># fees=0.001,  </span>
    accumulate=<span class="hljs-literal">True</span>,  
)
pf.stats()
</code></pre>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202411281649054.png&amp;size=m" alt="image.png"></p>
<p>输出解析</p>
<ul>
 <li>Total Return 最终投资利润增长</li>
 <li>Benchmark Return 基线收益（一直持有收益）</li>
 <li>Total Time Exposure 总暴露在市场中的时间</li>
 <li>Max Gross Exposure 最大交易中使用的现金量</li>
 <li>Max Drawdown 最大回撤，即组合价值在创下新高后下跌的最大距离</li>
 <li>Total Orders 总订单次数</li>
 <li>Total Trades 总交易次数。Vectorbt 中仅卖出操作计作交易。一旦卖出订单被执行（通过减少或关闭 position），就会根据加权平均进入和退出价格计算损益 (the profit and loss, PnL)</li>
 <li>Win Rate 交易（卖单）产生利润的概率</li>
 <li>Best Trade 最好交易的利润率</li>
 <li>Worst Trade 最差交易的利润率</li>
 <li>Profit Factor 利润因子</li>
 <li>Expectancy 预期 average profitability 平均盈利能力</li>
</ul>
<p>回报率 25%，还是可以的。</p>
<h3 id="gridv2">Gridv2</h3>
<p>简单改进一下网格策略：每次交易网格后，下一个网格按照一定比例增加份额。输出多增加一个 size ，表示交易的数量</p>
<pre><code class="hljs language-python"><span class="hljs-comment">## 针对股票买入特定份数  </span>
<span class="hljs-comment">## 每一次买入卖出都会重置基准单位  </span>
<span class="hljs-comment">## 大网格增加份额。  </span>
  
<span class="hljs-comment"># 策略在执行之前先买入一定比例，后续使用网格进行交易测算。</span>
<span class="hljs-comment"># init_position 初始建仓份数  </span>
<span class="hljs-comment"># init_price 建仓时价格  </span>
<span class="hljs-comment"># position_size 已建仓的金额  </span>
<span class="hljs-comment"># remain_cash 用于执行网格的金额  </span>
<span class="hljs-comment"># units 持有的仓位  </span>
<span class="hljs-comment"># base_unit_price 基准买入价格  </span>
<span class="hljs-comment"># today_unit_price 当日价格  </span>
  
<span class="hljs-keyword">def</span> <span class="hljs-title function_">stock_grid_line_v2</span>(<span class="hljs-params">close, remain_cash, init_position,price_low=<span class="hljs-number">6</span>, price_high=<span class="hljs-number">12</span></span>):  
    init_price = close.iloc[<span class="hljs-number">0</span>]  
    units = init_position  
  
    base_unit_price = close.iloc[<span class="hljs-number">0</span>]  
    direction = pd.Series(np.full(data.shape[<span class="hljs-number">0</span>], <span class="hljs-number">0</span>), index=data.index)  
    size = pd.Series(np.full(data.shape[<span class="hljs-number">0</span>], <span class="hljs-number">0</span>), index=data.index)  
  
    <span class="hljs-comment"># 计算网格大小和每格交易数量，采用等差方式  </span>
    grid_price, grid_amount, grid_interval = arithmetic_grid(price_low=price_low, price_high=price_high, initial_fund=remain_cash,  
                                                             grid_num=<span class="hljs-number">10</span>)  
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f"初始买入价格<span class="hljs-subst">{init_price}</span>"</span>)  
  
    <span class="hljs-comment"># 记录操作位置  </span>
    position_grid = <span class="hljs-number">0</span>  
    <span class="hljs-comment"># 增加网格份额   </span>
    grid_amount_increase = <span class="hljs-built_in">int</span>(grid_amount * <span class="hljs-number">0.02</span>)  
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f"网格增加数量<span class="hljs-subst">{grid_amount_increase}</span>"</span>)  
  
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, close.shape[<span class="hljs-number">0</span>]):  
        today_unit_price = close.iloc[i]  
        buy_grid_amount = grid_amount + grid_amount_increase * position_grid  
        sell_grid_amount = grid_amount + grid_amount_increase * position_grid  
          
        <span class="hljs-comment"># 超出交易区间不做交易  </span>
        <span class="hljs-keyword">if</span> today_unit_price&lt;price_low <span class="hljs-keyword">or</span> today_unit_price &gt; price_high:  
            <span class="hljs-keyword">continue</span>  
  
        <span class="hljs-comment">## sold operation  </span>
        <span class="hljs-comment"># 当日价格高于网格价，且手里有持仓有剩余  </span>
        <span class="hljs-keyword">if</span> today_unit_price &gt;= base_unit_price + grid_price <span class="hljs-keyword">and</span> units &gt;= sell_grid_amount:  
            units -= sell_grid_amount  
            remain_cash += sell_grid_amount * today_unit_price  
            direction.iloc[i] = -<span class="hljs-number">1</span>  
            size.iloc[i] = sell_grid_amount  
  
            <span class="hljs-comment"># 重置调整基准  </span>
            base_unit_price = today_unit_price  
            position_grid -= <span class="hljs-number">1</span>  
  
        <span class="hljs-comment">## buy operation  </span>
        <span class="hljs-comment"># 当日价格低于网格价，且手里有现金  </span>
        <span class="hljs-keyword">if</span> today_unit_price &lt;= base_unit_price - grid_price <span class="hljs-keyword">and</span> remain_cash &gt;= buy_grid_amount * today_unit_price:  
            units += buy_grid_amount  
            remain_cash -= buy_grid_amount * today_unit_price  
            direction.iloc[i] = <span class="hljs-number">1</span>  
            size.iloc[i] = buy_grid_amount  
  
            <span class="hljs-comment"># 重置调整基准  </span>
            base_unit_price = today_unit_price  
            position_grid += <span class="hljs-number">1</span>  
  
    <span class="hljs-keyword">return</span> direction, size, grid_interval
</code></pre>
<p>选取和之前相同的参数模拟</p>
<pre><code class="hljs language-python">direction, input_size, grid_interval = stock_grid_line_v2(close,<span class="hljs-number">10000</span>,<span class="hljs-number">400</span>)

输出：
每格交易价格间隔: <span class="hljs-number">0.6667</span>，每格交易数量: <span class="hljs-number">111</span>
初始买入价格<span class="hljs-number">8.7</span>
网格增加数量<span class="hljs-number">5</span>
</code></pre>
<p>可视化</p>
<pre><code class="hljs language-python">entries = (direction == <span class="hljs-number">1</span>).vbt.signals.fshift() 
exits = (direction == -<span class="hljs-number">1</span>).vbt.signals.fshift()
<span class="hljs-comment"># 传入的每次交易数量也需要移位  </span>
input_size = input_size.shift(<span class="hljs-number">1</span>, fill_value=<span class="hljs-number">0</span>)
plot_entry_exit(close,entries,exits,basic_line=close.iloc[<span class="hljs-number">0</span>],grid_interval=grid_interval)
</code></pre>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202411282227673.png&amp;size=m" alt="image.png"></p>
<p>回测</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">signal_func_nb_v2</span>(<span class="hljs-params">c, long_signals, short_signals, size,input_sizes</span>):  
    long_signal = vbt.pf_nb.select_nb(c, long_signals)  
    short_signal = vbt.pf_nb.select_nb(c, short_signals)  
    input_size = vbt.pf_nb.select_nb(c, input_sizes)  
    <span class="hljs-keyword">if</span> long_signal:  
        <span class="hljs-built_in">print</span>(<span class="hljs-string">f'buy <span class="hljs-subst">{input_size}</span> amount'</span>)  
        size[<span class="hljs-number">0</span>, c.col] = input_size  
    <span class="hljs-keyword">if</span> short_signal:  
        <span class="hljs-built_in">print</span>(<span class="hljs-string">f'sell <span class="hljs-subst">{input_size}</span> amount'</span>)  
        size[<span class="hljs-number">0</span>, c.col] = input_size  
    <span class="hljs-keyword">return</span> long_signal, <span class="hljs-literal">False</span>, short_signal, <span class="hljs-literal">False</span>  
pf = vbt.Portfolio.from_signals(  
    close=close,   
    init_cash=<span class="hljs-number">10000</span>, <span class="hljs-comment"># 初始资金  </span>
    init_position= <span class="hljs-number">400</span>, <span class="hljs-comment">#初始仓位  </span>
    init_price = close.iloc[<span class="hljs-number">0</span>], <span class="hljs-comment">#初始建仓金额  </span>
    signal_func_nb=signal_func_nb_v2,  
    signal_args=(  
        vbt.Rep(<span class="hljs-string">"long_signals"</span>),   
        vbt.Rep(<span class="hljs-string">"short_signals"</span>),   
        vbt.Rep(<span class="hljs-string">"size"</span>),  
        vbt.Rep(<span class="hljs-string">"input_sizes"</span>)      
    ),  
    size=vbt.RepEval(<span class="hljs-string">"np.full((1, wrapper.shape_2d[1]), np.nan)"</span>),    
    size_type=<span class="hljs-string">"amount"</span>,  
    accumulate=<span class="hljs-literal">True</span>,  
    broadcast_named_args=<span class="hljs-built_in">dict</span>(  
        long_signals= entries,  
        short_signals=exits,  
        input_sizes=input_size,  
    ),  
    jitted = <span class="hljs-literal">False</span>  
)
pf.stats()
</code></pre>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202411282229197.png&amp;size=m" alt="image.png">
 <br>
 就回报率而言没有太大变化，但是其他指标有所提升。</p>
<p>值得注意的是，这个策略的超参数很多，网格上下限，网格数量，准备投入金额，初始建仓数量，都可以选取改变。况且就股票市场来说，买入的数量基本都是以1手为单位，上述的111交易份额实际不符合预期。</p>
<p>策略也有很多优化空间，比如入场时机或许可以选择一些参数联合判断（如 EMA ，RSI 等）。</p>
<p>Vectorbt 的优势就在于能够快速的遍历测试大规模数据的情况，进而从中选取合适的超参数。这里限于篇幅和进度，先暂时分享上述内容。</p>]]></description><guid isPermaLink="false">/archives/StrategyGridv1</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202411291127187.png&amp;size=m" type="image/jpeg" length="82956"/><category>默认分类</category><pubDate>Fri, 29 Nov 2024 03:20:00 GMT</pubDate></item><item><title><![CDATA[Obsidian好用的AI插件]]></title><link>https://laffitto.xyz/archives/obsidian-AI-plugins</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=Obsidian%E5%A5%BD%E7%94%A8%E7%9A%84AI%E6%8F%92%E4%BB%B6&amp;url=/archives/obsidian-AI-plugins" width="1" height="1" alt="" style="opacity:0;">
<p>目前自己主要的笔记工具为 Obsidian。自从见识到各种在线笔记工具的不靠谱后，逐渐将自己的笔记存放在本地，方便随时进行迁移。Obsidian 作为蓬勃发展的本地笔记工具成了我的主力，小到每天的记录，大到笔记的组织和博客的撰写，基本都存放其中。</p>
<p>随着这两年 AI 的发展，笔记工具的 AI 属性已然成为一个强大的卖点，NotionAI 的很多功能让人眼馋。好在 Obsidian 有着强大的社区插件支持，在各路大神的加持下，Obsidian 也可以集成众多的 AI 功能。这里推荐几个在目前时间点我用着比较好的插件。其中是否持续更新是一个比较看重的点，有更好的插件也欢迎分享。</p>
<h2 id="copilot">Copilot</h2>
<p><a href="https://github.com/logancyang/obsidian-copilot">Copilot</a> 名字和微软推出的 copilot 重名，旨在 obsdian 进行模型的对话。在设置好在线或者本地（ollama）模型后，其可以在右侧的对话框中直接进行问答。当然可以提前设定好并调用特定的 prompt，得到更加无缝的体验。完整的回答可以直接保存到 Obsidian 文件中，方便后续参考。
 <br>
 另外它可以进行长文的回答和整个知识库的回答。通过设定的 embedding 模型将文章全部向量化，你就可以对单篇文章甚至这个 Obsidian 库中进行提问，当然这会耗费大量的 token，效果上目前不算太好，但是作者一直在进行改进优化，未来可期。
 <br>
 特点：</p>
<ul>
 <li>Obsidian 里直接调用模型进行对话。并有着高效的模型增加和替换的流程。</li>
 <li>实验性质的长文和知识库回答。
  <br>
  缺点：</li>
 <li>不能够删除预置模板的模型，显得模型列表非常臃肿。</li>
 <li>知识库回答效果暂时不太好，应该和 RAG 流程优化有关。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202410102322446.png&amp;size=m" alt="image.png"></li>
</ul>
<h2 id="smart-connections">Smart Connections</h2>
<p><a href="https://github.com/brianpetro/obsidian-smart-connections">Smart-connections</a> 同样可以在单独的界面进行模型对话，这一点于 copilot 类似。不过它最吸引我的功能在于它可以实现通过 embedding 将库里的文章向量化，计算文章间相似度，然后在右侧栏展示一些相关的内容。向量化可以基于文章，也可以更细一步基于特定的 block。这样在进行文章查看回顾时可以直接参考，从某种程度上也是一种自动化的双向链接。
 <br>
 特点：</p>
<ul>
 <li>Obsidian 里直接调用模型进行对话。</li>
 <li>基于本地库，通过相似度推荐和当前文章高相关性的文章或段落。
  <br>
  缺点：</li>
 <li>插件设置较为繁琐，且近几次更新频繁导致界面较乱。</li>
 <li>embedding模型暂时无法自定义，且 embedding速度较慢需要优化。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202410102314331.png&amp;size=m" alt="image.png"></li>
</ul>
<h2 id="text-generator">Text Generator</h2>
<p><a href="https://github.com/nhaouari/obsidian-textgenerator-plugin">Text Generator</a> 主要是辅助文章的书写流程。它的主要功能是基于 AI 大模型的生成功能，基于模板和上下文要求在文章界面进行文章的撰写生成。不过这个插件目前用的不多，毕竟没有用 AI 写文章的需求，没有深究其特性。
 <br>
 特点：</p>
<ul>
 <li>基于正文内容的无缝书写体验，似乎是所有插件中独一份的。</li>
 <li>有官方的模板仓库用于参考。
  <br>
  缺点：</li>
 <li>体验暂时较少残缺，暂未发现使用场景。
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202410112153057.png&amp;size=m" alt="image.png"></li>
</ul>
<p>如上介绍的三个 AI 插件是我觉得在 Obsidian 的 AI 插件中质量较高，时常维护的优秀插件。插件的不足相信都会在持续的更新中得以优化并解决。每个插件都有自己的侧重点与特点，例如我使用 Copilot 的模型问答功能，使用 Smart Connection 的相似度联想功能，使用 Text Generator 模板调用功能。取舍相辅相成使用它们各自最优秀的部分，可以给自己带来最好的 Obsidian 使用体验。</p>]]></description><guid isPermaLink="false">/archives/obsidian-AI-plugins</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202410112208970.png&amp;size=m" type="image/jpeg" length="36918"/><category>默认分类</category><pubDate>Fri, 11 Oct 2024 14:07:00 GMT</pubDate></item><item><title><![CDATA[黑神话悟空]]></title><link>https://laffitto.xyz/archives/game-wukong</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E9%BB%91%E7%A5%9E%E8%AF%9D%E6%82%9F%E7%A9%BA&amp;url=/archives/game-wukong" width="1" height="1" alt="" style="opacity:0;">
<p>相信前段时间大家都被黑神话悟空给刷屏了。我在看完最终预告片后也直接热血沸腾入手了一份。经过一段时间的游玩，目前总游戏时长 45小时，把支线和隐藏基本都探索了一遍，打了真结局，刚刚进入二周目。要说黑猴属于魂类游戏吧，他倒也没有其他魂类游戏那种可怕的死亡惩罚，这使得游戏过程不会有太多的心理压力，玩艾尔登法环死亡掉魂的感觉太难受，以至于打到一半失去热情闲置了。游戏整体体验非常爽，扮演天命人寻找六根踏上旅程让人过分沉醉。</p>
<h2 id="游戏各方面体验">游戏各方面体验</h2>
<p>画面上，可能是虚幻引擎 5 的加持，觉得每个画面去截图都是那么的震撼。游戏科学团队进行了大量的实地取景，游玩体验从浮屠塔到小西天，包括黑风山，黄风岭和盘丝洞，感受到一种身临其境的感觉。Boss 设计也让人眼前一亮，除了每关设计的剧情大 boss，各种小怪和头目设定的也非常有趣，特别是内置的影神图怪物图鉴，大大加丰富了各个出场人物的背景细节。细品之下不由觉得每个人物都有自己的小心思，精彩至极。</p>
<p>操作上，有精魄，变身，法术的加持，外加各种不同的棍势，使得打法流派丰富多样。你既可以使用安身法正面硬刚，也可以毛毛流多种组合一套带走，像我比较菜的就习惯使用安身法加立棍的轮椅打法，照样可以慢慢磨通关。</p>
<p>内容上，感觉量大管饱。在玩完第一关较为线性的流程后，先被游戏的精美画面和战斗场景震惊。第二关开始就有各种岔路，外加奇奇怪怪的探索，加上敌人强度明显提升，顿时觉得有点东西。第三关和第四关更是有一种柳暗花明又一村的感觉，感觉快到头了，居然又又又到了一个新的场景，不免热血沸腾。第五章倒是感觉流程较短，但是加上隐藏地图依旧惊艳。第六章整个地图可以使用筋斗云随意探索，也算是一个小场景的开放世界，也从中体会了别样的乐趣。在打完杨戬后法天象地的环节，正酣的打斗加上出彩的 cg 演出，直接把我玩高潮了。游戏可以进行多周目的游玩，如果说一周目不是完全体有点受苦，二周目得到好的装备再去收集时简直变成了爽游，曾经吃过的亏与苦都可以在二周目加倍奉还，一份价格，两种体验，爽麻了。</p>
<p>剧情上，我个人觉得没啥大问题，黑神话悟空仅仅是在原先西游记的世界观基础上再次创作而已。第一章的贪嗔痴，第二章不可仅听一面之词的道理，第三章黄眉的背道哲学，第四章八戒和蜘蛛精的凄美爱情故事，第五章红孩儿的身世和回忆过往，第六章加上隐藏剧情的铺垫，尽管有些细微的地方可能不同人看会有槽点，但是完全达不到有些 B 站 up 主破口大骂剧情稀烂的程度。那些人拿着西游记的原作去分析原意哲学，大骂游戏科学对其进行的胡编，但是人家只是基于原著的改编了，也不至于如此上纲上线，在我看来像是未免为了突出自己思想观点的不同强行当跳梁小丑罢了。</p>
<p>当然不容质疑还是有一些缺点的，比如游戏中有一些莫名其妙的空气墙。以为能过去但实际过不去，以为过不去却又能过去，难免会导致探索过程中碰壁或者错过一些东西。而且游戏没有小地图，有些特殊场景就比较容易迷路，但由于也不是开放世界，多转悠两圈也能找到正确的地方。更何况有民间大神自主开发出游戏跳跃空气墙和小地图的补丁，如果真需要可以去下载。这些小问题在优秀的游戏体验面前都不是事了。</p>
<h2 id="游戏评价">游戏评价</h2>
<p>虽然今年还未过完，但这应该是我自己的年度游戏了，总体差强人意，但我依旧给出 10 分的满分评价。游玩的这段时间是真心沉醉于游戏塑造的世界里，有挑战，但更多的轻松和探索的快乐。对比服务型游戏，买断制游戏通常是吃力不讨好的那种。但是买断制游戏带给人的幸福感是远远高于服务型游戏的。服务型游戏通常是有线上博弈的成分，赢了固然舒服，但也让人觉得疲惫，外加这类游戏需要每天做那些无聊的任务，甚至有些极其黑心的氪金系统，常常会觉得到底是我在玩游戏还是游戏在玩我，花钱又花时间。买断制游戏通常是有一个不断成长最终到达终点的过程，而这一路的旅途收集，好的游戏会让人沉浸其中极其愉悦，这点任天堂很会，旷野之息王国之泪等其他作品都让我获得了无穷的乐趣，我很开心黑神话悟空也让我感受到了同样的快乐。</p>
<h2 id="游戏展望">游戏展望</h2>
<p>截至目前，黑神话单 steam 的销量大概都快有 2000 万份了。作为中国自己的第一款 3A 大作，从结果上看这无疑是口碑和商业上的巨大成功。从前大家（包括我自己）总是嘲讽中国这环境根本做不出 3A 级别的游戏作品，这次终于被打了脸。这次成功的尝试给之后的游戏工作室提供的了宝贵的经验，未来可能会有更多的国产 3A 大作面世。不过我觉得可能还是改变不了什么，在品尝到网游与手游躺着就能收钱模式的甜头后，累死累活多年磨一剑，且根本不确定能否成功的情况下，这种试错对大多数企业还是太奢侈了。而且另一方面黑神话悟空过于优秀，直接给国内行业立了一个巨高的标杆，悲观的猜想是出道即巅峰。不过但愿我所说的都是屁话，希望国内的 3A 产业会以此为导火索，更加蓬勃的发展，结合中国传统文化发扬光大，为游戏作为第九艺术真正的正名。</p>]]></description><guid isPermaLink="false">/archives/game-wukong</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202409212305963.jpg&amp;size=m" type="image/jpeg" length="543258"/><pubDate>Sat, 21 Sep 2024 15:06:00 GMT</pubDate></item><item><title><![CDATA[香港银行卡]]></title><link>https://laffitto.xyz/archives/HongKongBankCards</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E9%A6%99%E6%B8%AF%E9%93%B6%E8%A1%8C%E5%8D%A1&amp;url=/archives/HongKongBankCards" width="1" height="1" alt="" style="opacity:0;">
<p>五一去香港旅游的时候，顺便办理了香港银行卡，这里记录一些经验分享。</p>
<p>这次一次性办理了两张银行卡，中国银行香港和汇丰银行。两个银行办理的流程不一样，但是很幸运一次性搞定。</p>
<h2 id="准备工作">准备工作</h2>
<p>办理银行卡需要以下物品</p>
<ul>
 <li><strong>中国居民身份证</strong></li>
 <li><strong>港澳通行证或护照</strong></li>
 <li><strong>入境小票</strong>: 入境的时候打印的凭证。</li>
 <li><strong>港币现金</strong>: 激活实体银行卡用</li>
</ul>
<p>有些教程说还需要<strong>内地地址证明</strong>，例如信用卡账单、水电缴费账单等，需要是本人名字的地址，时间需为近 3 个月。我准备了但这次完全没有用上。同时需要导出出入境记录: 微信小程序&nbsp;<code>移民局12367</code> &gt; <code>中国公民服务</code> &gt; <code>出入境记录查询</code> 导出记录。</p>
<p>参考教程主要如下:</p>
<ul>
 <li><a href="https://tumutanzi.com/archives/17252">香港银行开户经验 – 土木坛子</a></li>
 <li><a href="https://luolei.org/how-to-open-a-bank-account-in-hongkong-2024">香港银行开户：2024 年更新 | 中银、汇丰、众安开户经验分享 | 罗磊的独立博客</a></li>
</ul>
<h2 id="办理流程">办理流程</h2>
<p>办理卡需要看好银行营业时间，当时五一期间 1 号放假，2~3 号上班，4 号仅上午上班。因为住宿的酒店位于荃湾区，我选择的 2 号上午早上九点就直接去银行那边办理。从结果来看，两个银行都是可以事先预约的，但是当时有些经验说预约不上，所以我选择了直接去现场办理。</p>
<p>中国银行香港基本可以做到自助办理。进入网点后，全部的操作可以在自助机上进行，通过扫码操作，上传身份证，港澳通行证，入境记录，填入一些收入信息，仅有一个工作人员在旁边答疑。如果审核顺利的话，3 分钟刷新后就显示办理完成，效率高的不敢想象。注册完成后，需要在旁边的 ATM 上存入现金进行账户激活。实体银行卡大概 2 至 3 周左右会邮寄到预先填好的地址。</p>
<p>汇丰银行办理的过程比较费时。进去之后人挺多，如果没有预约的话就需要排队，而且他们是纯人工审核，时间会比较久。叫到号之后工作人员会带你进入一个小屋里面谈，主要就是证明一下自己的积蓄，有足够的能力在这里储蓄，填写一下各种信息。最终判断你能不能办卡还是根据网上系统的判断，这点和中国银行比较类似，所以面谈时保持理直气壮点就可以。在网上系统审核通过后，汇丰会当场给你卡并协助你激活。网点还直接帮我激活了人民币和美元一些业务。服务比较周到。</p>
<p>对比两家银行，中国银行香港可以自助办理，从申请到激活全程在机器上操作。整体速度快，效率高，但业务可能不会那么细致。汇丰银行需要排队等待，其中有人工的干预，申请流程会更细致，服务更好，有疑问也可以当面咨询。但是花费时间较长，申请和激活都要排队，而且等待休息区没有座位，比较累。不过两家银行一共花费了大概两个小时拿下两张卡，还是比较满意的。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202408102323384.jpg&amp;size=m" alt=""></p>
<h2 id="关于银行之间转账">关于银行之间转账</h2>
<p>香港账户之间可以通过「转数快」达到无手续费转账，内地账户之间也可以通过云闪付达成无手续费转账。但是香港和内地之间账户就涉及到跨境转账，通常需要手续费和电报费，加起来也是一笔不小的费用了，不过内地的中国银行和中国银行香港账户之间转账是可以做到免上面两种手续费的。详情可以参考这篇文章：</p>
<p><a href="https://mp.weixin.qq.com/s/FBovMycS3UPK_WNQjpPFIA">无损跨境转账，真香</a></p>
<p>文章写的很细致，经测试从香港转到内地无需费用，内地转香港最后一步由于银行需要物理密码器动态口令暂时未测试，不过问题应该是不大。</p>
<h2 id="办理银行卡原因">办理银行卡原因</h2>
<p>持有香港银行卡，主要还是多了一种工具。这就像是梯子一样，很多的东西都要通过它作为一种媒介去探索。无论是投资港股，中转转账，海外购物它都能胜任。当我看到新的东西，新的机会时，我不会因为手里没有某些工具而失之交臂。优势能够积少成多，这就已经足够了。</p>]]></description><guid isPermaLink="false">/archives/HongKongBankCards</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202408102330880.jpeg&amp;size=m" type="image/jpeg" length="10642"/><category>默认分类</category><pubDate>Sat, 10 Aug 2024 15:35:00 GMT</pubDate></item><item><title><![CDATA[RAG相关知识]]></title><link>https://laffitto.xyz/archives/RAG</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=RAG%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86&amp;url=/archives/RAG" width="1" height="1" alt="" style="opacity:0;">
<p>RAG 的一些学习参考，主要基于 <a href="https://twitter.com/rlancemartin">Lance Martin</a> 的介绍，随时更新。</p>
<h2 id="rag-定义">RAG 定义</h2>
<p>RAG（retrieval-augmented-generation）。检索增强生成（RAG）是指对大型语言模型输出进行优化，使其能够在生成响应之前引用训练数据来源之外的权威知识库。
 <br>
 从技术上讲，RAG是基于知识库检索的提示词增强技术。
 <br>
 根据用户输入的信息在数据库中进行查询，将与查询相关的数据，加入到提示词的上下文中，从而提高模型的回答质量。</p>
<p>这里整理一个基于 langchain 的 RAG 介绍视频教程
 <br>
 <a href="https://github.com/langchain-ai/rag-from-scratch">GitHub - langchain-ai/rag-from-scratch</a>
 <br>
 <a href="https://www.youtube.com/playlist?list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x">RAG From Scratch - YouTube</a></p>
<p>RAG整体流程和相关技术图如下
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405281735575.png&amp;size=m" alt="image.png"></p>
<h2 id="basic-idea">Basic idea</h2>
<h3 id="indexing">Indexing</h3>
<p>通常需要加载数据，分割数据，嵌入操作，这会让后续的 retrieve 操作变得更加方便。
 <br>
 分割（splitting）是因为模型实际上下文窗口是有限的，切分成小块以适应模型。
 <br>
 问题和参考文件都要进行 embedding 操作，转化到向量空间表达（vectorstore）。即使句子没有那么长，embedding 还是会统一到一个固定的向量长度的。</p>
<h3 id="retrieval">Retrieval</h3>
<p>问题和参考文件在进行 index 后，它们共同被转化到更高维度的空间，在此空间中计算相似度以查找和问题相似的参考文件。当然可以寻找很多个（参数中可以定义）相似度高的文件预料作为备选使用。</p>
<h3 id="generation">Generation</h3>
<p>将 retrieve 得到的文档放入 LLM 上下文窗口中，进一步得出答案。这一步需要用到 prompt。通常是构建一个 prompt template，将问题和得到的文档按照一定格式输入 LLM ，进行 chatmodel，之后解析为字符串后即可得到答案。</p>
<p>Langchain 中可以轻易的构建 chain，进行一系列操作。使用 invoke 等方法调用 chain</p>
<p>一段简单的流程代码：</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">import</span> bs4
<span class="hljs-keyword">from</span> langchain <span class="hljs-keyword">import</span> hub
<span class="hljs-keyword">from</span> langchain_chroma <span class="hljs-keyword">import</span> Chroma
<span class="hljs-keyword">from</span> langchain_community.document_loaders <span class="hljs-keyword">import</span> WebBaseLoader
<span class="hljs-keyword">from</span> langchain_core.output_parsers <span class="hljs-keyword">import</span> StrOutputParser
<span class="hljs-keyword">from</span> langchain_core.runnables <span class="hljs-keyword">import</span> RunnablePassthrough
<span class="hljs-keyword">from</span> langchain_openai <span class="hljs-keyword">import</span> OpenAIEmbeddings
<span class="hljs-keyword">from</span> langchain_text_splitters <span class="hljs-keyword">import</span> RecursiveCharacterTextSplitter

<span class="hljs-comment"># Load, chunk and index the contents of the blog.</span>
loader = WebBaseLoader(
    web_paths=(<span class="hljs-string">"https://lilianweng.github.io/posts/2023-06-23-agent/"</span>,),
    bs_kwargs=<span class="hljs-built_in">dict</span>(
        parse_only=bs4.SoupStrainer(
            class_=(<span class="hljs-string">"post-content"</span>, <span class="hljs-string">"post-title"</span>, <span class="hljs-string">"post-header"</span>)
        )
    ),
)
docs = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=<span class="hljs-number">1000</span>, chunk_overlap=<span class="hljs-number">200</span>)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())

<span class="hljs-comment"># Retrieve and generate using the relevant snippets of the blog.</span>
retriever = vectorstore.as_retriever()
prompt = hub.pull(<span class="hljs-string">"rlm/rag-prompt"</span>)


<span class="hljs-keyword">def</span> <span class="hljs-title function_">format_docs</span>(<span class="hljs-params">docs</span>):
    <span class="hljs-keyword">return</span> <span class="hljs-string">"\n\n"</span>.join(doc.page_content <span class="hljs-keyword">for</span> doc <span class="hljs-keyword">in</span> docs)


rag_chain = (
    {<span class="hljs-string">"context"</span>: retriever | format_docs, <span class="hljs-string">"question"</span>: RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

rag_chain.invoke(<span class="hljs-string">"What is Task Decomposition?"</span>)
</code></pre>
<p>整体例子和理解可以参考 <a href="https://python.langchain.com/v0.2/docs/tutorials/rag/">Build a Retrieval Augmented Generation (RAG) App | 🦜️🔗 LangChain</a></p>
<hr>
<p>以下为基于 RAG 流程的一些优化的方法，仅作简单解释，自己也不是太懂，随时学习补充。</p>
<h2 id="query-translation">Query Translation</h2>
<p>对于初始输入的问题，可以以某种特定的方法翻译或修改为更好的内容，以改进检索的过程。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405291107869.png&amp;size=m" alt="image.png"></p>
<h3 id="multi-query">Multi Query</h3>
<p>其中一种方法是转换一个问题至很多不同角度的问题，本质上是一种重写（rewritten）。至于如何转化为多个角度的问题，可以直接交给 LLM。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405290014409.png&amp;size=m" alt="image.png">
 <br>
 <a href="https://www.youtube.com/watch?v=JChPi0CRnDY&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=5">RAG from scratch: Part 5 (Query Translation -- Multi Query) - YouTube</a></p>
<h3 id="rag-fusion">RAG-Fusion</h3>
<p>和 multi query 类似，不过在向量化计算相似度之后，进行了一种排序（rank）来检索文档，称为 rank Fusion。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405290029930.png&amp;size=m" alt="image.png">
 <br>
 <a href="https://www.youtube.com/watch?v=77qELPbNgxA&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=6">RAG from scratch: Part 6 (Query Translation -- RAG Fusion) - YouTube</a></p>
<h3 id="decomposition">Decomposition</h3>
<p>Decomposition（Least-to-most prompt context）
 <br>
 将原始的问题分解成多个子问题，并<strong>依序</strong>解答问题。联合上一个问题得到的答案和这一个问题共同作为预料进行回答。至于如何分解成有嵌套关系的子问题，同样可以直接交给大模型。</p>
<p>IR-CoT: Interleave retrieval with CoT
 <br>
 动态检索以帮助解决子问题，有点 stacking 的味道。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405291041643.png&amp;size=m" alt="image.png">
 <br>
 <a href="https://www.youtube.com/watch?v=h0OPWlEOank&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=7">RAG from scratch: Part 7 (Query Translation -- Decomposition) - YouTube</a></p>
<h3 id="step-back-prompting">Step-back prompting</h3>
<p>通过提问基于该问题的更抽象层面的问题来改善原始问题。
 <br>
 <a href="https://www.youtube.com/watch?v=xn1jEjRyJ2U&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=8">RAG from scratch: Part 8 (Query Translation -- Step Back) - YouTube</a></p>
<h3 id="hyde">HyDE</h3>
<p>借助 LLM ，基于问题生成一部分具有参考意义的文档或论文参考，作为假设文档。联合假设文档和自己提供的文档作为语料，让 LLM 回答问题。
 <br>
 <a href="https://www.youtube.com/watch?v=SaDzIVkYqyY&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=9">RAG from scratch: Part 9 (Query Translation -- HyDE) - YouTube</a></p>
<h2 id="routing">Routing</h2>
<p>Rounting（路由）的作用是假设有很多的数据库，基于得到的问题，能够将问题分配到合适的数据库中进行后续处理。</p>
<h3 id="logitic-routing">Logitic routing</h3>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405291558965.png&amp;size=m" alt="image.png"></p>
<p>基于不同的库，将输入问题转化为一个结构化对象，对象的输出在不同的几个库中，
 <br>
 <a href="https://www.youtube.com/watch?v=pfpIndq7Fi8&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=10">RAG from scratch: Part 10 (Routing) - YouTube</a></p>
<h3 id="semantic-routing">Semantic routing</h3>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405291632778.png&amp;size=m" alt="image.png">
 <br>
 将多个 prompt 嵌入，和问题一起计算相似度，选择相似度高的 prompt 进行后续的问题回答。</p>
<p>这时 LLM 在回答问题的同时，还会返回基于问题的对象。</p>
<h2 id="query-structuring">Query Structuring</h2>
<p>目标是将输入的自然语言问题转化为结构化的查询，可以应用于向量存储层面的元数据过滤器。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405292310802.png&amp;size=m" alt="image.png">
 <br>
 可以用来作为结构化查询使用
 <br>
 <a href="https://www.youtube.com/watch?v=kl6NwWYxvbM&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=11">RAG from scratch: Part 11 (Query Structuring) - YouTube</a></p>
<h2 id="indexing-1">Indexing</h2>
<h3 id="multi--representation">Multi -representation</h3>
<p>借助 LLM 对原始的文档进行总结并分割，类似于一种蒸馏
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405301124497.png&amp;size=m" alt="image.png">
 <br>
 原始文档使用 LLM 总结后放入向量空间，联合原始的文档，进行最终的检索。
 <br>
 <a href="https://www.youtube.com/watch?v=gTCU9I6QqCE&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=12">RAG from scratch: Part 12 (Multi-Representation Indexing) - YouTube</a></p>
<h3 id="raptor">RAPTOR</h3>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405311653934.png&amp;size=m" alt="image.png"></p>
<p>有些信息可能需要来自很多的文件才能得到。这时候可以考虑如下思路，先用聚类的思想，将原始文件分为几块并形成摘要，可以继续抽象到更高层面摘要，逐级进行递归。这样等于是从细致到抽象层面都有非常广的覆盖范围，之后将这些部分共同向量化存储。
 <br>
 <a href="https://www.youtube.com/watch?v=z_6EeA2LDSw&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=13">RAG From Scratch: Part 13 (RAPTOR) - YouTube</a></p>
<h3 id="colbert">ColBERT</h3>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405312257477.png&amp;size=m" alt="image.png"></p>
<p><a href="https://www.youtube.com/watch?v=cN6S0Ehm7_8&amp;list=PLfaIDFEXuae2LXbO1_PKyVJiQ23ZztA0x&amp;index=14">RAG From Scratch: Part 14 (ColBERT) - YouTube</a></p>
<h2 id="retrieval-1">Retrieval</h2>
<h3 id="cohere-rerank">Cohere ReRank</h3>
<p>在进行 embedding 后进行搜索时，根据用户问答对语料进行一定程度的排序。
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202406031136210.png&amp;size=m" alt="image.png"></p>
<p><a href="https://techdiylife.github.io/blog/topic.html?category2=t07&amp;blogid=0049"># ReRank 与 Embedding 模型的区别？ 如何选择 ReRank 模型？</a>
 <br>
 <a href="https://www.bmabk.com/index.php/post/244105.html">聊聊QAnything之二阶段检索(粗召回与精排) | 极客之音</a>
 <br>
 <a href="https://github.com/netease-youdao/QAnything">GitHub - netease-youdao/QAnything: Question and Answer based on Anything.</a>
 <br>
 <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202405281708126.png&amp;size=m" alt="image.png"></p>
<h3 id="corrective-rag">Corrective RAG</h3>
<p><a href="https://www.youtube.com/watch?v=E2shqsYwxck">Building Corrective RAG from scratch with open-source, local LLMs - YouTube</a> <a href="https://github.com/langchain-ai/langgraph/blob/main/examples/rag/langgraph_crag_local.ipynb">langgraph/examples/rag/langgraph_crag_local.ipynb at main · langchain-ai/langgraph · GitHub</a></p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202406041216416.png&amp;size=m" alt="image.png"></p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202406041217971.png&amp;size=m" alt="image.png">
 <br>
 将每一部分抽象为一个节点。借助 langgraph 可以快速构建。
 <br>
 使用 jsonmode，借助 LLM 模型，针对问题对每一段预料其进行结构化的筛选，设定特定字符如 <code>score</code> 再进行后续的操作。例如，score 表示该预料是否和问题相对符合，输出为 yes/no。如果模型判断 <code>score=True</code>，将对应预料保留。如果不是，进行一些 web_search 等操作进行文档补充。最终使用 LLM 进行结果输出。</p>
<h2 id="embedding-models">Embedding models</h2>
<p><a href="https://ollama.com/blog/embedding-models">Embedding models · Ollama Blog</a>
 <br>
 <a href="https://techdiylife.github.io/blog/topic.html?category2=t07&amp;blogid=0047"># 如何选择RAG的Embedding模型？</a>
 <br>
 Acge 模型效果比较好</p>
<pre><code># 下载模型
ollama pull chevalblanc/acge_text_embedding

# 运行模型
from langchain_community.embeddings import OllamaEmbeddings
vectorstore = Chroma.from_documents(documents=splits, embedding=OllamaEmbeddings(model="chevalblanc/acge_text_embedding"))
</code></pre>
<p><a href="https://www.bilibili.com/video/BV1h142197Fm">如何选择RAG的Embedding模型？_哔哩哔哩_bilibili</a></p>
<h2 id="总结">总结</h2>
<p>可以发现，很多技术本身是依赖与 LLM 本身的性能。如果想构建一个性能优异的 RAG 系统，还是得选择一个靠谱的模型。</p>
<h3 id="其他参考">其他参考</h3>
<p><a href="https://python.langchain.com/v0.2/docs/tutorials/qa_chat_history/">Conversational RAG | 🦜️🔗 LangChain</a>
 <br>
 关于 pydantic 类 <a href="https://docs.pydantic.dev/latest/#pydantic-examples">Welcome to Pydantic - Pydantic</a>
 <br>
 <a href="https://techdiylife.github.io/blog/topic.html?category2=t07&amp;blogid=0050"># RAG共学一：16个问题帮你快速入门RAG</a></p>]]></description><guid isPermaLink="false">/archives/RAG</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Flaffitto%2FPic_bed%2F202406062257437.png&amp;size=m" type="image/jpeg" length="26961"/><pubDate>Thu, 6 Jun 2024 14:58:00 GMT</pubDate></item><item><title><![CDATA[游戏 Animal Well]]></title><link>https://laffitto.xyz/archives/game-animal-well</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E6%B8%B8%E6%88%8F%20Animal%20Well&amp;url=/archives/game-animal-well" width="1" height="1" alt="" style="opacity:0;">
<p>你应该或多或少看过或者上手玩过一些解谜游戏，或是纯粹解谜为主，类似锈湖系列，room 系列，纪念碑谷等等。或是<a href="https://zh.wikipedia.org/wiki/%E7%B1%BB%E9%93%B6%E6%B2%B3%E6%88%98%E5%A3%AB%E6%81%B6%E9%AD%94%E5%9F%8E%E6%B8%B8%E6%88%8F">类银河战士恶魔城游戏</a> ，在偌大的地图中探索，不断升级获得新能力，再进行新的探索。有些解谜基于游戏本身，你在自己解谜完成后会有一种小快感，有些麻烦的尝试后可能会在网上搜索答案，然后感叹谜题之精妙。更有构思复杂的谜题，在一环一环的嵌套破译后，你会惊呼是神作。然后还有一类谜题超出了游戏本身，他可能打破第四面墙，达到作者与玩家的直接沟通，或者疯狂的将游戏内容拓展到现实。</p>
<p>最近玩了一款新像素风类银河战士恶魔城游戏，<a href="https://www.animalwell.net/">animal well</a>，直译过来就是动物井。作者 <a href="https://twitter.com/billy_basso"><strong>Billy Basso</strong></a> 经过七年的独立开发最终问世。游戏 steam，switch 和 ps 平台都有。游戏很小仅有不到 40M，据说还是作者自己开发的引擎，但内容真的惊为天人，游戏设计之精妙，谜题难度之离谱，我个人评价是满分 10 分的佳作。</p>
<p>游戏的地图十分大，而且是左右上下连通的，这算是亮点，但不算新意。我之前玩过的<a href="https://memo.laffitto.xyz/m/e9d415d447740760">好狗狗星系</a>才是真正把这种连通地图做成游戏特色。游戏初始操纵着软糖人（个人称呼）在地图中探索。在途中你会收集各种各样的东西，获得不一样的能力，借助能力你就能去一些你之前无法探索的地形。听起来很俗套，但是真正游玩的时候，不同能力的搭配会达成一些操作，你会惊呼，同一个谜题原来可以这样解，又可以那样解，而这要求的操作难度是大大不同的，颇有一种塞尔达神庙解谜的感觉。但是你以为自己发现了游戏中的bug，可以用某种方式去无限作弊时，你又会发现，其实作者早就设置好了障碍，这一切都在他的计算之中。</p>
<blockquote>
 <p>庞大的地图和渺小的我
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405272333044.jpg&amp;size=m" alt=""></p>
</blockquote>
<p>游戏中期可以获得一个道具笛子，通过不同的方向可以吹出不同的韵律，而特定的韵律就可以触发特殊的效果。这就导致游戏中蕴含着很多隐藏谜题。无论是收集64颗蛋后，破译出64音符的旋律解锁重要道具，又或者全图寻找16只兔子，之后再次根据兔子耳朵结合四进制信息破译方向信息，抵达最终之地。你都会惊呼，这难度和隐藏度已经到了非人的境界。</p>
<p>更为疯狂的是，游戏中一些独特操作会产生一些特殊编码，然而他们都是有意义的，收集全部内容完成拼接，会得到一个地图，而地图的最终之地，居然是作者和玩家的对话录音，这切切实实打破了第四面墙。这终极的谜题，在全网玩家探索努力下居然三天就破译出来了，不得不感叹网络和群众的力量。尽管如此，游戏还有许多细小的彩蛋等待探索。你永远不知道作者藏了多少东西。
 <br>
 有兴趣的可以看看 b 站上的相关解谜视频，剩下的只剩感叹：
 <br>
 <a href="https://www.bilibili.com/video/BV1Dx4y1i7C1">动物井 寻找农场巨兔以及解谜原理 ANIMAL WELL 预定年度最佳探索类银河恶魔城</a>
 <br>
 <a href="https://www.bilibili.com/video/BV1Lz421Y7y1">动物井真结局 最疯狂的谜题以及解谜原理 开发者录音 ANIMAL WELL 预定年度最佳探索类银河恶魔城</a></p>
<p>我在switch平台购买游玩的游戏，现在大概12小时游戏时间，仅仅全收集了蛋，兔子谜题和第四面墙实在是过于复杂了，不是我能独立解决的，后面的内容看视频云完了。实际我是 2D 跳跃类型游戏的手残党，玩这个游戏有些地方还是受了点苦头的，特别是你在漫长跳跃尝试后因为一个失误失败重来，真的非常烦躁。不过好歹还不算太难，达成之后有一种非常强的满足感。玩游戏的时候打开地图，你会好奇地探索着任何一个黑色的区域，因为基本上所有的区域都有隐藏的东西，他们就如同一个个小手勾引着你将他们全部挖掘。作为一个独立游戏，在保证趣味性和探索性的同时，能够不断让你发出惊呼，这种惊喜让生活充满了乐趣。你也能够感受到开发者的硬核和设计良苦用心。这时一个好游戏，值得大家都去感受一下，不过 steam 上售价 85 米，不着急还是可以等等打折再入手吧。</p>
<blockquote>
 <p>追逐战的猫猫截图，说实话有点吓人
  <br>
  <img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405272334242.jpg&amp;size=m" alt=""></p>
</blockquote>]]></description><guid isPermaLink="false">/archives/game-animal-well</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405292341145.png&amp;size=m" type="image/jpeg" length="128740"/><pubDate>Wed, 29 May 2024 15:42:00 GMT</pubDate></item><item><title><![CDATA[旅程——香港]]></title><link>https://laffitto.xyz/archives/HongKong_journey</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E6%97%85%E7%A8%8B%E2%80%94%E2%80%94%E9%A6%99%E6%B8%AF&amp;url=/archives/HongKong_journey" width="1" height="1" alt="" style="opacity:0;">
<p>作为一个生活在中国的普通人，能有一个长假期不容易。趁着五一假期，和女朋友和另一位好朋友一起开启一段香港之旅。</p>
<h2 id="day1-过关-然后落寞离场">DAY1 过关 然后落寞离场</h2>
<p>去香港的第一步是过关。从合肥出发，乘坐 6 点 40 的飞机，于 8 点半左右到达深圳。我们的路线是前往福田口岸过关。可能是由于深圳香港天气不好的原因，口岸没有想象中五一那种流量，轻轻松松基本没有排队便到达了香港境内——落马洲站。</p>
<p>入境后香港这边也是有雨，先乘坐地铁到酒店。香港的地铁也算方便，在 iphone 上开通了八达通后，体验基本和国内一致。在一路换乘颠簸之后，我们终于到达位于荃湾附近的酒店。淅淅沥沥的小雨打湿了行李箱，不过也打走了假期拥挤的氛围。</p>
<p>我们这一行的目的是来看五月天五月一日的香港演唱会，可以说是为了这盘醋包了这顿饺子。在我去附近的取票机取了票后，已然下午1点左右。当下还是得吃点东西来填饱肚子，在休整一番后，我们乘坐酒店巴士到附近的新都会广场。这里我们吃了一家越南菜芽庄。整体来说是我了解的那种臭臭又香香的感觉，肉很香，酱很上头。</p>
<p>吃饱喝足后，我们向着演唱会的地点中环附近前行。在快到达场馆附近时，突然收到了因为器材和天气原因演唱会推迟到9号到噩耗。当时瞬间感觉如此的不真实但又不得不接受这样的结果。看着中环附近的巨大的摩天轮和同样得到消息失落的歌迷们，有一种身处巨大洪流下的无力感。天气倒是讽刺，雨逐渐消失甚至开始放晴，至少不用打伞了。</p>
<p>演唱会取消归取消，我们的行程还得继续。顺延着海滨长廊继续逛街拍照，海风与水面之间的游船航行在维多利亚港，有种轻松惬意的感觉。远远的可以看见museum+的巨大屏幕和天际100高挑身影。预报说8点有烟花大会，我们在时间差不多的时候选取到一个合适的位置，静静的等待烟花绽放。然而期望越大，失望也挺大，可能是离烟花地点较远的缘故。烟花在感官上非常的小，甚至没有旁边的楼高，反观烟倒是挺大，稀稀拉拉的放了10min就结束了。个人感觉实在是太拉了，无论是本地人还是游客，看到肯定都会失望，宣传的有点用力了。</p>
<p>回程的时候想着吃点东西，到达葵涌附近的富华冰室。一开始我听冰室这个名字，还以为是吃甜品冰淇淋的地方，尝试才知道是类似于香港的那种大排档一样的形式。你可以点各种盖饭面条，外加小零食饮料，算是有香港特色。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405142248846.jpg&amp;size=m" alt="20240514_122519.jpg"></p>
<h2 id="day2-city-walk-累但挺开心">DAY2 City Walk 累但挺开心</h2>
<p>第二天的主要任务就是逛街。从旺角出发，沿着弥敦道一路向南进发，途径油麻地-佐敦-尖沙咀。路上形形色色的车，形形色色的楼。五彩斑斓的双层巴士，红色鲜艳的小的士。走在香港的街头，路边有繁华的高楼大厦，但同时也有低矮小巷。整体感觉路边乱乱的，但是乱中又透露着秩序，有种矛盾的美感。像是走在一种极度现代与古老的结合体中。
 <br>
 中餐我们找了一家旺角的金华冰厅，在平常的主食基础上，点了菠萝包和西多士。西多士就是炸面包上面加上黄油，不过这一家的西多士有点过于油了，很香但不能够多吃。而且同是港式奶茶，仅仅是冰与热也有很大的区别。
 <br>
 区别于内地的商场，香港地段寸土寸金，有些商场甚至有十几楼高，不过占地面积倒不是很大。从下午走到晚上，一路走到尖沙咀附近，伴随着淅淅沥沥的小雨，再次沿着海滨漫步，星光大道附近有手印长廊，里面有很多明星大导演的手印嵌在其中，还有麦兜可爱的小猪蹄。晚上去一家叫池记的馆子吃的云吞面和艇仔粥，感觉比较正宗，因为云吞面的那个汤够难吃。它艇仔粥的英文够有意思，Congee with pork squid and fish，直观的展示了所有的配料。喝粥是很舒服的，可以消除一定疲惫。这一天走的实在是太累了，从小腿痛到脚后跟。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405142248382.jpg&amp;size=m" alt="20240514_122759.jpg"></p>
<h2 id="day3-香港海洋公园-进发">DAY3 香港海洋公园 进发</h2>
<p>第三天的行程是香港海洋公园。早晨先到一家小店吃了港式早茶，味道和种类与内地比较相似。点一壶茶，接着就是许许多多的小点心。旁边有很多的老年人，他们看着报纸聊着天，瞬间感觉时间被拉慢了。香港的报纸挺又去，收了一份收藏。</p>
<p>虽然香港也有迪士尼，但是忌惮人流量，还是选取了人数相对较少的海洋公园。票价在美团团购大概 310 元/人。海洋公园像是各地海洋世界与游乐场的结合体。整个公园横跨两座山，坐着小列车上山，然后缆车下山，四周环海，风景一览无余。尽管已经见识过一些海洋世界，但是漆黑一片中突现的海洋场景，巨大的章鱼，凌乱的鱼群，游走的海洋生物，加上场馆偏下坡的地形，我甚至感受到一阵阵迷幻眩晕，切实有种身处海洋世界的感觉。相较于国内的设施，海洋公园感觉有点地方有些岁月的痕迹，褪色和掉漆。我们看了海豚表演，是粤语和汉语双语进行的，表演的过程中穿插了一些保护自然环境和食用本地食品的宣传，要说节目精彩吧，和看过内地的海洋表演比是触不可及，更多感觉他们注重宣传而非表演。公园里面还有一些其他动物栖息，大熊猫，树懒等等。</p>
<p>从海洋公园出来后，我们到达了位于铜锣湾附近的沙嗲王吃晚餐。点了招牌的白咖喱香茅猪扒饭，蟹粉豆腐锅饭和和沙嗲乌冬面，外加一些小食饮料。不得不说白咖喱香茅猪扒和沙嗲还是非常香的，沙嗲有点像潮汕地区的沙茶酱，嘎嘎下饭。饭后又在附近的大商场逛了逛，之后到了尖沙咀的dondondonki 买了日本零食。回程后依旧又是巨累的一天。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405142248494.jpg&amp;size=m" alt="20240514_123118.jpg"></p>
<h2 id="day4-尖沙咀美食探索-然后回程">DAY4 尖沙咀美食探索 然后回程</h2>
<p>时间过的飞快，转眼就到了回程的日子。预计下午两点左右从酒店出发去关口，于是进行最后一次美食探索，这里选择了尖沙咀附近的深仔记茶餐厅。虽然叫做茶餐厅，但是和内地形式完全不一样。我们点了叉烧虾仁滑蛋饭，芝士猪扒面，焗咖喱猪扒意面，加上特色的菠萝包和西多士，同样是香到不行。这一家明显比之前吃的冰室更加正宗。之后又去 hashtag 买了蛋挞，不得不说这蛋挞是真的大一口下去满满当当，偏甜。</p>
<p>下午回程的时候下了大雨，我们决定坐出租车从酒店返回落马洲过关口岸。豆大的雨点击打在玻璃上，不得不说老天爷还算给我们面子，虽然国庆假期南方都是雨，但起码我们逛街的时候基本晴朗。不过香港打车是真的贵，大概 27 公里的路程，加上过隧道费，行李费，大概需要将近 300 港币。过关回深圳很顺利，基本没有排队，安检也很顺利。至于回程航班，由于深圳天气有点小插曲，不过好歹还是回来了，也就不再计较了。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405142249391.jpg&amp;size=m" alt="20240514_123329.jpg"></p>
<h2 id="香港的一点感想">香港的一点感想</h2>
<h3 id="电子化支付">电子化支付</h3>
<p>香港的支付即便是内地过去也不会感觉丝毫不方便，得益于支付宝和微信的普及，你基本可以在任何稍微大一点的地方使用他它们进行支付。再退其次，可以使用 apple 或 google pay 直接开通八达通，作为本地电子化支付的最好选择，无论是地铁公交，还有一些商店，做到了一卡在手，衣食无忧。当然我们还是备了 1000 港币现金的，吃早茶的小馆子没有任何电子支付的手段，手上有点实钱还是安心。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405142249753.jpg&amp;size=m" alt="20240514_123642.jpg"></p>
<h3 id="交通趣闻">交通趣闻</h3>
<p>香港的交通给人感觉一种不太方便，但混乱中又彰显秩序。这是国内交通太方便而造成的心理落差。走在繁华的旺角尖沙咀街头，即便是在小巷没车的情况下，大多数人也不会横穿马路而是从街头巷尾经过。红绿灯不是简单的这边绿那边就红，导致虽然看起来拥挤，但交通也算比较顺畅。居住的附近有个加油站，旁边甚至有单独隔出来供行人走的羊肠小道。香港由于沿用英国式交通规则，过马路先向左看的经验会不适用，不过每条马路口都写了大大的「向左」「向右」的文字进行提示，倒也显得别有风趣。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405142306529.jpg&amp;size=m" alt="20240514_230502.jpg"></p>
<p>与之对比，我感觉内地确实很方便。这包含支付，交通，服务等等的舒适程度。但我感觉这种方便是可能建立在一定劳动廉价内卷上的来的，它们背后都是无数人的汗水和辛酸。香港遇见的大部分本地人都挺热情，各个职位上的人，他们的生活好像也不只是被工作所压迫。而且那些开车的，在便利店打工的人年纪有的也都挺高。他们是享受生活？或者为了生活而努力？不会有更年轻的人来替代他们吗？又或者香港新一代的年轻人根本看不上这些时薪与职业。时代在不断变化，我也无法用自己狭隘的目光去妄加推测。可能是由于国内发展过于迅猛，日新月异的变化在我角度看来习以为常。是先进，或者是趋势，还是说怀旧。香港汇丰银行有些网点甚至连个座位都没有，大爷大妈办理业务都是站着排队。人性化吗，肯定不人性。可能是历史遗留，可能是利益度量。无法深究其后的理由，但我充满好奇，以后也还是得多出去走走，多看看别人才能看清自己究竟是什么。</p>]]></description><guid isPermaLink="false">/archives/HongKong_journey</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202405142310969.JPG&amp;size=m" type="image/jpeg" length="1393673"/><pubDate>Tue, 14 May 2024 15:27:46 GMT</pubDate></item><item><title><![CDATA[折叠屏Fold5双屏不同桌面方案]]></title><link>https://laffitto.xyz/archives/fold-with-different-launchers</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E6%8A%98%E5%8F%A0%E5%B1%8FFold5%E5%8F%8C%E5%B1%8F%E4%B8%8D%E5%90%8C%E6%A1%8C%E9%9D%A2%E6%96%B9%E6%A1%88&amp;url=/archives/fold-with-different-launchers" width="1" height="1" alt="" style="opacity:0;">
<p>我使用三星设备偏多，从S9系列入坑，S9+，S10 5G，Tab S7+，到S22U，耳机手表还用过buds+，buds pro，watch active2和watch classic4，最近还给女票淘了个美丽小废物flip3做热点备用机。实际自折叠屏发售以来我就觊觎已久，特别是fold系列的大折叠，但奈何感觉技术不成熟，加上价格也偏贵，一直没有入手。Fold5作为三星最新屏幕终于能够完整合上的新一代折叠，戳中了我的心窝。由于自己有root的需求，fold系列唯有欧版可以轻易的解锁且能使用相机，在海鲜市场蹲候多时终于入手。天蓝色12+256，屏幕完美，边框有一点点掉漆，不过6300，还要什么自行车，带个凯夫拉壳美滋滋。</p>
<p>三星折叠最与其他品牌折叠不同的点就在于它独特的屏幕比例，折叠情况下23:9的比例，导致它握起来更像是一个遥控器。自带默认的OneUI主屏幕固然可以，在展开内屏的情况下，合理显示布局，加上自带的下面一条任务栏，使用起来非常舒适。但是合起使用外屏时，拥挤的状态不够优雅。<a href="https://play.google.com/store/apps/details?id=bitpit.launcher&amp;hl=en_US&amp;pli=1">Niagara Launcher</a>作为一个第三方启动器，其简洁的滑动字母布局和通知直接呈现提醒非常适合三星狭长的外屏。于是需求产生了，是否可以在外屏使用Niagara主屏幕，而打开内屏后自动切换为有任务栏的OneUI主屏幕呢？</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202403190009529.jpg&amp;size=m" alt=""></p>
<h2 id="思路拆解">思路拆解</h2>
<p>答案显然是可以的，Android是可以选取拿个应用作为默认启动器的。在查阅和综合了相关资料后，结合实际使用情况，这个问题的解决方案可以进一步细化为以下三个部分：</p>
<ol>
 <li>当屏幕合上，为外屏时，切换Niagara为默认主屏幕</li>
 <li>当屏幕打开，为内屏时，切换OneUI为默认主屏幕</li>
 <li>在外屏正在使用一些app时，如果此时打开为大屏幕内屏，则需要保持这些app为打开状态。即外屏转到内屏时，有些app可以无缝切换（不会返回主屏）</li>
</ol>
<p>理论上，只要手机厂商允许修改默认启动器，那么在其他牌子折叠屏上也同样可以实现。</p>
<h2 id="无root解决方案">无ROOT解决方案</h2>
<p>大多情况下，手机是没有root的，这里需要借助<a href="https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm&amp;hl=en_US">Tasker</a>和它的一个插件 <a href="https://play.google.com/store/apps/details?id=com.joaomgcd.autotools&amp;hl=en_US">AutoTools</a>。Tasker是一个自动化工具，有点类似苹果的快捷指令和三星的日常程序，不过它能够做到的东西更加广泛一些。软件可以试用，tasker建议直接入手，autotools看广告免费用。</p>
<p>tasker使用adb命令去激活read logs的功能，连接adb后，输入以下命令：</p>
<pre><code class="hljs language-shell">adb shell pm grant net.dinglisch.android.taskerm android.permission.READ_LOGS
adb shell am force-stop net.dinglisch.android.taskerm
</code></pre>
<p>之后就需要使用tasker创建对应任务和触发条件，这里引用两个其他帖子的方法（本质一样），自行配置，不重复造轮子了。</p>
<p><a href="https://xdaforums.com/t/tasker-auto-switch-launcher-for-folded-unfolded-screen.4603923/">[Tasker] Auto-switch Launcher for folded/unfolded screen</a></p>
<p><a href="https://droidwin.com/how-to-set-different-launcher-for-folded-unfolded-screen/">How to Set Different Launcher for Folded/Unfolded Screen</a></p>
<p>如果觉得配置起来有点迷糊，这里也有reddit网友给出的tasker一键导入，一共三配置，分别对应思路拆解的三个部分：</p>
<p><a href="https://www.reddit.com/r/GalaxyFold/comments/174sz3d/comment/k4qoxuq/?utm_source=share&amp;utm_medium=web2x&amp;context=3">Reddit回答 Dual Launcher Fold 5</a></p>
<p>这里分别解释一下三个配置文件</p>
<h3 id="折叠情况">折叠情况</h3>
<p>在自定义设置情况下，执行Folded这个任务。自定义设置为判断条件，edge_panel_width值为401即折叠情况下。Folded任务有以下步骤：</p>
<ol>
 <li>使用AutoTools将主屏幕设置为Niagara。</li>
 <li>返回桌面主页。</li>
 <li>设置一个变量，名称为FoldStatus，设置此时状态为CLOSED（关闭）。实际上这步可以不需要。后续可以根据这个自定义更多复杂的操作。</li>
</ol>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202403190010100.jpg&amp;size=m" alt=""></p>
<h3 id="判断需要保持打开的app">判断需要保持打开的APP</h3>
<p>在特定app打开的情况下，执行Hold Refresh这个任务；在app关闭后，执行Pause Refresh这个任务。特定app可以根据自己需要选中即可。</p>
<p>其中，Hold Refresh任务定义了一个变量，名称为PauseRefresh，并设定为1。Pause Refresh任务将PauseRefresh这个变量值进行清楚。</p>
<p>因此这个配置文件的逻辑为：在特定选中的app打开时，变量PauseRefresh被设置为1，在app关闭退出时，变量PauseRefresh变为未设置状态。这个主要是为了配合下面一个配置文件做判断。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202403190010414.jpg&amp;size=m" alt=""></p>
<h3 id="展开情况">展开情况</h3>
<p>在自定义设置情况下，执行Unfolded这个任务。自定义设置为判断条件，edge_panel_width值为362即展开情况下。UnFolded任务有以下步骤：</p>
<ol>
 <li>使用AutoTools将主屏幕设置为OneUI主屏幕。</li>
 <li>判断变量PauseRefresh是否设置，如果设置，表示选中app在前台，不做操作。如果未设置，则返回桌面，启动主屏幕。</li>
 <li>将变量FoldStatus，设置此时状态为OPENED（打开）。实际上这步可以不需要。</li>
</ol>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202403190010030.jpg&amp;size=m" alt=""></p>
<p>在导入完三个配置文件后，<strong>一定要将默认启动器设置为AutoTools</strong>，不然无效。</p>
<h3 id="小瑕疵">小瑕疵</h3>
<p>因为本质上还是借助AutoTools作为一个中间应用，去启动两个不同的桌面，AutoTools才是默认的桌面，因此有点小瑕疵：比如桌面长按应用无法使用shortcuts；手机重启后展开大屏无法显示状态栏，需要手动把默认桌面先切换回OneUI主屏幕，保证状态栏显示，再修改为AutoTools。不过这些瑕疵无伤大雅，因为99%的时间你不会去调整桌面，也不会经常去重启手机。所以体验还算舒服。</p>
<h2 id="root解决方案">ROOT解决方案</h2>
<p>不过既然我都已经root，当然要展现root的优势。主要改进就一点，使用tasker直接调用shell命令，在root的环境下切换默认桌面。这样就可以和AutoTools说拜拜了。</p>
<p>至于切换的命令，探索后发现是这个：</p>
<pre><code class="hljs language-shell">adb shell cmd package set-home-activity com.example.launcher/com.example.launcher.MainActivity
</code></pre>
<p>com.example.launcher为启动器的包名，</p>
<p>在tasker中选择将选择Autotools的命令改为运行shell命令，输入语句，例如展开时OneUI启动器：</p>
<pre><code class="hljs language-shell">cmd package set-home-activity com.sec.android.app.launcher/com.sec.android.app.launcher.MainActivity
</code></pre>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202403190011303.jpg&amp;size=m" alt=""></p>
<p>折叠时Niagara 启动器</p>
<pre><code class="hljs language-shell">cmd package set-home-activity bitpit.launcher/bitpit.launcher.MainActivity
</code></pre>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202403190011070.jpg&amp;size=m" alt=""></p>
<p>其他更改不变，这样就可以直接切换到默认的启动器，而且小瑕疵问题也解决了。</p>
<p>我图中还借助<a href="https://play.google.com/store/apps/details?id=com.pranavpandey.rotation&amp;hl=en_US">rotation</a>这个应用，实现折叠小屏强制竖屏，展开大屏强制旋转。另外我发现，用大屏情况下，转到后置摄像头自拍，且用小屏控制时会回到桌面，所以我还设置了一个变量Camera Set，检测如何变为小屏时相机打开了，那么还是再开启相机，实现一个无缝后置摄像头自拍的情况。这种设置很灵活，配合自己的需求修改就好。</p>
<h2 id="fold5简单使用体验">Fold5简单使用体验</h2>
<p>Fold5到手已经用了快10天了，我用起来还算满意。可能是这种屏幕比例，我更倾向于展开使用屏幕，真的就像在用一个小平板一样，阅读文字和漫画的体验非常舒服。自己也不是追求那么极致的拍照体验，所以从S22U换下来感觉也还好。而且折叠屏最重要的一点，我拍照的时候可以打开后置预览，这样拍人物的时候对方可以在外屏看到呈现效果，调整姿势表情。这简直感动哭了好吧，拍女朋友时候难度直接降低一个等级，增进情侣和睦的好机器呀。</p>
<p>而且8gen2真的出色，尽管Fold5只有4400毫安的电池，当感觉比我8gen1的S22U续航还要好，外出续航焦虑至少是没有了。虽然25w充电，但三星45和25w在充满时间上没太大区别，也感知不强了。</p>
<p>目前时这些，后续如果再有啥体验再补充吧。</p>
<p>自己由于是root玩家，淘一个可以轻易root且不锁相机的欧版也算是花了大功夫。最后我只建议三星你不要不识好歹，把你那针对除了欧版其他版本解锁后相机不能用的规矩给我取消了，让人能好好的玩玩机喽！</p>]]></description><guid isPermaLink="false">/archives/fold-with-different-launchers</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202403191241986.jpg&amp;size=m" type="image/jpeg" length="152233"/><pubDate>Tue, 19 Mar 2024 04:49:00 GMT</pubDate></item><item><title><![CDATA[一场朋友的婚礼]]></title><link>https://laffitto.xyz/archives/wedding_of_friend</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E4%B8%80%E5%9C%BA%E6%9C%8B%E5%8F%8B%E7%9A%84%E5%A9%9A%E7%A4%BC&amp;url=/archives/wedding_of_friend" width="1" height="1" alt="" style="opacity:0;">
<p style=""><span fontsize="" color="">2024年2月25日，我受邀去参加了高中同学的婚礼。作为这么多年还联络的朋友，外加正好是自己的生日，去参加婚礼时的心情十分开心。虽然说同学邀请了我和我的女朋友，但奈何她正好在项目上出差，只能我一个人带着她的心意去赴宴。</span></p>
<p style="text-align: start; "><span fontsize="" color="">回想起来，这还是我第一次以自己的名义去参加朋友的婚礼，虽然小的时候和老妈一起去参加过婚礼，但那都是以一种儿童的视角。以前印象中参加的婚宴都是晚上进行，而现在很多人都是中午进行婚礼，不知道这是风俗习惯的不同还是时代演化的差异。</span></p>
<p style="text-align: start; "><span fontsize="" color="">宴会厅在合肥滨湖的富茂大酒店，酒店比较红火，今天这个日子有九对新人喜结连理，据说要预定场所都得提前一年预约。酒店门前大大的粉色系花墙，喜庆中透露出温馨。同学的场子在二楼，穿过长长的电梯，婚照便呈现在眼前。比较遗憾的是，我没有与新郎新娘合照，可能是去的时候正好卡点了，和新郎说几句话后他正好要去下面拍，导致没能拍几张俊男靓女合照。</span></p>
<p style="text-align: start; "><span fontsize="" color="">一同参与婚礼的还有几位高中的同学，当然都是经常聚聚的朋友。有时候难免会感叹，这么多年还能保持联络，真的是很难得。人与人之间的关系就是在一点点失去联络之中逐渐疏远的。回想起之前还有几个经常一起上下学的同学，当时觉得关系挺不错的，但是长久没有保持联络，毕业后也就渐渐淡出生活了。</span></p>
<p style="text-align: start; "><span fontsize="" color="">桌台前有高高的花束，摆的比人都高很多。男方女方加起来大概有20多桌。同学们坐一桌，两个同学是新郎的伴郎，穿起礼服来还真是那么回事，俊得很。大家婚礼上又再起相聚，当然还是很开心的，没心没肺的拌拌嘴，唠唠嗑，调调侃，日子仿佛回到了以前。</span></p>
<p style="text-align: start; "><span fontsize="" color="">婚礼上有个小乐队，说是小乐队，主要是就只有主唱，吉他手和一个键盘手。等待的过程中，他们演唱了「你是如此的相信」，「温柔」等歌，还挺好听的。</span></p>
<p style="text-align: start; "><span fontsize="" color="">在12:18的时候，结婚仪式正式开始了，在司仪烘托完气氛后，终于等到新郎和新娘的入场。在庄重的婚礼进行曲中，在众人的欢笑注视中，在漫天气球爆开的包围中，新郎牵着新娘，缓缓地向舞台中间走去。虽然新郎之前给我们吐槽很紧张，但是我发现了，正式流程他也确实是肉眼可见的紧张。在相互宣读完誓词，父母代表发言后，大致的婚礼流程也就结束了。这里实际新郎新娘没有说太多的话，如果要在上面说很多很多的话，那真的是有点心理压力哩。</span></p>
<p style="text-align: start; "><span fontsize="" color="">在祝福完最美好的场景后，饭局开始。安徽人这边似乎对古井贡酒情有独钟，桌子上的白酒是古16，我和一个同学打开来喝了喝，应该是清香型的，喝起来不是那么上头，不容易发昏，虽然我下午回家还是去躺着睡得挺舒服就是。宴会的菜基本上有的都有，螃蟹，虾，甲鱼，石斑鱼，红烧肉等等一大桌子。大家吃吃喝喝相互敬酒和饮料，扯扯淡中时间就过去了。在新郎新娘敬完了所有桌子后，婚礼也基本上到了尾声，拿完喜糖，我们又聊了聊相互祝福后基本上就离场了。</span></p>
<p style="text-align: start; "><span fontsize="" color="">这次去参加婚礼，不仅仅是去给他们送去祝福，也有一部分是想看看未来的自己。自己终将也会经历人生的这么一个过程，结婚是一件重要的事，也是个麻烦事。这些东西的选购，场地预定，相互沟通等等都要花费大量的精力。不过参加朋友的婚礼，也能给我带来一些经验的积累。小时候的我看的更多是热闹，吃的更多是喜糖，现在的我看着红毯上的他们，也会带入自己和女朋友的情境，吃着生活这道酸甜苦辣并存的菜，憧憬着美好的未来。</span></p>]]></description><guid isPermaLink="false">/archives/wedding_of_friend</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202402252134609.jpg&amp;size=m" type="image/jpeg" length="1312878"/><pubDate>Sun, 25 Feb 2024 13:34:00 GMT</pubDate></item><item><title><![CDATA[2023年度总结]]></title><link>https://laffitto.xyz/archives/2023review</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=2023%E5%B9%B4%E5%BA%A6%E6%80%BB%E7%BB%93&amp;url=/archives/2023review" width="1" height="1" alt="" style="opacity:0;">
<p>2023年已然过去，惯例还是需要总结一下一年的过程。</p>
<p>总体来说今年的状态不算满意，因为生活的主轴并没有步入正轨，从而进入一种混沌的浑浑噩噩状态。我将通过去年的Flag一一对应今年的收获。</p>
<h2 id="职业发展">职业发展</h2>
<p>这是最大的硬伤，自从一月份离职回家后，由于各种原因一直也没有再全职工作。这就产生一种巨大的落差，没有一种稳定收入与投入的事情。虽然自己兼职也接了一些项目，也有一部分的收入，但是那终究不能作为全部。职业技能方面，虽然一直没有拉下，没有太大的退步，但是看待事物难免会眼界落于局限之中，最新最潮的事物肯定弄不明白，也没有那个自制力去弄。</p>
<h2 id="财务状况">财务状况</h2>
<p>目前并没有房子和车子之类负债资产。但是由于没有稳定的收入，投资方面也暂时停下了脚步。从目前自己的投资看来，经过这几年的实验，确实发现市场是一个起起落落的过程。今年的行情尤其不好，投资一片绿油油，不过这个本身就是个过程，顺其自然不断改变吧。投资的理念学习不足，还是需要多读书。</p>
<p>财务的记录方面记账基本坚持了下来，通过小星记账完美的记录了自己的每一笔支出，能明确的看到自己每一步前都花在了哪里。过程是有所收获的，记账是一个长期的过程，未来有了更多的资产，开源节流，才能不断积攒财富。虽然住在家里，但是花费还是不少。设备上主要是增加了一台台式机，用于跑跑代码。其他零零散散软件支出也不少，不过由于有明确的账单，明年重新调整预算还是有所依据的。</p>
<h2 id="信息输出">信息输出</h2>
<p>这一年自己的记录方面基本确定了下来。个人笔记以Obsidian本地为主，Notion表格线上为辅。滴答清单作为轻量级的记录主力使用。之前总是在不同的应用间换来换去，现在越来越趋于简单化。基本形成了一套记录体系，软件如果不出意外的话不会太换了。</p>
<p>输出方面，长篇文章用博客记录，短篇想法用memos表达，除了软件更新，基本上也不想再折腾了。但是落实到今年具体的细节，输出的内容还是太少了，尽管很多时候有很多想法，但是都没有及时的记录进行反思。博客只更新了8篇，一月一篇都没有做到，memos也分享了才大概40个。基本处于想到这东西才去做。这个流程和心理的负担还是需要减少，逼着自己进行输出。因为这些对于自己也是一种回首与反思。</p>
<h2 id="自我实现">自我实现</h2>
<p>这一部分基本没有完成，大部分的精力被奶头乐所消耗，没有充足的动力让我去执行。但是我渐渐也发现自己似乎可以并不用把全部的注意力集中在一件事上也可以大致的完成内容，或许需要从某些细节上验证这个问题。不过注意力分散和好奇心有点消退确实是个问题，需要好好调整。</p>
<p>不过今年还是读了几本书的，也算有点收获。游戏方面，单机游戏玩了王国之类，艾尔登法环，杀戮尖塔等等，联机游戏中，游戏王大师决斗，皇室战争等，都带我领略了电子游戏的魅力。</p>
<h2 id="个人健康">个人健康</h2>
<p>睡觉作息方面，尽管在家里，但是整体的作息还是比较规律的。日常起床，吃饭，基本可以保证正常的日常生活与学习。</p>
<p>身体健康方面，中途有四个月根据b站的课程进行健身，肌肉量有所增长，不过最近天冷了又有所懈怠。但是最近发现明显腰痛，这说明最近明显缺少锻炼，锻炼还是要融入生活中，成为习惯才能坚持下去呀。</p>
<p>心理精神方面，由于直接的压力较小，还是比较愉悦的，而且现在遇到问题好像不会特别着急，仿佛知道急也没有用，如何解决才是硬道理，似乎心智有一些提升。</p>
<h2 id="家庭朋友">家庭朋友</h2>
<p>在这个方面，由于时间比较充足，和女朋友约会了35次，和朋友相聚了14次，和家人聚餐了19次，外地出行了5次。这点我还是比较满意的，能够有较多的时间陪陪家人，陪陪朋友，看看世界还是很不错的。</p>
<p>自己也快27岁了，这几年也算是非常重要的黄金时间，今年的日子不算好，有很重要的事情没有推进。时间不等人，自己不能懈怠。我每周都会根据清单做一个简单的复盘，所以明白今年在一日一点点过后后的无奈与焦虑。明年真的需要更加努力了。希望明年回顾后能看到更优秀的自己。</p>]]></description><guid isPermaLink="false">/archives/2023review</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312312316053.webp&amp;size=m" type="image/jpeg" length="11528"/><pubDate>Sun, 31 Dec 2023 15:20:00 GMT</pubDate></item><item><title><![CDATA[迪士尼之旅]]></title><link>https://laffitto.xyz/archives/Disneyland</link><description><![CDATA[<img src="https://laffitto.xyz/plugins/feed/assets/telemetry.gif?title=%E8%BF%AA%E5%A3%AB%E5%B0%BC%E4%B9%8B%E6%97%85&amp;url=/archives/Disneyland" width="1" height="1" alt="" style="opacity:0;">
<p>女朋友说，迪士尼是世界上最快乐的地方。尽管她已经去过两次上海迪士尼了，但是我们两个一起去倒是未体验过。正好上迪的疯狂动物城园区也正式开幕了，安排好一切事项后，28号开启一趟轰轰烈烈的迪士尼之旅。</p>
<p>用女朋友的话讲，这是她最晚的一次进园。选定的酒店离园区不远，尽管我们6点就已经起床，在洗漱，化妆，吃早饭完毕后不知不觉已经7点半了。打车到迪士尼的地铁口，拿到网上租借的达菲发箍，差不多已经8点多了。虽然八点半才正式开园，但是从此刻开始，一天的奔跑计划就已然拉开序幕！</p>
<p>远远望去，人山人海，为了能够更快一点入园，我被拽着穿过一波又一波的人流。真正排队入园后，大概8点50，外加满头大汗。迪士尼的官方app可以看到地图和各个项目的大致排队入园时间，我们没有犹豫选择最新开的疯狂动物城作为初始目标。经过整整4个大棚的排队后，终于在10点多一点进入了动物城的园区内。整个动物城还原了很多动画中的元素，豹警官，牛局长，充满俏皮可爱。动物城警局，动物城监狱，场景惟妙惟肖。项目「热力追踪」不算刺激，但是绝对精彩，大屏幕的震撼仿佛身临其境，在动画世界中。城中还有很多奇妙的小景点，比如小动物红绿灯，巨大座椅，迷你乐器店等等，还是非常有趣的。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311405534.jpg&amp;size=m" alt=""></p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311405839.jpg&amp;size=m" alt=""></p>
<p>拍拍照出来疯狂动物城园区大概快12点了，正好到了花车巡游的时候，伴随着振奋人心的乐曲，浩浩荡荡的队伍缓缓走来。疯狂动物城，玩具总动员，小飞象，美女与野兽，海底总动员，冰雪奇缘等各路IP都出来亮相，还有他们招牌的各种动画角色，唐老鸭，小熊维尼，玲娜贝儿，达菲等等。这些人物和场景浩浩荡荡的从你眼前经过时，会让你瞬间进入他们营造的世界中，不经意的嘴角上扬。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311406492.jpg&amp;size=m" alt=""></p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311406560.jpg&amp;size=m" alt=""></p>
<p>出来后由于没赶上预约米奇妙游童话书内容，先去排队玩了加勒比海盗，不过内容与剧情不能说是一模一样，只能说是毫不相关。结束差不多快2点了，终于去迪士尼小镇炫完了中午饭。15点左右终于看上了预约的米奇妙游童话书，这个类似于舞台剧，整体场景还是十分迷幻的，虚实结合，配合表演者的演唱和舞蹈共同呈现。一开始我还以为是对嘴型，结果原来真的是在唱，Let it go响起时鸡皮疙瘩起立。整体大概30min，质量上乘。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311407974.jpg&amp;size=m" alt=""></p>
<p>后续又七零八落的把各个项目都排队玩了一遍。排队的过程是痛苦与漫长的，平均大概排队一个小时，爽一小会儿，创极速光轮，抱抱龙冲天赛车，七个小矮人矿山车。当然还玩了一些休闲小场景，旋转木马，旋转疯蜜罐等等。过程中感觉自己的腿已经不是自己的了，走路不可怕，怕的是站着老半天不动。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311407806.jpg&amp;size=m" alt=""></p>
<p>在排排等等玩玩后，时间来到了21点，这时最大也是最值得的内容开始了：灯光烟火秀。激昂的歌曲加上变换的场景，灯光投射出斑斓的效果，喷泉交相辉映，甚至在空中映射出虚幻的场景。在不同的IP变换后，巨大的烟火腾空而起，在城堡上方绽放开来，场景震撼且令人着迷。之前我一直以为烟火是重点，看过不少的视频，也看过几次户外烟火表演，然而真正体验过才发现，迪士尼将灯光与烟火结合，加上音乐与喷泉，配合着自己的主题内容一切显得浑然得体。百闻不如一见的明确诠释了。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311407076.jpg&amp;size=m" alt=""></p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311408847.jpg&amp;size=m" alt=""></p>
<p>烟火结束后，这场旅途也接近了尾声，我们去商店逛逛买了达菲后，22点左右离开了园区。一天下来，筋疲力尽，浑身大汗，腰酸脚痛，最后到酒店后有根筋都差点抽了。虽然很累，但是一整天下来也玩到了很多的项目很充实。女朋友说这是世界上最快乐的地方，确实，来到这里你可以抛弃一切的烦恼去享受。我最喜欢的还是花车巡游与灯光烟火，其他自家IP的项目也令人充满喜悦，相较于一些令人肾上腺素飙升的刺激项目，这些在其他地方都无法体会到的独一无二梦幻时刻。另外，与重要的人共同享受这份快乐，创造美好回忆，这也是这趟旅程更重要的事吧。</p>
<p><img src="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311410260.jpg&amp;size=m" alt=""></p>]]></description><guid isPermaLink="false">/archives/Disneyland</guid><dc:creator>Laffitto</dc:creator><enclosure url="https://laffitto.xyz/apis/api.storage.halo.run/v1alpha1/thumbnails/-/via-uri?uri=https%3A%2F%2Fpicgo-1306089623.cos.ap-nanjing.myqcloud.com%2F202312311637035.jpg&amp;size=m" type="image/jpeg" length="270318"/><pubDate>Sun, 31 Dec 2023 08:44:00 GMT</pubDate></item></channel></rss>