<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/css" href="/assets/css/rss.css" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>GeekPie Posts</title>
    <link>https://geekpie.club</link>
    <description>GeekPie_ 的 RSS 订阅源，包含了最新的帖子和活动。订阅我们，探索我们的最新动态和技术分享！ <br/> GeekPie_ 是一个立足于技术的综合性科创社团，屡获殊荣。方向覆盖人工智能、高性能计算、硬件与软件工程、计算机系统与安全、理论与算法、芯片设计等。实际上很难用简单的标签概括我们，我们是一个秉承开源与合作理念，不断追求思想进步和技术前沿的学生组织。</description>
    
    <item>
      <title>[GeekPie blog] OpenClaw 安全总结：供应链攻击、配置指南与安全指引</title>
      <author>Henry</author>
      <link>https://geekpie.club/posts/blog/2026-03-15-openclaw-safety</link>
      <guid>https://geekpie.club/posts/blog/2026-03-15-openclaw-safety</guid>
      <pubDate>Sun, 15 Mar 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[本文将结合 OpenClaw 历史上著名的供应链攻击事件，以及北京大学计算中心最新发布的安全指引，为您详细梳理 OpenClaw 的安全风险及最佳实践。]]></description>
      <content:encoded><![CDATA[<p>OpenClaw 作为一款功能强大的开源 AI 智能体，极大地提升了我们的工作效率，但其引发的安全问题也不容忽视。本文将结合 OpenClaw 历史上著名的「ClawHavoc」供应链攻击事件，以及北京大学计算中心最新发布的<a href="https://its.pku.edu.cn/announce/tz20260310195800.jsp">安全指引</a>，为您详细梳理 OpenClaw 的安全风险及最佳实践。</p>
<h2 id="一重大安全事件回顾clawhavoc-供应链攻击">一、重大安全事件回顾：ClawHavoc 供应链攻击</h2>
<p>ClawHavoc 供应链攻击是 OpenClaw 历史上最严重的安全事件之一，每个「养虾人」都必须引以为戒。</p>
<h3 id="时间线">时间线</h3>
<table>
<thead>
<tr>
<th>日期</th>
<th>事件</th>
</tr>
</thead>
<tbody>
<tr>
<td>1月27日</td>
<td>首个恶意 Skill 出现在 ClawHub 上，伪装成专业工具</td>
</tr>
<tr>
<td>1月28-30日</td>
<td>攻击者快速上传大量恶意 Skill，利用 ClawHub 缺乏审查机制的漏洞</td>
</tr>
<tr>
<td>1月31日</td>
<td>攻击全面爆发，多名用户报告异常行为</td>
</tr>
<tr>
<td>2月1日</td>
<td>Koi Security 正式命名该攻击为「ClawHavoc」</td>
</tr>
<tr>
<td>2月上旬</td>
<td>社区展开大规模审计和清理</td>
</tr>
</tbody>
</table>
<h3 id="攻击规模">攻击规模</h3>
<p>当时 ClawHub 技能总数约为 2,857 个，初步确认恶意 Skills 341 个（约 12%），后续扫描发现的恶意 Skills 超过 800 个（约 20%）。其中可追溯到同一协调行动的达 335 个，受影响设备超过 135,000 台。这意味着当时随机安装 5 个 Skill，大概率至少有 1 个是恶意的。</p>
<h3 id="攻击手法">攻击手法</h3>
<p>攻击者的手法相当精密：</p>
<ol>
<li>上传看似专业的 Skill，名称和描述都很正常（如 <code>advanced-code-review</code>, <code>smart-scheduler</code>）。</li>
<li>诱导用户安装后，Skill 会建议安装一个「helper agent」来增强功能。</li>
<li>实际植入的是 Atomic macOS Stealer（AMOS）信息窃取木马。</li>
<li><strong>更危险的是：</strong> 攻击专门针对 OpenClaw 的持久记忆文件（<code>SOUL.md</code> 和 <code>MEMORY.md</code>），篡改 Agent 的长期行为指令。</li>
</ol>
<p>篡改 <code>SOUL.md</code> 意味着你的 Agent 被「洗脑」了。它的核心行为准则被改写，可能在后续所有交互中执行恶意操作，而你完全不知情。</p>
<h3 id="应对建议">应对建议</h3>
<ol>
<li><strong>安装前审查源码：</strong> 永远不要盲目安装 ClawHub 上的 Skill。去 GitHub 查看源码，确认 <code>SKILL.md</code> 中没有可疑的指令。特别注意任何要求额外安装「helper」或「agent」的内容。</li>
<li><strong>使用 SecureClaw 扫描：</strong> 社区推出了开源安全工具 SecureClaw，可以扫描已安装的 Skills 检查恶意内容。
<pre><code class="language-bash"># 安装SecureClaw
npm install -g secureclaw

# 扫描已安装的skills
secureclaw scan ~/.openclaw/skills/
</code></pre>
</li>
<li><strong>优先使用精选列表：</strong> 参考 <a href="https://github.com/VoltAgent/awesome-openclaw-skills">awesome-openclaw-skills</a> 项目（近 31.4K Stars）的精选列表，过滤掉大量垃圾和恶意 Skill。</li>
<li><strong>定期检查记忆文件：</strong> 养成习惯，定期检查 <code>SOUL.md</code> 和 <code>MEMORY.md</code> 有没有被异常修改。</li>
</ol>
<p><strong>关键认知：</strong> OpenClaw 的 Skill 本质上是受信任代码。一旦安装，它就拥有和你的 OpenClaw 实例相同的权限。没有沙箱隔离，没有权限分级。这和 npm 生态早期面临的问题一模一样，但后果可能更严重，因为 OpenClaw 可以访问你的邮件、日历、消息和文件系统。</p>
<hr>
<h2 id="二全面风险排查清单">二、全面风险排查清单</h2>
<p>根据北京大学计算中心在 2026 年 3 月 10 日发布的<a href="https://its.pku.edu.cn/announce/tz20260310195800.jsp">安全指引</a>，OpenClaw 在缺乏有效安全控制的情况下存在四大核心风险：默认无身份认证、存在远程代码执行漏洞（CVE-2026-25253）、第三方技能供应链攻击（如上述的 ClawHavoc）以及 API 密钥明文存储。</p>
<p>以下是详细的安全配置最佳实践与排查清单：</p>
<h3 id="1-api-密钥安全与身份认证">1. API 密钥安全与身份认证</h3>
<p>绝对不要将 API 密钥明文存储在代码中或提交到公开仓库。</p>
<p><strong>正确做法：</strong></p>
<ul>
<li><strong>使用环境变量：</strong> <code>export OPENAI_API_KEY="sk-xxx"</code></li>
<li><strong>设置文件权限：</strong> <code>chmod 600 ~/.openclaw/config.json</code></li>
<li><strong>配置 Git 忽略：</strong> <code>echo ".openclaw/config.json" >> .gitignore</code></li>
<li><strong>定期轮换密钥：</strong> 建议每 3 个月更换一次。</li>
<li><strong>启用身份认证：</strong> 在配置文件中添加强认证 Token：
<pre><code class="language-json">{
  "gateway": {
    "auth": {
      "token": "你的至少32位强随机字符串"
    }
  }
}
</code></pre>
</li>
</ul>
<h3 id="2-排查公网暴露与网络安全配置">2. 排查公网暴露与网络安全配置</h3>
<p>千万不要让未启用认证的实例暴露在公网，并利用防火墙或网关配置限制访问。</p>
<ul>
<li><strong>排查暴露：</strong> 检查默认端口 18789 是否监听在 <code>0.0.0.0</code>
<ul>
<li>Linux: <code>ss -tlnp | grep 18789</code></li>
<li>macOS: <code>lsof -i :18789</code></li>
<li>Windows: <code>netstat -ano | findstr ":18789"</code></li>
</ul>
</li>
<li><strong>限制本地访问：</strong> 修改配置仅监听本地：
<pre><code class="language-json">{
  "gateway": {
    "mode": "local",
    "port": 18789, 
    "bind": "loopback",
    "allowIPs": [
      "127.0.0.1",
      "192.168.1.0/24"
    ],
    "ssl": {
      "enabled": true,
      "cert": "/path/to/cert.pem",
      "key": "/path/to/key.pem"
    }
  }
}
</code></pre>
</li>
</ul>
<h3 id="3-数据隐私与文件访问控制">3. 数据隐私与文件访问控制</h3>
<p>不要在 OpenClaw 中存储或处理极度敏感的信息（如密码、银行卡）。</p>
<p><strong>配置数据脱敏与路径限制：</strong></p>
<pre><code class="language-json">{
  "privacy": {
    "enabled": true,
    "rules": [
      { "type": "phone", "action": "mask", "pattern": "\\d{11}" },
      { "type": "email", "action": "mask" },
      { "type": "idcard", "action": "block" }
    ]
  },
  "files": {
    "allowPaths": [
      "~/Documents/OpenClaw",
      "~/Desktop"
    ],
    "denyPaths": [
      "~/.ssh",
      "~/Documents/Private",
      "~/Documents/Finance",
      "~/Documents/Medical"
    ]
  }
}
</code></pre>
<h3 id="4-最小权限原则与防范-xss-劫持">4. 最小权限原则与防范 XSS 劫持</h3>
<ul>
<li><strong>警惕不明链接：</strong> CVE-2026-25253 漏洞允许攻击者通过恶意网页劫持本地 OpenClaw 会话，只需在浏览器中打开链接即可触发。对来源不明的链接务必保持警惕。</li>
<li><strong>低权限运行：</strong> 绝对不要以 <code>root</code> 或管理员身份运行 OpenClaw，为其分配专用的低权限账户。</li>
</ul>
<h3 id="5-审计日志与备份策略">5. 审计日志与备份策略</h3>
<p>开启日志记录，并利用 v2026.3.8 新增的备份工具保障数据安全。</p>
<ul>
<li><strong>启用审计：</strong>
<pre><code class="language-json">{
  "audit": {
    "enabled": true,
    "logLevel": "info",
    "logFile": "~/.openclaw/logs/audit.log",
    "retention": 90
  }
}
</code></pre>
</li>
<li><strong>检查日志：</strong> 定期执行 <code>tail -n 100 ~/.openclaw/logs/audit.log</code> 等命令检查是否有异常的 <code>delete</code> 或 <code>upload</code> 操作。</li>
<li><strong>合理备份：</strong>
<pre><code class="language-bash"># 创建、验证与恢复备份
openclaw backup create
openclaw backup verify &#x3C;backup-file>
openclaw backup restore &#x3C;backup-file>
</code></pre>
建议每周自动备份，重要操作前手动备份，并定期测试恢复流程。</li>
</ul>
<hr>
<p>安全无小事。作为一个迅速发展的开源项目，OpenClaw 为我们带来便利的同时也伴随着风险。请务必养成定期更新、审查代码、最小化权限和定期备份的良好习惯。</p>]]></content:encoded>
      <category>blog</category>
      <category>OpenClaw</category>
