<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>开源 on Svtter's Blog</title><link>https://svtter.cn/tags/%E5%BC%80%E6%BA%90/</link><description>Recent content in 开源 on Svtter's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 09 May 2026 12:00:00 +0800</lastBuildDate><atom:link href="https://svtter.cn/tags/%E5%BC%80%E6%BA%90/index.xml" rel="self" type="application/rss+xml"/><item><title>sth：一个给 AI Agent 用的 HTML 预览服务器</title><link>https://svtter.cn/p/sth%E4%B8%80%E4%B8%AA%E7%BB%99-ai-agent-%E7%94%A8%E7%9A%84-html-%E9%A2%84%E8%A7%88%E6%9C%8D%E5%8A%A1%E5%99%A8/</link><pubDate>Sat, 09 May 2026 12:00:00 +0800</pubDate><guid>https://svtter.cn/p/sth%E4%B8%80%E4%B8%AA%E7%BB%99-ai-agent-%E7%94%A8%E7%9A%84-html-%E9%A2%84%E8%A7%88%E6%9C%8D%E5%8A%A1%E5%99%A8/</guid><description>&lt;img src="https://svtter.cn/p/sth%E4%B8%80%E4%B8%AA%E7%BB%99-ai-agent-%E7%94%A8%E7%9A%84-html-%E9%A2%84%E8%A7%88%E6%9C%8D%E5%8A%A1%E5%99%A8/cover.jpg" alt="Featured image of post sth：一个给 AI Agent 用的 HTML 预览服务器" /&gt;&lt;p&gt;我开源了一个小工具：&lt;a class="link" href="https://github.com/sun-praise/static-html" target="_blank" rel="noopener"
&gt;static-html&lt;/a&gt;，命令行叫 &lt;code&gt;sth&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;它做的事情很简单：提供一个 HTTP 服务，让你把本地生成的 HTML 文件注册上去，然后在浏览器里预览。&lt;/p&gt;
&lt;h2 id="为什么需要这个东西"&gt;为什么需要这个东西
&lt;/h2&gt;&lt;p&gt;问题出在 AI Agent 的输出上。&lt;/p&gt;
&lt;p&gt;现在我用 Claude Code、OpenCode 这些 agent 干活，它们经常需要输出一些复杂的内容——代码评审汇总、对比分析、报价单、架构设计文档。这些内容用纯文本发到 Telegram 里，格式全乱了，表格看不了，代码高亮也没了。&lt;/p&gt;
&lt;p&gt;总而言之就是一大坨。&lt;/p&gt;
&lt;p&gt;最开始的做法是让 agent 直接在本地生成 HTML 文件，然后用浏览器打开。但问题在于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;agent 跑在服务器上，没有图形界面&lt;/li&gt;
&lt;li&gt;本地生成的文件路径不确定，管理混乱&lt;/li&gt;
&lt;li&gt;没有历史记录，发过的东西找不到&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以我需要一个服务：agent 把 HTML 文件&amp;quot;发&amp;quot;上去，然后给一个 URL，在任何设备的浏览器里打开就能看。手机和 PC 兼容性直接让 agent 来搞定就行。&lt;/p&gt;
&lt;h2 id="sth-做了什么"&gt;sth 做了什么
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;sth&lt;/code&gt; 是一个 Go 写的轻量 HTTP 服务，核心就两个命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 启动服务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth start
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 发送 HTML 文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth send ./report.html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;sth send&lt;/code&gt; 会把目标 HTML 文件和同目录下的资源文件（CSS、JS、图片等）打包上传，然后返回一个 URL。打开这个 URL 就能看到完整的页面效果。&lt;/p&gt;
&lt;p&gt;实际跑在我的内网开发机上，agent 通过 &lt;code&gt;--server&lt;/code&gt; 参数指定远程地址：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth send ./report.html --server http://dev-1:3939
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="我的实际用法"&gt;我的实际用法
&lt;/h2&gt;&lt;p&gt;目前 &lt;code&gt;sth&lt;/code&gt; 主要跑在我的开发服务器上，和 Hermes Agent 配合使用。&lt;/p&gt;
&lt;p&gt;Hermes 是我的日常 AI assistant，跑在 Telegram 上。当它需要输出复杂内容时——比如代码评审结论、技术方案对比、项目报价——会调用 &lt;code&gt;html-report&lt;/code&gt; skill 生成一个格式精美的 HTML 文件，然后通过 &lt;code&gt;sth send&lt;/code&gt; 发到预览服务器，最后把 URL 发给我。&lt;/p&gt;
&lt;p&gt;整个流程是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;用户提问 -&amp;gt; Hermes Agent 分析
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 生成 HTML 报告（html-report skill）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; sth send 发到预览服务器
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -&amp;gt; 返回 URL -&amp;gt; 发到 Telegram
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样我在手机上点开链接就能看到排版良好的报告，而不是一坨纯文本。&lt;/p&gt;
&lt;h2 id="元数据管理"&gt;元数据管理
&lt;/h2&gt;&lt;p&gt;除了基本的发送和预览，&lt;code&gt;sth&lt;/code&gt; 还支持给 session 打标签、分类、关联项目：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth tag &amp;lt;session-id&amp;gt; code-review pricing
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth categorize &amp;lt;session-id&amp;gt; &lt;span class="s2"&gt;&amp;#34;技术评审&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth project &amp;lt;session-id&amp;gt; hydrogen-permeation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth list --project hydrogen-permeation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sth search &lt;span class="s2"&gt;&amp;#34;报价&amp;#34;&lt;/span&gt; --tag pricing
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个功能解决了一个实际问题：时间一长，发过的报告会积攒很多。通过标签和项目分类，可以快速找到之前的输出。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;list&lt;/code&gt; 和 &lt;code&gt;search&lt;/code&gt; 的区别在于：&lt;code&gt;list&lt;/code&gt; 是精确匹配元数据字段，&lt;code&gt;search&lt;/code&gt; 是全文搜索。两者可以组合使用。&lt;/p&gt;
&lt;h2 id="技术细节"&gt;技术细节
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;语言&lt;/strong&gt;：Go 1.24+&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储&lt;/strong&gt;：SQLite（&lt;code&gt;github.com/mattn/go-sqlite3&lt;/code&gt;，需要 CGO）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;部署&lt;/strong&gt;：单二进制文件，systemd 管理就行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;构建&lt;/strong&gt;：&lt;code&gt;go build -o dist/sth ./cmd/html-server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就这么简单，没有多余的依赖。&lt;/p&gt;
&lt;h2 id="开源"&gt;开源
&lt;/h2&gt;&lt;p&gt;这个工具之前是 private repo，今天刚改成 public：&lt;a class="link" href="https://github.com/sun-praise/static-html" target="_blank" rel="noopener"
&gt;sun-praise/static-html&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;如果你也在用 AI Agent 做日常开发工作，并且遇到过&amp;quot;agent 输出的复杂内容在聊天工具里没法看&amp;quot;的问题，可以试试 &lt;code&gt;sth&lt;/code&gt;。它足够轻量，够用就行。&lt;/p&gt;</description></item><item><title>探索 opencode 之后，我的一些思考</title><link>https://svtter.cn/p/opencode-three-months-reflection/</link><pubDate>Tue, 31 Mar 2026 11:30:00 +0800</pubDate><guid>https://svtter.cn/p/opencode-three-months-reflection/</guid><description>&lt;img src="https://svtter.cn/p/opencode-three-months-reflection/cover.jpg" alt="Featured image of post 探索 opencode 之后，我的一些思考" /&gt;&lt;blockquote&gt;
&lt;p&gt;一个开源工具，让我看清了&amp;quot;不被绑定&amp;quot;的价值，也让我重新理解了《大教堂与集市》&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="缘起选择-opencode-作为编程工具"&gt;缘起：选择 opencode 作为编程工具
&lt;/h2&gt;&lt;p&gt;之前我写了一篇博客——《高效省钱：我的 AI Agent 工作流选择》，分享了自己用 opencode + Gemini 3 Flash + 智谱免费 GLM 4.7 构建&amp;quot;省钱又不妥协&amp;quot;的 AI 编程助手的经验。&lt;/p&gt;
&lt;p&gt;当时我正想找一个性价比高的方案。Claude Code 的 Pro 计划一个月 20 美元，Max 计划则要 100 美元，对个人开发者来说确实不算便宜。而智谱的 Coding Plan Lite 套餐 20 元/月，加上 opencode 这个开源终端工具，正好组合成了一套&amp;quot;省钱&amp;quot;方案。&lt;/p&gt;
&lt;p&gt;真正打动我的，是 opencode 的一个核心特性：它支持 75 种以上的模型供应商——OpenAI、Anthropic、Google Gemini、智谱，甚至本地 Ollama。这意味着我随时可以换模型：用智谱的套餐日常开发，想尝鲜某家新模型时也能快速接入，不会被任何一家绑定。&lt;/p&gt;
&lt;p&gt;这正是我想要的：没有 vendor lock-in，不被&amp;quot;花钱的工具&amp;quot;绑架。我用谁家的模型，应该取决于模型能力，而不是因为工具只支持那一家。&lt;/p&gt;
&lt;p&gt;从 1 月开始，我就这样用起了 opencode + 智谱 Coding Plan。三个月下来，跑得很熟，体验也一直很稳定。&lt;/p&gt;
&lt;h2 id="转折github-上的积压让我心里一沉"&gt;转折：GitHub 上的&amp;quot;积压&amp;quot;让我心里一沉
&lt;/h2&gt;&lt;p&gt;直到最近，我随手翻了一下 opencode 的 GitHub 仓库。我看到了大量无人处理的 issue，还有堆了几周甚至几个月的 pull request，没人合并，没人回复。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://svtter.cn/p/opencode-three-months-reflection/pics/inline-01.jpg"
width="1200"
height="896"
srcset="https://svtter.cn/p/opencode-three-months-reflection/pics/inline-01_hu_bd038bed779bd657.jpg 480w, https://svtter.cn/p/opencode-three-months-reflection/pics/inline-01_hu_f26788b5e1da7bc3.jpg 1024w"
loading="lazy"
alt="大量无人处理的 PR 和 issue 堆积在 GitHub 上"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="321px"
&gt;&lt;/p&gt;
&lt;p&gt;我心里&amp;quot;嘶&amp;quot;了一下：&amp;ldquo;这项目是不是没人维护了？&amp;rdquo;&lt;/p&gt;
&lt;p&gt;后来我才知道，2026 年 3 月，Anthropic 向 opencode 发来了正式的法律要求，要求移除所有 Claude 相关的集成。项目方在 1.3.0 版本中执行了这件事，创始人 Dax Raad 公开回应：&amp;ldquo;我们尽力说服 Anthropic 支持开发者的选择权，但他们派了律师来。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;但说实话，这个法律事件本身我并不太担心。我只是一个用户，用 opencode 跑智谱的套餐，不涉及法律风险。真正让我在意的，是另一个问题——&lt;strong&gt;项目的工程治理能力&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;opencode 发展很快，功能越做越多，社区贡献者也越来越多。但从 GitHub 上的积压来看，核心团队对 issue 的分类、triage、PR review 的流程，明显没跟上项目膨胀的速度。PR 堆在那里，有人愿意贡献，但没人有精力、有流程去接住这些贡献。说白了就是：项目膨胀了，治理能力没跟上，积压是早晚的事。&lt;/p&gt;
&lt;p&gt;一个开源项目，长期没人处理贡献，社区慢慢就凉了。这跟&amp;quot;厂商锁定&amp;quot;是另一种层面的风险：开源工具也会因为没人维护而变得没法用。&lt;/p&gt;
&lt;h2 id="开源的安全垫历史版本可以继续用"&gt;开源的安全垫：历史版本可以继续用
&lt;/h2&gt;&lt;p&gt;但转念一想，我又释然了。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;因为是开源软件，所以 opencode 实际上就算是暂时不维护，我也可以使用历史版本。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;这个想法一下子点醒了我。开源软件和商业 SaaS 的区别就在这：商业工具一旦公司倒闭或停服，你就真的没了；开源项目，哪怕 GitHub 上再也没人合并 PR，我手上那个跑得很顺的版本，照样能用。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://svtter.cn/p/opencode-three-months-reflection/pics/inline-02.jpg"
width="1200"
height="896"
srcset="https://svtter.cn/p/opencode-three-months-reflection/pics/inline-02_hu_9c6b2d411a75c6aa.jpg 480w, https://svtter.cn/p/opencode-three-months-reflection/pics/inline-02_hu_b7f15e1f630cb77c.jpg 1024w"
loading="lazy"
alt="开源的安全垫：哪怕项目停滞，历史版本依然可以继续使用"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="321px"
&gt;&lt;/p&gt;
&lt;p&gt;模型 API 可能会升级，但那通常有缓冲期，而且 opencode 的 provider 抽象层是独立的，即使官方不更新，社区或我自己也可以 fork 改一下适配层。安全漏洞也许是个问题，但 coding agent 这类工具的风险主要在于代码执行权限，自己注意控制就好。&lt;/p&gt;
&lt;p&gt;所以，最坏情况我也能继续用现在的版本，不用急着迁移。但我会保持观察——如果几个月后积压依然严重，可能就要考虑备选方案了。&lt;/p&gt;
&lt;h2 id="大教堂与集市linus-为什么是大师"&gt;大教堂与集市：Linus 为什么是大师
&lt;/h2&gt;&lt;p&gt;积压这个问题，让我想到了《大教堂与集市》。&lt;/p&gt;
&lt;p&gt;Eric S. Raymond 把开源开发模式分成两种：大教堂模式（少数人精心设计、封闭开发）和集市模式（开放、迭代快、靠&amp;quot;足够多的眼睛&amp;quot;来捉 bug）。Linux 内核是集市模式的代表。Linus Torvalds 写的代码其实不算多，但他建立了一套让人放心的流程和权威——这才是重点。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://svtter.cn/p/opencode-three-months-reflection/pics/inline-03.jpg"
width="1200"
height="896"
srcset="https://svtter.cn/p/opencode-three-months-reflection/pics/inline-03_hu_27e02f9e72a13ff3.jpg 480w, https://svtter.cn/p/opencode-three-months-reflection/pics/inline-03_hu_44a4ec2ba45cf506.jpg 1024w"
loading="lazy"
alt="大教堂模式（左）：封闭、有序；集市模式（右）：开放、混沌但高效"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="321px"
&gt;&lt;/p&gt;
&lt;p&gt;集市模式能成功，关键在于有一个清晰的、被信任的维护者来合并代码、建立规范、保持方向。即便 Linus 某段时间回复慢，大家也知道规范在那里，最终会被处理。Linux 活到现在，靠的是大家相信&amp;quot;好代码最终会被合进去&amp;quot;，不是靠 PR 响应速度。&lt;/p&gt;
&lt;p&gt;用这个框架看 opencode，它一开始确实带着集市的气质：多模型支持、插件化、社区驱动、快速迭代。但最近积压的 issue 和 PR 暴露了一个问题：&lt;strong&gt;集市模式要运转，前提是有一只&amp;quot;看似松散但始终在运作的手&amp;quot;在合并代码&lt;/strong&gt;。这只手忙不过来了，集市也就乱了。&lt;/p&gt;
&lt;p&gt;opencode 缺的是机制，不缺热心人。&lt;/p&gt;
&lt;h2 id="我现在的态度继续用但保持关注"&gt;我现在的态度：继续用，但保持关注
&lt;/h2&gt;&lt;p&gt;我现在依然用着 opencode + 智谱 Coding Plan，日常开发没有任何问题。对于项目的未来，我的打算很简单：继续用，但不指望它一定会变好。现有版本够用，哪怕不再更新，我也能撑一段时间。我会关注积压的处理情况——如果两三个月后 PR 开始被清理、核心团队恢复沟通，说明扛过去了；如果还是没人管，就开始看别的方案。好在我选的就是开源方案，代码和数据都不会被锁死，这正是当初选它的原因。&lt;/p&gt;
&lt;h2 id="一点最后的想法"&gt;一点最后的想法
&lt;/h2&gt;&lt;p&gt;这件事让我重新理解了&amp;quot;开源工具 vs 商业 SaaS&amp;quot;。商业 SaaS 省心，但你被绑着。开源工具自由，但项目健康不健康得自己盯着。我还是倾向于开源——我不喜欢把命脉交给一家公司。不过这次也提醒了我：自由不是免费的，得自己盯生态、评风险、想好退路。&lt;/p&gt;
&lt;p&gt;Linus 早就说明白了，一个好的开源项目，光靠热情撑不住，得有一套让人信任的规则，还有源源不断愿意维护的人。我希望 opencode 能走过这段波折，继续做那个&amp;quot;不被任何一家模型绑架&amp;quot;的工具。&lt;/p&gt;
&lt;p&gt;好工具值得多一点耐心。但耐心也不是无限的。&lt;/p&gt;</description></item></channel></rss>