<category>安全</category>
    </item>
    <item>
      <title>[GeekPie blog] GeekPie 成员勇夺小红书 48 小时黑客松软件赛道一等奖！</title>
      <author>GeekPie</author>
      <link>https://geekpie.club/posts/blog/2026-04-10-redhackathon</link>
      <guid>https://geekpie.club/posts/blog/2026-04-10-redhackathon</guid>
      <pubDate>Sun, 15 Mar 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[由小红书举办的黑客松巅峰赛于 4 月 10 日落幕。由 GeekPie 前任社长贺泽邦和 DataTech（原 GeekPie 数据科学方向）社长洪沐天及他们的团队开发的 ChicChic 夺得软件赛道一等大奖及 50000 元奖金。]]></description>
      <content:encoded><![CDATA[<h2 id="48-小时能做什么">48 小时能做什么？</h2>
<p>2026 年 4 月 10 日，由小红书举办的 <strong>“2026 小红书黑客松巅峰赛”</strong> 圆满落幕。由信息学院两大科技社团的领军人物—— GeekPie 前任社长 <strong>贺泽邦</strong> 和 DataTech（原 GeekPie 数据科学方向）社长 <strong>洪沐天</strong> 及他们的团队“当理发遇上 Token 上限”开发的 ChicChic 夺得软件赛道一等大奖，并囊获 50000 元奖金。这也是 GeekPie 再一次在全国性黑客松拿下头筹奖金。</p>
<p><img src="2026-redhackathon-final.jpeg" alt="2026 小红书黑客松巅峰赛颁奖现场，由 Monolith 创始人曹曦（左一）颁奖。贺泽邦（左二）、洪沐天（右一）及队长余亮（右二）上台领奖"></p>
<p>本次黑客松巅峰赛是小红书科技薯主办的第一次黑客松，此届更是有超过 62% 的 00 后选手同台竞争。来自五湖四海的开发者齐聚一堂，在 48 小时的严格限制下，不许提前制作，从零开发一个完整的 MVP 并由各大评委打分。其中软硬件赛道的前五可以前往决赛进行最终的路演并角逐巨额奖金。</p>
<h2 id="什么是黑客松">什么是黑客松？</h2>
<p>“黑客松”这个词，源于英文 Hackathon，是黑客 Hacker 和马拉松 Marathon 的结合。它不仅是程序员写代码，更是世界上最酷、最硬核的脑力极限运动。</p>
<p>黑客松的基本模式，是由几百名顶尖极客，在一个巨大的封闭空间里，在连续的 24 小时、48 小时等时间限制内，从0到1，把一个天马行空的想法，变成一个能跑能用的产品Demo。除了热衷钻研技术的软件工程师，参与黑客马拉松的还有来自各种风投公司、初创公司和互联网大厂的团队。最早的黑客马拉松距今已有超过 20 年历史，如今，这一活动已经从极客圈的小众活动逐渐变成了一种广泛的创新的文化象征，是人类创新智斗的巅峰对决。</p>
<h2 id="geekpiedatatech-与黑客松">GeekPie/DataTech 与黑客松</h2>
<p>作为上海科技大学最大的科技社团，<a href="https://geekpie.club">GeekPie</a> 早就与黑客松深深的绑定在了一起。早在 2016 年，GeekPie 社团创始人吕文涛等本科生就曾代表上科大在黑客松取得佳绩。黑客松动辄数万元的奖金，成为了 GeekPie 一代又一代成员赚取“零花钱”的生活回忆。</p>
<p><img src="/posts/blog/2026-04-10-redhackathon/geekpie-2016.png" alt="2016 年，GeekPie 团队（吕文涛、袁蕴哲、刘永豪、周杨）凭借 Nearby 夺得 i-Lab &#x26; 微软黑客松二等奖"></p>
<p><img src="/posts/blog/2026-04-10-redhackathon/geekbeta-2016.png" alt="2016 年，GeekBeta 团队（石嘉禾、谢志强、夏寅岑、张家健、曹逸凡）凭借 Angry Trash Bin 获得三等奖"></p>
<p><a href="https://www.datatech.club">DataTech 社团</a> 由前 GeekPie 数据科学方向孵化而来，由 GeekPie 社员、22 届本科生洪沐天创立。早在 GeekPie 时期，团队就获得 ADIA Lab 因果发现挑战赛第三名。至今短短几年的创立时间却也已包揽各大奖项，游走于 kaggle 等知名数据科学竞赛中。</p>
<p><img src="/posts/blog/2026-04-10-redhackathon/datatech-deep-past.png" alt="DataTech 社团荣获 Kaggle Deep Past Challenge - Translate Akkadian to English 冠军"></p>
<p>社团的发展也与学院的支持密不可分，依托上海科技大学信息学院，GeekPie / DataTech 社团拥有充足的算力资源可供自由调度，社团成员申请即可使用，这也大大增强了社团在各大科学研究、超算比赛和数据科学竞赛上的积极性与活跃度。本次小红书竞赛中，社团也充分利用了学校的高性能 GPU 资源，在此之上搭建了 ChicChic 的发丝建模到发型迁移的整套工作流，为创新能力的施展提供了充分的平台和资源保障。</p>
<h2 id="chicchic做用户和-tony-老师之间的-google-translate">ChicChic，做用户和 Tony 老师之间的 Google Translate</h2>
<p>“理发就是 VibeCoding，和 Tony 老师永远要解释半天，就像抽卡一样……”</p>
<p>这一次，两位社长创造性地将理发的痛点发掘，并结合了二位各自领域擅长的技能点，在团队中成为了不可或缺的中坚力量。</p>
<p>GeekPie 前社长贺泽邦，同时也是 GeekPie_HPC 超算队队长、GeekPie_404 前后端团队首席负责人，创造性地将前后端开发经验与超算的集群维护及调度经验结合，负责了本次应用开发的后端开发、Workflow 搭建、集群管理，并实现了 ComfyUI 的多卡调度和并行算法。</p>
<p>DataTech 社长洪沐天，则发挥数据科学的专长，在数小时内复现了 GaussianHaircut 的部分功能的同时，训练了专属于发型的识别和机器学习推荐系统。在本次应用开发中扛起了算法工程师的大旗。</p>
<p><img src="/posts/blog/2026-04-10-redhackathon/chic-chic.jpeg" alt="ChicChic 荣获本次软件赛道一等奖（图片来源：科技薯）"></p>
<p>创新永不过期，真爱不会变质。未来 GeekPie 与 DataTech 将继续带领社团角逐各类黑客松，驰骋更多的赛场，留下上海科技大学的辉煌旗帜！</p>
<p><img src="/posts/blog/2026-04-10-redhackathon/2026-end.jpeg" alt="图为 2026 年 4 月 10 日零点，团队击鼓鸣金，宣告 48 小时开发结束"></p>]]></content:encoded>
      <category>blog</category>
      <category>GeekPie</category>
<category>DataTech</category>
<category>黑客松</category>
<category>Hackathon</category>
<category>小红书</category>
    </item>
    <item>
      <title>[GeekPie blog] GeekPie Day 极客派对 2026</title>
      <author>Henry</author>
      <link>https://geekpie.club/posts/blog/2026-03-13-piday</link>
      <guid>https://geekpie.club/posts/blog/2026-03-13-piday</guid>
      <pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[赴一场春日之约！硬核与美味交织，GeekPie Pi Day 极客派对活动]]></description>
      <content:encoded><![CDATA[<p>3月13日下午2点，初春的暖阳正好。8号楼科道庭院里早已人头攒动，由极客社团 GeekPie 为大家准备的 Pi Day 极客派对如约而至。</p>
<p>GeekPie 是一群热爱技术、崇尚创新的同学共同组成的科技社团，致力于让校园内的大家都能体会到科技带来的便利。而圆周率 $\pi$（Pi）不仅是数学中最经典的常数，也是理工科学生心中独特的浪漫符号。为了庆祝这个属于极客的节日，GeekPie 特意将硬核的科技互动与轻松的美食结合，将传统节日打造成了一场校园专属的“极客游园会”。</p>
<p>不同于传统的游园会，当天的活动不仅带来了社团极具科技风格的硬核互动，还为大家准备了美味的免费小食（Pie）。师生们穿梭在各个点位间，在这个春日下午玩得不亦乐乎，让庭院里充满了轻松与欢乐。</p>
<p><strong>PART.1</strong>
<strong>全民算力与电子投针</strong></p>
<p>在 “Distributed Pi” 展区，现场的大屏实时滚动着一个由大家共同搭建的算力统计图表。只要打开手机或电脑加入，就能领到一个专属的数字区间，用自己的设备为圆周率的计算贡献一份算力。许多同学都在这留下属于自己的一笔。</p>
<p>而在另一边的布丰投针实验区，大家熟悉的经典概率学实验被搬上了屏幕。同学们纷纷在电脑前按动按钮比拼手速，通过快速点击进行模拟投针，用蒙特卡洛方法一点点逼近真正的 Pi 值，原本枯燥的推演在现场变成了一场欢乐的手速竞技。</p>
<p><img src="/posts/blog/2026-03-13-piday/Buffons-needle-problem.jpeg" alt="同学们热情参与互动"></p>
<p><strong>PART.2</strong>
<strong>徒手画圆与 AI 编曲</strong></p>
<p>除了计算挑战，现场的互动游戏队伍排得更长。比如“徒手画圆挑战”就要求大家不借助任何工具，直接在屏幕上一笔画出一个尽可能圆的图形。系统精准的自动打分配合周围同学的围观欢呼，让大家都跃跃欲试，想要刷新当天的排行榜。</p>
<p><img src="/posts/blog/2026-03-13-piday/draw-circle.JPG" alt="同学们围在画圆挑战前"></p>
<p>而全场最高人气的还要数 “Vibe Cod'in Pie” 区域了，大家可以现场当一回极客 DJ。只要扫码输入“让节奏快一点”或者“加一点赛博朋克感的贝斯”，这套实时电子乐系统就会在几秒钟内把自然语言转换成代码，并在大屏上播放出来。不少书院的老师也被这种新奇的玩法吸引，加入扫码发弹幕的队伍，和同学们一起跟着节拍感受 AI 编曲的乐趣。</p>
<p><img src="/posts/blog/2026-03-13-piday/vibecodinpie.JPG" alt="Vibe Cod&#x27;in Pie 活动"></p>
<p><strong>PART.3</strong>
<strong>吃派算派，暖心相聚</strong></p>
<p>玩得尽兴了，当然也少不了今天的主角——麦当劳派。</p>
<p>领派的摊位前，排队的身影蜿蜒成了长龙。大家领到了香芋或菠萝口味的麦当劳派后，三五成群地在冬去春来的暖阳下围坐闲聊。“吃派算派”，平时课业的紧张与忙碌，都在这庭院的欢声笑语中被轻松化解。</p>
<p><img src="/posts/blog/2026-03-13-piday/mcdonald-pie.jpeg" alt="香芋派 &#x26; 菠萝派 发放"></p>
<hr>
<p>从一起共享设备算力，到师生同乐的 AI 打碟和画圆挑战，GeekPie 用充满科技感的设计，为书院的师生带来了一个既硬核又好玩的下午，让师生真切感受到了科技带来的纯粹乐趣和同乐的温情。期待未来能在书院碰撞出更多好玩又有料的相聚！</p>]]></content:encoded>
      <category>blog</category>
      <category>GeekPie</category>
<category>Pi</category>
<category>PiDay</category>
<category>极客派对</category>
    </item>
    <item>
      <title>[GeekPie blog] macOS 环境下 OpenClaw 完全部署与配置教程</title>
      <author>Henry</author>
      <link>https://geekpie.club/posts/blog/2026-03-10-openclaw-macos</link>
      <guid>https://geekpie.club/posts/blog/2026-03-10-openclaw-macos</guid>
      <pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[本文记录了在 macOS 环境下安装 OpenClaw 的完整过程，包含 Homebrew 自动化安装、Node.js 环境配置、Gateway 服务启动，以及常用命令和插件管理的详细步骤。]]></description>
      <content:encoded><![CDATA[<p><a href="https://geekpie.club/posts/blog/2026-03-09-openclaw/">Windows 安装教程点我</a>
OpenClaw 是一款强大的开源 AI Agent 工具，相比 Windows 环境，macOS 的安装体验更加流畅，得益于 Homebrew 包管理器的自动化支持。本文将详细记录在 macOS 上从零开始安装、配置 OpenClaw 的完整流程。</p>
<hr>
<h2 id="一环境准备">一、环境准备</h2>
<h3 id="1-系统要求">1. 系统要求</h3>
<ul>
<li>macOS 10.15 或更高版本（本教程基于 macOS 15.4.1）</li>
<li>已安装 Homebrew 包管理器</li>
<li>稳定的网络连接</li>
</ul>
<h4 id="如何查看自己的-macos-版本">如何查看自己的 macOS 版本？</h4>
<ol>
<li>打开终端（也叫Terminal）</li>
</ol>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/terminal.png" alt="终端图片"></p>
<ol start="2">
<li>输入<code>sw_vers</code>并回车，<code>ProductVersion</code>后的即为版本号</li>
</ol>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/macos-version.png" alt="版本号"></p>
<h3 id="2-检查-homebrew">2. 检查 Homebrew</h3>
<p>如果尚未安装 Homebrew，请先访问 <a href="https://brew.sh/">brew.sh</a> 安装，或在终端执行：</p>
<pre><code class="language-bash">/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
</code></pre>
<p>验证 Homebrew 安装：</p>
<pre><code class="language-bash">brew --version
</code></pre>
<hr>
<h2 id="二一键安装-openclaw">二、一键安装 OpenClaw</h2>
<h3 id="1-执行官方安装脚本">1. 执行官方安装脚本</h3>
<p>OpenClaw 提供了针对 macOS 优化的安装脚本，会自动处理 Node.js 版本升级和依赖安装。在终端中执行：</p>
<pre><code class="language-bash">curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash
</code></pre>
<h3 id="2-安装过程说明">2. 安装过程说明</h3>
<p>安装脚本会自动完成以下步骤：</p>
<ol>
<li><strong>检测系统环境</strong>：识别 macOS 系统并选择合适的安装方式</li>
<li><strong>安装 Node.js v22</strong>：通过 Homebrew 安装 <code>node@22</code>（OpenClaw 要求 Node.js 22+）</li>
<li><strong>安装 OpenClaw</strong>：通过 npm 全局安装最新版本</li>
<li><strong>配置环境变量</strong>：在 <code>~/.local/bin/openclaw</code> 创建启动脚本</li>
</ol>
<p>安装成功后，你会看到类似以下输出：</p>
<pre><code>🦞 OpenClaw installed successfully (OpenClaw 2026.3.8)!
Home sweet home. Don't worry, I won't rearrange the furniture.
</code></pre>
<h3 id="3-配置-path-环境变量">3. 配置 PATH 环境变量</h3>
<p>为了在任何位置都能使用 <code>openclaw</code> 命令，需要将 Node.js 22 添加到 PATH。编辑 <code>~/.zshrc</code> 文件：</p>
<pre><code class="language-bash">echo 'export PATH="/opt/homebrew/opt/node@22/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
</code></pre>
<p>验证安装：</p>
<pre><code class="language-bash">openclaw --version
</code></pre>
<p>应该输出类似：<code>OpenClaw 2026.3.8 (3caab92)</code></p>
<hr>
<h2 id="三初始化配置">三、初始化配置</h2>
<h3 id="1-执行配置向导">1. 执行配置向导</h3>
<p>首次使用需要在终端里执行：</p>
<pre><code class="language-bash">openclaw onboard --flow quickstart
</code></pre>
<p>在连续的风险提示与初始询问中：</p>
<ul>
<li>看到 <code>I understand this is powerful and inherently risky. Continue?</code>，请选择 <code>Yes</code>。</li>
</ul>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/risk-confirm-macos.png" alt="风险确认"></p>
<p>后续配置项建议按需简化（可使用最小化跑通再深层配置）：</p>
<ul>
<li><strong>模型/Model</strong>：选择所需模型，若暂未准备 API 可选 <code>skip for now</code>。</li>
<li><strong>API Keys</strong>：提供对应的 API Key (例如 Kimi、DeepSeek 或 MiniMax)，其余保持默认。</li>
</ul>
<p>下面以 MiniMax 为例获取 API Key：</p>
<ol>
<li>
<p>打开浏览器前往 <a href="https://platform.minimaxi.com/">MiniMax 开发者平台 (platform.minimaxi.com)</a>，并通过手机号快速注册/登录。</p>
</li>
<li>
<p>登录后，在页面右上角中找到并点击 <strong>账户管理</strong> ，左侧栏选择 <strong>接口密钥</strong> ，</p>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/minimax-api-keys.png" alt="MiniMax 控制台配置 API Keys"></p>
</li>
<li>
<p>点击 <strong>创建新的 API Key</strong> 或 <strong>+ 新建</strong>，给这个 Key 随意命名（比如 "OpenClaw"）并确认。</p>
</li>
<li>
<p>系统会生成一串以 <code>sk-</code> 开头的密钥。<strong>该密钥仅会完整显示一次</strong>，请务必立刻<strong>复制并妥善保存</strong>至密码管理器或安全位置，切勿发给他人。</p>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/minimax-sk-key.png" alt="获取并复制 API Key"></p>
</li>
</ol>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/api-key-config-macos.png" alt="API Key配置"></p>
<ul>
<li>
<p><strong>Select Channel/Search Provider/Skills</strong>*：可以先 <code>skip for now</code>，先验证安装完成，后续单独配置。</p>
</li>
<li>
<p><strong>Hooks</strong>：全部勾选。上下箭头选择，空格选中/取消选中，回车提交。</p>
</li>
</ul>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/hooks-config-macos.png" alt="hooks设置"></p>
<ul>
<li><strong>Hatch your bot</strong>：选择 <code>open in web ui</code>，将启动网关服务并在浏览器弹出控制台页面 <code>http://127.0.0.1:18789/</code>。控制台启动完成并可发消息回复，即代表基础运行成功。<em>(注：目前 Web UI 界面仍处于早期阶段，体验还不是很完善。对于熟悉命令行的用户，强烈推荐使用命令行交互，后续可通过终端输入 <code>openclaw tui</code> 进入。)</em></li>
</ul>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/openclaw-web-macos.png" alt="Web控制台"></p>
<p>你可以在 Web UI 中：</p>
<ul>
<li>发送消息与 AI 对话</li>
<li>查看会话历史</li>
<li>管理设备配对</li>
<li>配置模型和插件</li>
</ul>
<hr>
<h2 id="四配置-ai-模型">四、配置 AI 模型</h2>
<p>如果后续额外配置其他AI模型，可以参考以下步骤：</p>
<pre><code class="language-bash">openclaw config
</code></pre>
<p>选择<code>Local</code>→<code>Model</code></p>
<p>随后选择自己的提供商。如果没有则选择<code>Custom Provider</code>。随后同上方 初始化配置<code>API Keys</code>处所提的相同方式配置。</p>
<h3 id="验证配置">验证配置</h3>
<pre><code class="language-bash">openclaw health
</code></pre>
<h3 id="动态切换模型">动态切换模型</h3>
<p>如果需要在聊天过程中临时切换不同的 AI 模型，可以在终端使用 TUI（文本用户界面）进行操作：</p>
<ol>
<li>在终端输入 <code>openclaw tui</code> 打开命令行交互界面。</li>
<li>在对话框中输入 <code>/model</code>（或者 <code>/models</code>）并回车。</li>
<li>使用键盘的上下方向键挑选想要的模型，最后回车确认，即可切换成功。</li>
</ol>
<p><img src="/posts/blog/2026-03-10-openclaw-macos/change-model-macos.png" alt="动态切换模型"></p>
<hr>
<h2 id="五插件管理">五、插件管理</h2>
<h3 id="1-查看所有插件">1. 查看所有插件</h3>
<pre><code class="language-bash">openclaw plugins list
</code></pre>
<p>OpenClaw 内置 38+ 插件，包括：</p>
<ul>
<li>通讯平台：Telegram、Discord、Slack、飞书、微信等</li>
<li>语音功能：voice-call、talk-voice</li>
<li>内存管理：memory-core、memory-lancedb</li>
<li>其他工具：browser、diffs、lobster 等</li>
</ul>
<h3 id="2-启用插件">2. 启用插件</h3>
<p>以飞书插件为例：</p>
<pre><code class="language-bash">openclaw plugins enable feishu
</code></pre>
<h3 id="3-安装第三方插件">3. 安装第三方插件</h3>
<pre><code class="language-bash">openclaw plugins install @m1heng-clawd/feishu
</code></pre>
<hr>
<h2 id="六常用命令速查">六、常用命令速查</h2>
<h3 id="服务管理">服务管理</h3>
<pre><code class="language-bash"># 启动 Gateway
openclaw gateway

# 查看健康状态
openclaw health

# 查看实时日志
openclaw logs follow

# 重启服务
openclaw restart
</code></pre>
<h3 id="配置管理">配置管理</h3>
<pre><code class="language-bash"># 查看配置
openclaw config get

# 设置配置项
openclaw config set key value

# 删除配置项
openclaw config unset key

# 打开配置文件
openclaw config file
</code></pre>
<h3 id="诊断与修复">诊断与修复</h3>
<pre><code class="language-bash"># 运行诊断
openclaw doctor

# 自动修复问题
openclaw doctor --fix

# 查看详细日志
openclaw logs follow --level debug
</code></pre>
<h3 id="设备管理">设备管理</h3>
<pre><code class="language-bash"># 生成配对码
openclaw devices pair

# 查看已配对设备
openclaw devices list

# 打开控制台
openclaw dashboard
</code></pre>
<hr>
<h2 id="七常见问题排查">七、常见问题排查</h2>
<h3 id="1-端口被占用">1. 端口被占用</h3>
<p>如果 18789 端口被占用，可以指定其他端口：</p>
<pre><code class="language-bash">openclaw gateway --port 19000
</code></pre>
<p>或强制关闭占用进程：</p>
<pre><code class="language-bash">openclaw gateway --force
</code></pre>
<h3 id="2-nodejs-版本不匹配">2. Node.js 版本不匹配</h3>
<p>确保使用 Node.js 22：</p>
<pre><code class="language-bash">node --version  # 应显示 v22.x.x
</code></pre>
<p>如果版本不对，重新加载环境变量：</p>
<pre><code class="language-bash">source ~/.zshrc
</code></pre>
<h3 id="3-权限问题">3. 权限问题</h3>
<p>如果遇到权限错误，检查目录权限：</p>
<pre><code class="language-bash">ls -la ~/.openclaw
chmod -R 755 ~/.openclaw
</code></pre>
<h3 id="4-网络连接问题">4. 网络连接问题</h3>
<p>如果安装过程中下载缓慢，可以配置 npm 镜像：</p>
<pre><code class="language-bash">npm config set registry https://registry.npmmirror.com
</code></pre>
<p>完整文档：<a href="https://docs.openclaw.ai">https://docs.openclaw.ai</a></p>
<p>整个 macOS 环境下的 OpenClaw 部署流程到此完成。</p>
<p>—— GeekPie 社团，2026 年 3 月 10 日</p>]]></content:encoded>
      <category>blog</category>
      <category>OpenClaw</category>
<category>教程</category>
<category>macOS</category>
<category>配置</category>
    </item>
    <item>
      <title>[GeekPie event] GeekPie Day 极客派对 2026</title>
      
      <link>https://geekpie.club/posts/event/2026-03-13-piday</link>
      <guid>https://geekpie.club/posts/event/2026-03-13-piday</guid>
      <pubDate>Mon, 09 Mar 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[一年一度的 Pi Day 来临，今年我们有这些玩意儿~]]></description>
      <content:encoded><![CDATA[<p>一年一度的 Pi Day (3.14) 即将来临！今年 3 月 11 日至 3 月 13 日，GeekPie 在【科道庭院】为你准备了一场别开生面的技术“派”对。</p>
<p>不但有好吃的麦麦派免费发放，更有神秘周边礼品等你来拿，先到先得哦 🥰</p>
<h2 id="投针算-pi-">投针算 Pi 📐</h2>
<ul>
<li><strong>活动时间</strong>：3月11日 ~ 3月13日</li>
<li><strong>活动内容</strong>：经典概率实验——蒲丰投针。亲身体验如何通过随机投掷，逐步“「投」”出圆周率 $\pi$ 的奥秘。</li>
</ul>
<h2 id="vibecodinpie-">Vibecodin'Pie 🎶</h2>
<ul>
<li><strong>活动时间</strong>：3月11日 ~ 3月13日</li>
<li><strong>活动内容</strong>：<a href="https://github.com/ShanghaitechGeekPie/VibeCodinPie">VibeCodinPie</a>
Vibe Cod'in Pie 是一个让观众通过自然语言直接干预音乐进行的实时电子乐系统。观众只需扫码提出需求（如“让节奏快一点”、“加一点赛博朋克感的贝斯”），AI 就会在几秒钟内将需求转化为 <strong>Strudel</strong> 代码，并实时注入大屏运行引擎。来现场体验 AI 编曲的魅力吧！</li>
</ul>
<h2 id="全场麦派免费吃-">全场麦派免费吃 🥧</h2>
<ul>
<li><strong>活动时间</strong>：3月13日（周五）</li>
<li><strong>活动内容</strong>：我们为大家订购了多口味的麦当劳派！参与互动的同学即可<strong>免费</strong>领取，先到先得！</li>
</ul>
<h2 id="灵魂画手大揭秘-">灵魂画手大揭秘 🎨</h2>
<ul>
<li><strong>活动时间</strong>：3月13日 中午</li>
<li><strong>活动内容</strong>：<a href="https://paint2025.geekpie.club/">Paint2025</a> 绘板活动进入尾声。即日起登录 <a href="https://paint2025.geekpie.club/evaluation">投票页面</a> 进行投票，选出你心中的灵魂画手！我们将在活动当天现场揭晓结果并颁发<strong>现金奖励</strong>，敬请期待！</li>
</ul>
<hr>
<blockquote>
<p>3月13日，科道庭院不见不散！</p>
</blockquote>]]></content:encoded>
      <category>event</category>
      <category>GeekPie</category>
<category>Pi</category>
<category>PiDay</category>
<category>极客派对</category>
    </item>
    <item>
      <title>[GeekPie blog] Windows 环境下 OpenClaw 完全部署与配置教程</title>
      <author>Henry</author>
      <link>https://geekpie.club/posts/blog/2026-03-09-openclaw</link>
      <guid>https://geekpie.club/posts/blog/2026-03-09-openclaw</guid>
      <pubDate>Mon, 09 Mar 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[本文记录了在 Windows 环境下安装 OpenClaw 的完整过程，包含环境依赖配置、常见的网络及权限报错排查，以及接入 DeepSeek/豆包大模型、飞书平台的详细步骤。]]></description>
      <content:encoded><![CDATA[<p><a href="https://geekpie.club/posts/blog/2026-03-10-openclaw-macos/">macOS 安装教程点我</a>
OpenClaw 是近期备受关注的开源 AI Agent 工具，但官方对 Windows 的原生生态支持相对有限。在实际部署过程中，经常会遇到关于 Node.js 环境、执行策略设限和依赖下载的问题。</p>
<p>本文将结合实际安装记录以及社区的解决方案，提供一份详尽的 Windows 端安装、配置直至接入工具及大模型的完整流程。</p>
<hr>
<h2 id="一环境准备">一、环境准备</h2>
<p>由于 OpenClaw 对 Node.js 版本有要求，为避免后续权限和全局变量导致的问题，强烈建议使用 nvm（Node Version Manager）来进行环境管理。</p>
<h3 id="1-安装-nvm-for-windows">1. 安装 nvm for Windows</h3>
<blockquote>
<p><strong>⚠️ 强烈注意</strong>：在安装 nvm 之前，<strong>如果你的电脑上已经安装过 Node.js，请严格卸载旧版本！</strong> 包括清理掉全局模块和环境变量（如 <code>C:\Program Files\nodejs</code> 等），否则安装 nvm 后可能会导致极其混乱的路径冲突。</p>
</blockquote>
<p>前往 GitHub Releases 页面下载最新的 <code>nvm-setup.exe</code>：<a href="https://github.com/coreybutler/nvm-windows/releases">nvm-windows releases</a></p>
<p>安装过程保持默认并一路 Next 即可。</p>
<p><img src="/posts/blog/2026-03-09-openclaw/nvm-install.png" alt="nvm安装界面"></p>
<p>安装成功后，请使用<strong>管理员身份</strong>打开 PowerShell，执行 <code>nvm version</code> 验证安装。</p>
<p><img src="/posts/blog/2026-03-09-openclaw/nvm-version.png" alt="nvm version验证"></p>
<h3 id="2-配置-nodejs-22220-环境">2. 配置 Node.js 22.22.0 环境</h3>
<p>在 <strong>管理员 PowerShell</strong> 中，执行以下命令安装并指定使用 Node.js 22.22.0 版本：</p>
<pre><code class="language-powershell"># 安装指令
nvm install 22

# 使用指令
nvm use 22.22.0
</code></pre>
<p>安装并启用成功后，终端会打印类似 <code>Now using node v22.22.0</code> 的系统提示。</p>
<p><img src="/posts/blog/2026-03-09-openclaw/node-success.png" alt="Node安装成功"></p>
<hr>
<h2 id="二安装与启动-openclaw">二、安装与启动 OpenClaw</h2>
<h3 id="1-核心安装命令">1. 核心安装命令</h3>
<p>在已开启的<strong>管理员 PowerShell</strong> 中，执行官方提供的一键安装脚本：</p>
<pre><code class="language-powershell">iwr -useb https://openclaw.ai/install.ps1 | iex
</code></pre>
<h3 id="2-常见报错及排查">2. 常见报错及排查</h3>
<p><strong>报错 A：执行策略受限</strong>
在执行上述命令时，遇到如下红色报错：</p>
<blockquote>
<p><code>iex : 无法加载文件 C:\Program Files\nodejs\npm.ps1，因为在此系统上禁止运行脚本。...</code></p>
</blockquote>
<p><strong>原因</strong>：PowerShell 默认执行策略限制了未经签名的脚本执行。
<strong>解决方法</strong>：在终端输入以下命令提升当前用户的执行权限，并在系统询问时输入 <code>Y</code> 确认：</p>
<pre><code class="language-powershell">Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
</code></pre>
<p>提升权限后，重新执行前面的 <code>iwr</code> 安装命令。</p>
<p><strong>报错 B：安装卡死或极度缓慢</strong>
如果控制台显示 <code>[*] Installing OpenClaw (openclaw@latest)...</code> 后长时间无响应。
<strong>解决方法</strong>：按 <code>Ctrl + C</code> 中断当前进程，将 npm 源修改为国内镜像后再次安装：</p>
<pre><code class="language-powershell">npm config set registry https://registry.npmmirror.com
iwr -useb https://openclaw.ai/install.ps1 | iex
</code></pre>
<h3 id="3-初始化默认配置">3. 初始化默认配置</h3>
<p>安装成功后，通常会自动进入配置流程。如果不小心关闭了终端，可重新打开后执行：</p>
<pre><code class="language-powershell">openclaw onboard --flow quickstart
</code></pre>
<p>在连续的风险提示与初始询问中：</p>
<ul>
<li>看到 <code>I understand this is powerful and inherently risky. Continue?</code>，请选择 <code>Yes</code>。</li>
</ul>
<p><img src="/posts/blog/2026-03-09-openclaw/risk-confirm.png" alt="风险确认"></p>
<p>后续配置项建议按需简化（可使用最小化跑通再深层配置）：</p>
<ul>
<li><strong>模型/Model</strong>：选择所需模型，若暂未准备 API 可选 <code>skip for now</code>。</li>
<li><strong>API Keys</strong>：提供对应的 API Key (例如 Kimi、DeepSeek 或 MiniMax)，其余保持默认。</li>
</ul>
<p>下面以 MiniMax 为例获取 API Key：</p>
<ol>
<li>
<p>打开浏览器前往 <a href="https://platform.minimaxi.com/">MiniMax 开发者平台 (platform.minimaxi.com)</a>，并通过手机号快速注册/登录。</p>
</li>
<li>
<p>登录后，在页面右上角中找到并点击 <strong>账户管理</strong> ，左侧栏选择 <strong>接口密钥</strong> ，</p>
<p><img src="/posts/blog/2026-03-09-openclaw/minimax-api-keys.png" alt="MiniMax 控制台配置 API Keys"></p>
</li>
<li>
<p>点击 <strong>创建新的 API Key</strong> 或 <strong>+ 新建</strong>，给这个 Key 随意命名（比如 "OpenClaw"）并确认。</p>
</li>
<li>
<p>系统会生成一串以 <code>sk-</code> 开头的密钥。<strong>该密钥仅会完整显示一次</strong>，请务必立刻<strong>复制并妥善保存</strong>至密码管理器或安全位置，切勿发给他人。</p>
<p><img src="/posts/blog/2026-03-09-openclaw/minimax-sk-key.png" alt="获取并复制 API Key"></p>
</li>
</ol>
<p><img src="/posts/blog/2026-03-09-openclaw/api-key-config.png" alt="API Key配置"></p>
<ul>
<li><strong>Select Channel/Search Provider/Skills</strong>：官方建议 Windows 原生最好通过 WSL2 运行飞书等 IM 插件，因此在此步骤的连接频段建议先 <code>skip</code>，后续单独安装管理。</li>
</ul>
<p><img src="/posts/blog/2026-03-09-openclaw/skip-channel.png" alt="跳过通讯配置"></p>
<ul>
<li>
<p><strong>Hooks</strong>：全部勾选。上下箭头选择，空格选中/取消选中，回车提交。</p>
</li>
<li>
<p><strong>Hatch your bot</strong>：选择 <code>open in web ui</code>，将启动网关服务并在浏览器弹出控制台页面 <code>http://127.0.0.1:18789/</code>。控制台启动完成并可发消息回复，即代表基础运行成功。<em>(注：目前 Web UI 界面仍处于早期阶段，体验还不是很完善。对于熟悉命令行的用户，强烈推荐使用命令行交互，后续可通过终端输入 <code>openclaw tui</code> 进入。)</em></p>
</li>
</ul>
<p><img src="/posts/blog/2026-03-09-openclaw/openclaw-web.png" alt="Web控制台"></p>
<hr>
<h2 id="三配置-ai-模型">三、配置 AI 模型</h2>
<p>如果在初始化向导中跳过了模型配置，或者后续需要额外接入其他 AI 模型（如 DeepSeek、豆包等），可以通过命令行进行配置：</p>
<pre><code class="language-powershell">openclaw config
</code></pre>
<p>选择<code>Local</code>→<code>Model</code></p>
<p>随后选择自己的提供商。如果没有则选择<code>Custom Provider</code>。随后同上方 初始化配置<code>API Keys</code>处所提的相同方式配置。</p>
<h3 id="验证配置">验证配置</h3>
<pre><code class="language-powershell">openclaw health
</code></pre>
<h3 id="动态切换模型">动态切换模型</h3>
<p>如果需要在聊天过程中临时切换不同的 AI 模型，可以在终端使用 TUI（文本用户界面）进行操作：</p>
<ol>
<li>在终端输入 <code>openclaw tui</code> 打开命令行交互界面。</li>
<li>在对话框中输入 <code>/model</code>（或者 <code>/models</code>）并回车。</li>
<li>使用键盘的上下方向键挑选想要的模型，最后回车确认，即可切换成功。</li>
</ol>
<p><img src="/posts/blog/2026-03-09-openclaw/change-model.png" alt="动态切换模型"></p>
<hr>
<h2 id="四接入飞书平台应用全流程">四、接入飞书平台应用全流程</h2>
<h3 id="1-手动安装飞书插件">1. 手动安装飞书插件</h3>
<p>由于初始化向导在 Windows 可能报错缺失路径，请在 PowerShell 中直接调用 CLI 执行：</p>
<pre><code class="language-powershell">openclaw plugins install @m1heng-clawd/feishu
</code></pre>
<p><img src="/posts/blog/2026-03-09-openclaw/install-feishu-plugin.png" alt="安装飞书插件"></p>
<h3 id="2-飞书开放平台新建应用与配置">2. 飞书开放平台新建应用与配置</h3>
<p>访问 <a href="https://open.feishu.cn/">飞书开放平台</a> 创建应用，开启机器人功能，并获取 <strong>App ID</strong> 与 <strong>App Secret</strong>，在 OpenClaw 设置对应项时输入。</p>
<p><img src="/posts/blog/2026-03-09-openclaw/create-app.png" alt="创建应用"></p>
<p><img src="/posts/blog/2026-03-09-openclaw/create-app-credentials.png" alt="创建应用凭证"></p>
<h3 id="3-配置权限与事件">3. 配置权限与事件</h3>
<ul>
<li><strong>批量导入权限</strong>：寻找“权限管理” -> “批量导入导出权限”，导入json权限。</li>
</ul>
<pre><code class="language-json">{
  "scopes": {
    "tenant": [
      "aily:file:read",
      "aily:file:write",
      "application:application.app_message_stats.overview:readonly",
      "application:application:self_manage",
      "application:bot.menu:write",
      "contact:user.employee_id:readonly",
      "corehr:file:download",
      "event:ip_list",
      "im:chat.access_event.bot_p2p_chat:read",
      "im:chat.members:bot_access",
      "im:message",
      "im:message.group_at_msg:readonly",
      "im:message.p2p_msg:readonly",
      "im:message:readonly",
      "im:message:send_as_bot",
      "im:resource"
    ],
    "user": ["aily:file:read", "aily:file:write", "im:chat.access_event.bot_p2p_chat:read"]
  }
}
</code></pre>
<ul>
<li><strong>事件订阅</strong>：在“事件与回调”内，订阅方式改为 <strong>使用长连接接收事件</strong>，并点击添加事件 <code>im.message.receive_v1</code>。
<em>(注：若开启长连接提示失败，请确认 openclaw gateway 在后台正常 running，或者等待几分钟后重试保存)</em></li>
</ul>
<p><img src="/posts/blog/2026-03-09-openclaw/event-subscription.png" alt="事件订阅与长连接"></p>
<h3 id="4-发布应用并在飞书连通">4. 发布应用并在飞书连通</h3>
<p>一切配置就绪后，在飞书开发者“版本管理与发布”中提交版本。随后在飞书中直接搜索该机器人发起对话。
此时它回复的一串 <strong>配对码 (Pairing Code)</strong> 即为鉴权依据，将其输入 OpenClaw（或 <code>http://127.0.0.1:18789/</code> 中的飞书卡片绑定栏）即可完成双向绑定。</p>
<hr>
<h2 id="五常用命令排查与修复排查修复必备">五、常用命令排查与修复（排查/修复必备）</h2>
<p>如果在后续配置、开发途中遭遇服务状态异常卡死，下列终端命令将非常高效：</p>
<pre><code class="language-powershell"># 1. 启动网关服务 (如果长连接不上先跑这个)
openclaw gateway start

# 2. 从头配置你的连接、大模型与密钥项
openclaw config

# 3. 诊断系统及依赖项 (包括 NodeJS、网络连通性)
openclaw doctor

# 4. 实时跟踪日志 (排查飞书不回消息、插件调用报错的最核心工具)
openclaw logs follow

# 5. 重启网关底层进程，常用于更新插件后刷新鉴权与缓存
openclaw restart
</code></pre>
<p>完整文档：<a href="https://docs.openclaw.ai">https://docs.openclaw.ai</a></p>
<p>整个配置与连通流程到此全部走通。</p>
<p>—— GeekPie 社团，2026 年 3 月 9 日</p>]]></content:encoded>
      <category>blog</category>
      <category>OpenClaw</category>
<category>教程</category>
<category>Windows</category>
<category>配置</category>
    </item>
    <item>
      <title>[GeekPie event] HPCGame 3rd</title>
      
      <link>https://geekpie.club/posts/event/2026-02-01-hpcgame3rd</link>
      <guid>https://geekpie.club/posts/event/2026-02-01-hpcgame3rd</guid>
      <pubDate>Fri, 16 Jan 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[大家好，一年一度的由北京大学主办，GeekPie 等多所高校和社团参与协办的第三届 HPCGame 将于近日开赛！比赛设置了丰厚的奖励，欢迎大家对超算感兴趣的同学前来参赛，比赛成绩将作为之后超算队招新的参考！]]></description>
      <content:encoded><![CDATA[<p>大家好，一年一度的由北京大学主办，GeekPie 等多所高校和社团参与协办的第三届 HPCGame 将于近日开赛！比赛设置了丰厚的奖励，欢迎大家对超算感兴趣的同学前来参赛，比赛成绩将作为之后超算队招新的参考！</p>
<h2 id="比赛详情">比赛详情</h2>
<ul>
<li><strong>比赛时间</strong>：2026年2月1日11:00至2月8日23:59</li>
<li><strong>比赛网址</strong>：<a href="https://hpcgame.pku.edu.cn">https://hpcgame.pku.edu.cn</a></li>
<li><strong>比赛类型</strong>：个人赛</li>
<li><strong>主办方</strong>：北京大学学生 Linux 俱乐部</li>
<li>本次比赛设有附加赛，时间为 2 月 10 日 12:00 至 3 月 3 日 23:59，部分挑战性较大、无法完整放入正式比赛的赛题会拆分成简单部分放入正式赛、较难部分作为附加赛赛题。附加赛可两人组队，欢迎同学们挑战。</li>
<li>请加入选手交流QQ群：679550783。</li>
</ul>
<p><img src="/posts/event/2026-02-01-hpcgame3rd/hpcgame3rd.png" alt="HPCGame 3rd"></p>
<hr>
<blockquote>
<p>以下为主页搬运，仅供参考，一切以 <a href="https://hpcgame.pku.edu.cn/">https://hpcgame.pku.edu.cn/</a> 为准</p>
</blockquote>
<h2 id="比赛介绍">比赛介绍</h2>
<p>北京大学高性能计算综合能力竞赛（PKU HPCGame）是以高性能和并行计算为主题的入门向竞赛，目的是推进高性能计算在高校中的普及，提升同学们的计算素养。</p>
<p>比赛面向全国高校在校同学开放，追求零基础入门、题目难度具有梯度，致力于让完全没接触过高性能计算的新生和具备一定专业基础的同学都能享受比赛，在学习的过程中有所收获。</p>
<p>比赛是个人赛，我们针对高性能计算中的各个方向准备了相应的学习资料。经过学习和比赛，同学们可以对高性能和并行计算形成基本的认识，并掌握一定的实操能力。</p>
<p>我们对优胜者给予丰厚的激励，并颁发由北京大学计算中心和北大信息科学技术学院、北大计算机学院、北京大学长沙计算与数字经济研究院签发的获奖证书。我们欢迎北京大学的同学参加未名超算队，共同探索高性能计算的魅力。</p>
<p>题目考察的内容涉及到高性能计算的各个方面，包括萌新能愉快探索的入门题目和具有一定选拔作用的题目，有以下几个模块</p>
<ul>
<li>高性能计算简介：导论部分，对高性能计算模块做基本介绍</li>
<li>并行与大规模：并行计算相关工具和 CPU 上的计算优化，还包括了多台机器间的交互</li>
<li>机器学习系统：NPU 与 GPU 等加速器并行计算，主要介绍加速器在高性能计算以及大模型训练推理优化方面的应用</li>
<li>综合应用提升：综合运用高性能计算各方面的知识，解决一些有趣的问题</li>
</ul>
<p>比赛平台基于MIT协议开源，将会在赛后进行整理。</p>
<p>比赛的算力环境由<a href="https://hpc.pku.edu.cn">北京大学高性能计算平台</a>与北京大学卓越中心项目支持。</p>
<h2 id="赛程安排">赛程安排</h2>
<table>
<thead>
<tr>
<th>比赛环节</th>
<th>时间</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>赛前讲座</td>
<td>2026 年 1 月 23 日 至 1 月 30 日</td>
<td>请关注QQ群通知与<code>live.lcpu.dev</code>网页通知</td>
</tr>
<tr>
<td>正式比赛</td>
<td>2026 年 2 月 1 日 11:00 至 2 月 8 日 23:59</td>
<td>个人赛</td>
</tr>
<tr>
<td>附加赛</td>
<td>2026 年 2 月 10 日 12:00 至 3 月 3 日 23:59</td>
<td>可最多两人组队，完成个人赛中对应的资质赛题即可参与，可能无奖励</td>
</tr>
<tr>
<td>颁奖典礼</td>
<td>另行通知</td>
<td>2026 年春季学期开学后于北京大学线下举行</td>
</tr>
</tbody>
</table>
<h2 id="奖项设置">奖项设置</h2>
<h2 id="北京大学校内奖项设置">北京大学校内奖项设置</h2>
<ul>
<li>一等奖 5 名： 奖金 6000 元、获奖证书</li>
<li>二等奖 10 名： 奖金 4000 元、获奖证书</li>
<li>三等奖 15 名： 奖金 2000 元、获奖证书</li>
<li>优胜奖 20 名： 获奖证书、奖品</li>
<li>新生特别奖 3 名： 获奖证书、奖品《并行计算与高性能计算》</li>
</ul>
<p>只有在校本科生和研究生参与评奖，请确保通过IAAA登录。一、二、三等奖及优胜奖颁发给校内排名 1 ～ 5、6 ～ 15、16 ～ 30、31 ～ 50 的选手。新生特别奖颁发给分数不低于优胜奖分数线且在新生中排名前 3 的选手。</p>
<h2 id="校外选手奖励">校外选手奖励</h2>
<ul>
<li>一等奖 5 名：奖金 2000 元、获奖证书</li>
<li>二等奖 10 名：奖金 1500 元、获奖证书</li>
<li>三等奖 15 名：奖金 1000 元、获奖证书</li>
</ul>
<p>协办组织所在高校获奖选手将获奖500元额外奖金。获奖选手需通过学信网验证在校身份，且需不低于北京大学对应奖项分数线。</p>
<h2 id="特别赛道奖">特别赛道奖</h2>
<ul>
<li>解题特别奖（若干）：奖金、纪念品，奖励超出组委会预期的优秀解法</li>
</ul>
<h2 id="相关单位">相关单位</h2>
<h3 id="主办单位">主办单位</h3>
<p>北京大学计算中心</p>
<h3 id="联合主办">联合主办</h3>
<p>北京大学计算机学院</p>
<p>北京大学信息科学技术学院</p>
<p>北京大学长沙计算与数字经济研究院</p>
<h3 id="承办单位">承办单位</h3>
<p>北京大学未名超算队</p>
<p>北京大学学生 Linux 俱乐部</p>
<h3 id="协办组织">协办组织</h3>
<p>（按确定协办的先后顺序排列、目前还在招募中）</p>
<ul>
<li>上科大GeekPie_HPC</li>
<li>东南大学 Linux 俱乐部</li>
<li>齐鲁工业大学网络运维</li>
<li>北京航空航天大学超算社</li>
<li>华中科技大学七边形超算队</li>
<li>兰州大学开源社区</li>
<li>电子科技大学 Negation 超算俱乐部</li>
<li>中国科学技术大学学生 Linux 用户协会</li>
<li>澳门科技大学超算队</li>
<li>西安电子科技大学开源社区</li>
<li>南京大学 e-Science 中心</li>
<li>北京联合大学计算机技术社</li>
<li>浙江大学超算队</li>
<li>北京理工大学 Linux 用户小组</li>
<li>上海交通大学 Xflops 超算队</li>
<li>上海大学开源社区</li>
</ul>
<h3 id="特别鸣谢">特别鸣谢</h3>
<p><img src="https://hpcgame.pku.edu.cn/oss/images/public/huawei-big-logo.png" alt="HUAWEI"></p>
<p><img src="https://hpcgame.pku.edu.cn/oss/images/public/xiaomi-foundation-logo.png" alt="XIAOMI"></p>
<p><img src="https://hpcgame.pku.edu.cn/oss/images/public/ubiquant-logo.png" alt="UbiQuant"></p>]]></content:encoded>
      <category>event</category>
      <category>GeekPie</category>
<category>GeekPie_HPC</category>
<category>PKU</category>
<category>HPCGame</category>
<category>HPC</category>
    </item>
    <item>
      <title>[GeekPie blog] 与科技同行，与未来共新</title>
      <author>GeekPie</author>
      <link>https://geekpie.club/posts/blog/2026-01-01-newyear</link>
      <guid>https://geekpie.club/posts/blog/2026-01-01-newyear</guid>
      <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
      <description><![CDATA[极境未殇，客聚众望；星河如炬，派写新章。GeekPie 祝你新年快乐！]]></description>
      <content:encoded><![CDATA[<h1 id="geekpie-2026-新年献词--与科技同行与未来共新">GeekPie 2026 新年献词 | 与科技同行，与未来共新</h1>
<p>新年的钟声已然敲响，站在 2026 的奇点回望 2025 这短暂而又漫长的一年。科技的车轮如同列车过轨，每一次动荡都碾碎旧壳，每一次前行都孕生曙光。</p>
<p>继 “ChatGPT 时刻” 之后，我们迎来了 “DeepSeek冲击”，我们在 AI 的雨林里扇动翅膀，不仅引发了纳斯达克历史上最大的单日市值蒸发，更迫使全球重新评估算力成本与智能供给之间的关系。放眼国际，由 Grok 4、Claude 4.5 Sonnet、GPT-5.2 和 Gemini 3 构筑成的大模型年轮仍在螺旋式的生长。大语言模型不再仅仅是回答问题和 Copy &#x26; Paste，它们开始融入我们每一行代码、每一次补全、每一次 Review，开始接管软件开发、科学研究和企业管理流程。Agentic AI昼夜奔流，Cursor 的井喷和 Copilot 的迭代，国产 TRAE 和 Claude Code 后来居上——这一切不断丰盈我们对生产力的想象，也让无数目光在憧憬中交织着忐忑。</p>
<p>在物理世界，算力的争夺进入了原子级别的较量。台积电开启 2nm 量产、英特尔落地 18A 节点、国产光刻 EUV 传言四起，芯片制造的竞争已上升为这场算力博弈的核心。NVIDIA 凭借 Blackwell 架构和 RTX 50 系列显卡继续统治 AI 硬件市场，国产显卡仍在缝隙中点亮自己的微光，内存厂又在演绎火灾与供应短缺的脚本。在消费级电子领域，系统级 AI 和 NPU 已融进各大系统的血脉，手机不仅是摄影变焦环与双镜演绎的美学诗篇，还有麒麟和玄戒等对自主研发和自主设计的探索。科技之路，容得下曲折与试错，却从未允许脚步停歇。</p>
<p>人类探索的羽翼也在这一年加速舒展。Artemis II 告诉人类重返深空的倒计时已经开始；SpaceX 以惊人纪录确立了其在近地轨道的绝对统治地位；天问二号任务将目光投向了更遥远的小行星采样。生物技术领域，CRISPR基因编辑疗法和AI设计药物的临床突破，“TechBio”时代正在到来。</p>
<p>然而光芒背后，暗影也随之生长。网络安全面临前所未有的危机，各大安全事件随着科技的进步变得更加诡谲难防，Deepfakes 在社交媒体的滥用挑战了社会的信任基石；Sora 的出现让真实的边界愈发飘摇；Manus 的昙花一现，则让人们审视什么是科技真正的护城墙。行业深处，科技的“效率悖论”愈发凸显：一方面是创纪录的并购交易，另一方面是持续不断的裁员潮…… AI 催生的生产力浪潮与它掀起的商业泡沫，正共同重塑劳动力的瀚海，我们虽不知航向，却已身在浪潮。</p>
<p>我们栖居于一个剧变的年代，幸甚，亦哀甚。世界张力未松，网络戾气弥漫，全球化逆流盘旋——但这所有，从未冷却我们胸中那团对科技的热望。</p>
<p>因为我们，本就是追逐星光的人。</p>
<p>极境未殇，客聚众望；星河如炬，派写新章。</p>
<p>祝你新年快乐！</p>
<p>—— GeekPie 社团，2026 年 1 月 1 日</p>
<p><img src="/posts/blog/2026-01-01-newyear/paint2025-result.png" alt="Paint2025 Result"></p>]]></content:encoded>
      <category>blog</category>
      <category>GeekPie</category>
<category>Post</category>
<category>2026</category>
<category>New Year</category>
    </item>
    <item>
      <title>[GeekPie blog] 2025 新年绘板——规则说明、 API 文档及样例</title>
      <author>ZAMBAR</author>
      <link>https://geekpie.club/posts/blog/2025-12-22-paint2025</link>
      <guid>https://geekpie.club/posts/blog/2025-12-22-paint2025</guid>
      <pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate>
      <description><![CDATA[即日起至 2025/12/31 23:59:59，2025 新年绘板都将开放。本文介绍了其具体的规则补充，可用于编程的 API 文档和一个最小 Python 样例]]></description>
      <content:encoded><![CDATA[<h1 id="2025-新年绘板">2025 新年绘板</h1>
<ul>
<li>Link: <a href="https://paint2025.geekpie.club">https://paint2025.geekpie.club</a></li>
<li>活动时间：即日起至 2025/12/31 23:59:59</li>
</ul>
<blockquote>
<p>[!note]</p>
<p>本文最近已于 2025/12/24 02:55 (UTC+8) 有更新，之前的消息可能过时。</p>
<ul>
<li>2025/12/24: 预祝大家圣诞节快乐！我们紧急修复了样例中在某些校园网环境下无法访问服务器的问题 <del>（图信你干得好啊）</del>，并更新了相关配置要求。</li>
</ul>
</blockquote>
<p>活动具体详情见 Event 页面</p>
<h2 id="规则补充说明">规则补充说明</h2>
<ul>
<li>第一天为了快速占有领地，我们给出了 128 体力槽和 1.5 秒的体力恢复时间，之后为了保证作品不会被覆盖，我们会随着时间推移增加冷却间隔和减少体力槽。</li>
<li>我们允许并支持组队（合理收集他人 Token）和使用 BOT 绘图，这有助于你快速的更新版图。</li>
<li>请不要恶意覆盖他人图案。</li>
<li>请不要攻击服务器，公开他人信息。</li>
<li>请不要绘制任何不适当的内容，包括但不限于涉政、色情、暴力、仇恨言论等。</li>
</ul>
<h2 id="api-文档">API 文档</h2>
<h3 id="非绘画-api">非绘画 API</h3>
<h4 id="post-apiauthexchange---令牌交换">POST <code>/api/auth/exchange</code> - 令牌交换</h4>
<blockquote>
<p>⚠️：我们推荐手动获取 Token，此处仅为列出。</p>
</blockquote>
<ul>
<li><strong>功能</strong>: 与 Casdoor 进行 OAuth2 OIDC 集成，交换用户令牌获取会话</li>
<li><strong>请求体</strong>: <code>{ token: string }</code></li>
<li><strong>返回</strong>: 包含 <code>sessionToken</code> 和用户信息</li>
<li><strong>认证</strong>: 使用 Casdoor OIDC userinfo 端点验证令牌</li>
<li><strong>存储</strong>: 在 MongoDB 中创建/更新用户会话，分配绘制点数额度</li>
</ul>
<h2 id="get-apiv2place-获取画板数据-json">GET <code>/api/v2/place</code> 获取画板数据 (JSON)</h2>
<blockquote>
<p>⚠️：**不再维护。**可能存在延迟且由于 JSON 格式开销较大，仅供初始化或调试使用，不推荐频繁轮询。</p>
</blockquote>
<ul>
<li>
<p><strong>功能</strong>: 获取当前画板上所有已绘制的点及配置信息。</p>
</li>
<li>
<p><strong>返回</strong>:</p>
<pre><code class="language-json">{
"status": true,
"data": {
    "points": [
    { "x": 10, "y": 20, "c": "ff0000" },
    { "x": 15, "y": 25, "c": "00ff00" }
    ],
    "colors": ["000000", "ffffff", ...], // 预置颜色列表
    "delay": 5,                           // 绘制延迟时间（秒）
    "actionCount": 12345                  // 总操作次数
}
}
</code></pre>
</li>
<li>
<p><strong>认证</strong>: 无需认证</p>
</li>
</ul>
<hr>
<h2 id="get-apiv2init---获取画板数据-binary">GET <code>/api/v2/init</code> - 获取画板数据 (Binary)</h2>
<ul>
<li>
<p><strong>功能</strong>: 以二进制流格式高效获取画板数据，支持增量更新。</p>
</li>
<li>
<p><strong>URL 参数</strong>:</p>
<ul>
<li><code>since</code> (可选): 上次获取到的操作计数（Action Count）。如果提供且大于 0，则返回自该操作以来的增量更新数据；否则返回全量数据。</li>
</ul>
</li>
<li>
<p><strong>返回</strong>: <code>application/octet-stream</code> 二进制流</p>
</li>
</ul>
<p><strong>二进制结构解析</strong>:</p>
<p>数据流由 <strong>Header</strong> 和 <strong>Points Body</strong> 两部分组成。所有多字节整数均采用 <strong>Little-Endian (小端序)</strong>。</p>
<p><strong>Header 结构</strong></p>
<table>
<thead>
<tr>
<th align="left">字段</th>
<th align="left">类型</th>
<th align="left">字节数</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Action Count</td>
<td align="left">UInt32</td>
<td align="left">4</td>
<td align="left">当前总操作次数 (用于下次请求 <code>since</code> 参数)</td>
</tr>
<tr>
<td align="left">Delay</td>
<td align="left">Float32</td>
<td align="left">4</td>
<td align="left">绘制延迟时间（秒）</td>
</tr>
<tr>
<td align="left">Palette Size</td>
<td align="left">UInt8</td>
<td align="left">1</td>
<td align="left">调色板颜色数量 (N)</td>
</tr>
<tr>
<td align="left">Palette</td>
<td align="left">UInt8 Array</td>
<td align="left">N * 3</td>
<td align="left">调色板颜色数据，每个颜色 3 字节 (R, G, B)</td>
</tr>
<tr>
<td align="left">Points Count</td>
<td align="left">UInt32</td>
<td align="left">4</td>
<td align="left">随后的点数据数量 (M)</td>
</tr>
</tbody>
</table>
<p><strong>Points Body 结构</strong></p>
<p>紧接 Header 之后，包含 M 个点的数据。每个点占用 7 字节。</p>
<table>
<thead>
<tr>
<th align="left">字段</th>
<th align="left">类型</th>
<th align="left">字节数</th>
<th align="left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">X</td>
<td align="left">UInt16</td>
<td align="left">2</td>
<td align="left">X 坐标</td>
</tr>
<tr>
<td align="left">Y</td>
<td align="left">UInt16</td>
<td align="left">2</td>
<td align="left">Y 坐标</td>
</tr>
<tr>
<td align="left">Color</td>
<td align="left">UInt8 Array</td>
<td align="left">3</td>
<td align="left">颜色值 (R, G, B)</td>
</tr>
</tbody>
</table>
<p><strong>解析示例 (伪代码)</strong>:</p>
<pre><code class="language-javascript">// 假设 buffer 是接收到的 ArrayBuffer
let offset = 0;
const view = new DataView(buffer);

// 1. 读取 Action Count
const actionCount = view.getUint32(offset, true); // true for Little-Endian
offset += 4;

// 2. 读取 Delay
const delay = view.getFloat32(offset, true);
offset += 4;

// 3. 读取 Palette
const paletteSize = view.getUint8(offset);
offset += 1;

const palette = [];
for (let i = 0; i &#x3C; paletteSize; i++) {
  const r = view.getUint8(offset++);
  const g = view.getUint8(offset++);
  const b = view.getUint8(offset++);
  palette.push({ r, g, b });
}

// 4. 读取 Points Count
const pointsCount = view.getUint32(offset, true);
offset += 4;

// 5. 读取 Points
const points = [];
for (let i = 0; i &#x3C; pointsCount; i++) {
  const x = view.getUint16(offset, true);
  offset += 2;
  const y = view.getUint16(offset, true);
  offset += 2;
  const r = view.getUint8(offset++);
  const g = view.getUint8(offset++);
  const b = view.getUint8(offset++);
  points.push({ x, y, color: { r, g, b } });
}
</code></pre>
<ul>
<li><strong>认证</strong>: 无需认证</li>
</ul>
<h4 id="get-apistatus---统计信息">GET <code>/api/status</code> - 统计信息</h4>
<ul>
<li>
<p><strong>功能</strong>: 获取应用的统计数据</p>
</li>
<li>
<p><strong>返回</strong>:</p>
<pre><code class="language-json">{
  "status": true,
  "data": {
    "totalActions": 12345,     // 总绘制操作数
    "totalUsers": 789,         // 总用户数
    "timestamp": "2025-12-23..."
  }
}
</code></pre>
</li>
<li>
<p><strong>认证</strong>: 无需认证</p>
</li>
</ul>
<hr>
<h3 id="绘画-api">绘画 API</h3>
<p>本次绘画相关 API 没有使用 HTTP Endpoint，因此所有的请求都不会产生新的 HTTP 请求，如需抓包请从开始的 Websocket 会话中提取信息。</p>
<h4 id="连接信息">连接信息</h4>
<ul>
<li>协议: Socket.io v4 (并非原生 WebSocket)</li>
<li>端点 (Endpoint): <code>https://paint2025.geekpie.club</code></li>
<li>命名空间 (Namespace): <code>/</code> (默认)</li>
<li>认证方式: 在建立连接握手（Handshake）时，需要在 auth 对象中携带 Token。
<ul>
<li>Token 获取方式：登录网页版后，在 Token 输入框复制或者刷新。</li>
</ul>
</li>
</ul>
<h4 id="连接流程">连接流程</h4>
<p>要通过 API 进行绘画，你需要使用 Websocket 建立一个会话，并且通过这个绘画不断发送和监听消息。我们已经通过 Socket.IO 简化了对应流程，大致流程主要如下：</p>
<ol>
<li><strong>握手认证</strong>: 你需要通过携带 Token 发送请求，实现建连。</li>
<li><strong>中间件验证</strong>: 服务器验证令牌有效性，触发 <code>authenticated</code> 时间通知认证结果和初始点数。</li>
<li><strong>房间加入</strong>: 服务器根据令牌自动将您加入 Token 对应房间，房间内广播 <code>sync</code> 事件用来同步剩余点数和最后计算时间。</li>
<li><strong>开始绘画</strong>：客户端发送 <code>draw</code> 事件进行绘画，你可以通过 Socket.IO 的 Callback(ACK) 来获取返回信息。</li>
<li><strong>广播更新</strong>：绘画成功后服务器统一广播 <code>draw</code> 事件进行增量更新。</li>
</ol>
<h4 id="事件列表">事件列表</h4>
<table>
<thead>
<tr>
<th>事件名</th>
<th>方向</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>authenticated</strong></td>
<td>服务器→客户端</td>
<td>连接建立时返回认证结果和初始点数</td>
</tr>
<tr>
<td><strong>draw</strong></td>
<td>客户端↔服务器</td>
<td>客户端请求绘制操作，服务器广播绘制进行同步（含速率限制、点数消耗）</td>
</tr>
<tr>
<td><strong>sync</strong></td>
<td>服务器→客户端</td>
<td>返回绘制后剩余点数和最后更新时间</td>
</tr>
<tr>
<td><strong>onlineClientsUpdated</strong></td>
<td>服务器→客户端</td>
<td>广播在线用户数量变化</td>
</tr>
<tr>
<td><strong>disconnect</strong></td>
<td>系统事件</td>
<td>用户断开连接时触发</td>
</tr>
</tbody>
</table>
<h4 id="数据格式">数据格式</h4>
<h5 id="pointdata"><code>PointData</code></h5>
<p>描述一个像素点</p>
<table>
<thead>
<tr>
<th>字段</th>
<th>类型</th>
<th>说明</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>x</code></td>
<td>Integer</td>
<td>X 坐标 (<code>0</code> ~ <code>CANVAS_WIDTH-1</code>)</td>
<td><code>100</code></td>
</tr>
<tr>
<td><code>y</code></td>
<td>Integer</td>
<td>Y 坐标 (<code>0</code> ~ <code>CANVAS_HEIGHT-1</code>)</td>
<td><code>200</code></td>
</tr>
<tr>
<td><code>c</code></td>
<td>String</td>
<td>颜色 (Hex 格式字符串)</td>
<td><code>"#FF0000"</code></td>
</tr>
<tr>
<td><code>w</code></td>
<td>Number</td>
<td>宽度 (⚠️限制为 1，即将删除)</td>
<td><code>1</code></td>
</tr>
<tr>
<td><code>h</code></td>
<td>Number</td>
<td>高度 (⚠️限制为 1，即将删除)</td>
<td><code>1</code></td>
</tr>
<tr>
<td><code>user</code></td>
<td>String</td>
<td><strong>(仅接收)</strong> 绘制该点的用户名</td>
<td><code>"user_123"</code></td>
</tr>
</tbody>
</table>
<h4 id="客户端推送事件">客户端推送事件</h4>
<h5 id="draw"><code>draw</code></h5>
<p>用于请求在画布上绘制一个点。</p>
<ul>
<li>
<p><strong>频率限制</strong>: 受服务端 <code>DRAW_MAX_POINTS</code> 和 <code>DRAW_DELAY_MS</code> 控制（类似于体力槽机制）。</p>
</li>
<li>
<p><strong>Payload 结构</strong>:</p>
<pre><code class="language-json">{
    "data": { // 参考 `PointData`
        "x": 100,
        "y": 200,
        "c": "#000000",
        "w": 1, // 必须为 1
        "h": 1  // 必须为 1
    },
    "token": "xxx" // 已废弃，无需携带
}

</code></pre>
</li>
<li>
<p>返回样例(失败)</p>
<pre><code class="language-json">{
    "code": -4,
    "message": "Insufficient points",
    "pointsLeft": 0 // 其他情况下为 undefined
}
</code></pre>
</li>
<li>
<p>返回样例(成功)</p>
<pre><code class="language-json">{
    "code": 0,
    "message": "Draw successful",
    "pointsLeft": 10
}
</code></pre>
</li>
<li>
<p>错误代码参考</p>
<pre><code class="language-ts">export enum AppErrorCode {
    Success = 0,                // 成功
    InvalidToken = -1,          // Token 无效
    UnknownError = -2,          // 未知错误
    InvalidRequest = -3,        // 请求载荷不正确或 Zod 验证失败
    InsufficientPoints = -4,    // 体力不足
    InvalidPosition = -5,       // 位置无效
}
</code></pre>
</li>
</ul>
<p>Example (Python):</p>
<pre><code class="language-python">def on_draw_response(result):
    print(f"Draw response received: {result}")
    
    code = result.get('code')
    points_left = result.get('pointsLeft')
    last_update = result.get('lastUpdate')
    message = result.get('message', "Unknown Error")

payload = {
    "data": {
        "x": x,
        "y": y,
        "c": color,
        "w": 1,
        "h": 1
    }
}

self.sio.emit("draw", payload, callback=on_draw_response)
</code></pre>
<h4 id="服务端推送事件">服务端推送事件</h4>
<p>客户端需要监听这些事件来更新本地状态。</p>
<h5 id="authenticated"><code>authenticated</code></h5>
<p>连接成功并验证 Token 后立即发送。</p>
<ul>
<li>
<p><strong>数据</strong>:</p>
<pre><code class="language-json">{
    "success": true,
    "pointsLeft": 10,
    "lastUpdate": 1766427449915, // ms 时间戳
}
</code></pre>
</li>
</ul>
<h5 id="draw-1"><code>draw</code></h5>
<p><strong>广播事件</strong>。当<strong>其他用户</strong>（或你自己）成功绘制一个点时触发。用于实时同步画布。</p>
<ul>
<li>
<p><strong>数据</strong>: 包含完整的点信息 (<code>x</code>, <code>y</code>, <code>c</code>, <code>user</code>, <code>create_at</code> 等)。</p>
<pre><code class="language-json">{
    "x": 0,
    "y": 0,
    "h": 1,
    "w": 1,
    "c": "#000000"
}
</code></pre>
</li>
</ul>
<h5 id="onlineclientsupdated"><code>onlineClientsUpdated</code></h5>
<p>当在线用户数量变化时触发。</p>
<ul>
<li>
<p><strong>数据</strong>:</p>
<pre><code class="language-json">{
    "count": 123
}
</code></pre>
</li>
</ul>
<h4 id="房间内推送事件">房间内推送事件</h4>
<p>只有根据 token 加入房间后才会按 token 广播的私有事件。</p>
<h5 id="sync"><code>sync</code></h5>
<p>当你发送 <code>draw</code> 请求后，无论成功与否，服务端可能会发送此事件来强制同步客户端的剩余点数。</p>
<ul>
<li>
<p><strong>数据</strong>:</p>
<pre><code class="language-json">{
    "pointsLeft": 10,
    "lastUpdate": 1766427449915
}
</code></pre>
</li>
</ul>
<h2 id="样例">样例</h2>
<h3 id="紧急更新关于在校内部分网段无法连接服务器的解决办法">紧急更新：关于在校内部分网段无法连接服务器的解决办法</h3>
<p>我们发现在部分网段下（例如寝室和部分地点）无法通过 Python 的 Websocket 与服务器正常连接。经过排查，我们初步断定这是由于图信的 DNS 将服务器解析成 IPv6 但是没有正确配置 IPv6 出口等基础设施的原因。😠</p>
<p>如果你使用的是自己的脚本，加入下列 patch 在最前方即可强制使用 IPv4 解析：</p>
<pre><code class="language-python">import socket

old_getaddrinfo = socket.getaddrinfo

def getaddrinfo_ipv4_only(host, port, *args, **kwargs):
    # 只保留返回 AF_INET（IPv4）的解析结果
    results = old_getaddrinfo(host, port, *args, **kwargs)
    return [res for res in results if res[0] == socket.AF_INET]

socket.getaddrinfo = getaddrinfo_ipv4_only
</code></pre>
<h3 id="环境准备">环境准备</h3>
<p>下面给出较现代的 uv 格式的环境，保存为 <code>pyproject.toml</code> 后用 <code>uv sync</code> 即可。</p>
<pre><code class="language-toml">[project]
name = "paint-bot"
version = "0.1.0"
description = "paint2025 bot"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "pillow>=12.0.0",
    "python-socketio>=5.15.1",
    "requests>=2.32.5",
    "websocket-client>=1.9.0",
]
</code></pre>
<p>或者使用 <code>requirements.txt</code> 以及 <code>pip</code> 手动安装上述 4 个依赖也可以解决问题。注意不要安装 <code>socketio</code> 库。</p>
<h3 id="代码">代码</h3>
<p>关于填涂策略，你可以选择顺序填涂或者防御性更好的和更适合并行的散点式绘图。</p>
<p>下面是一个来自 <a href="https://github.com/GregTaoo/">@Gregtaoo</a> 编写的基本样例程序，基本实现了多 Token 和绘图，但缺少对 Delay Time 的计算和实时监听 <code>sync</code> 同步的过程。</p>
<pre><code class="language-python">import argparse
import time
import requests
from PIL import Image
import socketio
import threading

def rgb_to_hex(r, g, b):
    return f"#{r:02x}{g:02x}{b:02x}"

def get_canvas_points():
    resp = requests.get("https://paint2025.geekpie.club/api/place")
    resp.raise_for_status()
    data = resp.json()
    points = {}
    for p in data.get("data", {}).get("points", []):
        points[(int(p["x"]), int(p["y"]))] = p["c"].lower()
    return points

# =========================
# 单 token Socket.IO 客户端
# =========================
class TokenClient:
    def __init__(self, token: str):
        self.token = token
        self.sio = socketio.Client(
            logger=False,
            engineio_logger=False
        )
        self.connected = False

        @self.sio.event
        def connect():
            self.connected = True
            print(f"[socketio] token {self.token[:6]} connected")

        @self.sio.event
        def disconnect():
            self.connected = False
            print(f"[socketio] token {self.token[:6]} disconnected")

    def connect(self):
        self.sio.connect(
            "https://paint2025.geekpie.club",
            transports=["websocket"],
            wait=True,
            wait_timeout=30,
            auth={
                "token": self.token
            }
        )

    def draw(self, x, y, color):
        if not self.connected:
            return False
        self.sio.emit(
            "draw",
            {
                "data": {"w": 1, "h": 1, "x": x, "y": y, "c": color},
            },
        )
        return True

    def close(self):
        if self.connected:
            self.sio.disconnect()

# =========================
# 主绘制逻辑
# =========================
def draw_image_until_complete(img_path, width, height, start_x, start_y, tokens_str):
    tokens = [t.strip() for t in tokens_str.split(",") if t.strip()]
    if not tokens:
        raise ValueError("No valid tokens")

    print(f"Starting with {len(tokens)} tokens")

    # 创建 token 客户端
    clients = [TokenClient(t) for t in tokens]

    # 并行连接
    threads = []
    for c in clients:
        t = threading.Thread(target=c.connect, daemon=True)
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    img = Image.open(img_path).convert("RGB")
    img = img.resize((width, height), Image.LANCZOS)
    pixels = img.load()

    client_index = 0
    sleep_time = 0.25

    try:
        while True:
            canvas = get_canvas_points()
            all_done = True

            for dy in range(height):
                for dx in range(width):
                    x = start_x + dx
                    y = start_y + dy
                    r, g, b = pixels[dx, dy]
                    color = rgb_to_hex(r, g, b).lower()

                    if canvas.get((x, y)) != color:
                        all_done = False

                        client = clients[client_index]
                        client_index = (client_index + 1) % len(clients)

                        if client.draw(x, y, color):
                            print(
                                f"[draw] x={x}, y={y}, color={color}, token={client.token[:6]}"
                            )
                        else:
                            print(
                                f"[draw] skipped (not connected) token={client.token[:6]}"
                            )

                        time.sleep(sleep_time)

            if all_done:
                print("All pixels match the target image!")
                break
            else:
                print("Not finished, checking again")
                time.sleep(5)
    finally:
        for c in clients:
            c.close()

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--image", required=True)
    parser.add_argument("--width", type=int, required=True)
    parser.add_argument("--height", type=int, required=True)
    parser.add_argument("--start-x", type=int, required=True)
    parser.add_argument("--start-y", type=int, required=True)
    parser.add_argument("--tokens", required=True)
    args = parser.parse_args()

    draw_image_until_complete(
        args.image,
        args.width,
        args.height,
        args.start_x,
        args.start_y,
        args.tokens,
    )

if __name__ == "__main__":
    main()
</code></pre>]]></content:encoded>
      <category>blog</category>
      <category>GeekPie</category>
<category>Paint</category>
<category>Post</category>
    </item>
    <item>
      <title>[GeekPie event] Paint2025 新年绘板</title>
      
      <link>https://geekpie.club/posts/event/2025-12-17-paint2025</link>
      <guid>https://geekpie.club/posts/event/2025-12-17-paint2025</guid>
      <pubDate>Sun, 21 Dec 2025 00:00:00 GMT</pubDate>
      <description><![CDATA[去年我们有过许多瞬间：比赛、展演、寝室的深夜讨论、图书馆的清晨打卡……今年我们把这些瞬间用像素画下来。]]></description>
      <content:encoded><![CDATA[<h1 id="paint2025-新年绘板">Paint2025 新年绘板</h1>
<blockquote>
<p>2025 要被定格成什么样子？</p>
</blockquote>
<p>去年我们有过许多瞬间：比赛、展演、寝室的深夜讨论、图书馆的清晨打卡……今年我们把这些瞬间用像素画下来。</p>
<p>Paint2025 是一个多人在线协作的画布（灵感来自 r/place）——在一张覆盖整个上科大的像素地图上，你可以与所有师生同时创作、覆盖、合作或对抗。画社团徽标、画你和朋友的“地盘”、画表情包；每个像素都在记录属于我们的 2025。</p>
<p>📍活动时间：2025/12/22 12:00 开始，2026/1/1 00:00 定格画布。
🔗 参与入口：<a href="https://paint2025.geekpie.club">https://paint2025.geekpie.club</a>
👑 奖励亮点：</p>
<ul>
<li><strong>灵魂画手奖</strong>（赛后评比）—— <strong>第1名 200 RMB / 第2名 150 RMB / 第3名 100 RMB</strong></li>
<li><strong>广而告之奖</strong> —— 转发空间即可获周边贴纸；再从中随机抽取 2 名各 <strong>50 RMB</strong></li>
<li><strong>天选之子奖</strong> —— 从注册用户随机抽取 2 名，各 <strong>50 RMB</strong>
🔧 玩法要点：</li>
<li>每位玩家拥有 24 点体力，体力随时间冷却回复，冷却会逐渐加长；</li>
<li>可选择快速发育占领大块区域，或与同伴协作/对抗进行像素博弈；</li>
<li>开发者/高级玩家可以编写自动化脚本（注意遵守活动规则）。
📂 项目仓库：<code>HeZeBang/DrawingPlace</code>（欢迎感兴趣的同学贡献想法/提 PR）</li>
</ul>
<p>来吧，把你的像素留在校园的地图上，让我们在新年一起回顾这张属于上科大的 2025。</p>
<p><img src="/posts/event/2025-12-17-paint2025/paint2025.png" alt="Poster"></p>]]></content:encoded>
      <category>event</category>
      <category>学生会</category>
<category>GeekPie</category>
<category>Paint</category>
    </item>
    <item>
      <title>[GeekPie blog] 欢迎来到 GeekPie Blogs！</title>
      <author>ZAMBAR</author>
      <link>https://geekpie.club/posts/blog/2025-12-10-welcome</link>
      <guid>https://geekpie.club/posts/blog/2025-12-10-welcome</guid>
      <pubDate>Wed, 10 Dec 2025 00:00:00 GMT</pubDate>
      <description><![CDATA[这是一个 Blog 模板，也是一次新的开始。希望 GeekPie Blogs 越办越好！]]></description>
      <content:encoded><![CDATA[<h1 id="新的开始">新的开始？</h1>
<blockquote>
<p>这是一个 Blog 模板，也是一次新的开始。希望 GeekPie Blogs 越办越好！</p>
<p>—— ♥️ from <a href="https://github.com/HeZeBang/">ZAMBAR</a></p>
</blockquote>
<h2 id="碎碎念">碎碎念</h2>
<p>其实我也不知道说什么…… <del>其实是为了测试我的渲染到底正不正常</del></p>
<p><img src="/posts/blog/2025-12-10-welcome/geekpie-isc26.png" alt="GeekPie_HPC"></p>]]></content:encoded>
      <category>blog</category>
      <category>GeekPie</category>
<category>Post</category>
    </item>
  </channel>
</rss>