<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Louis Wu</title><link>https://me.micuks.click</link><description>Louis Wu&apos;s personal website</description><language>en-us</language><copyright>2021 – 2026 Louis Wu</copyright><managingEditor>hey@me.micuks.click</managingEditor><webMaster>hey@me.micuks.click</webMaster><lastBuildDate>Fri, 24 Jul 2026 10:55:47 +0000</lastBuildDate><item><title>把 myflicker 接到 CLIProxyAPI</title><link>https://me.micuks.click/articles/myflicker-as-cliproxyapi-provider</link><description><![CDATA[本地对齐 Takumi 流量，把万擎挂进 CLIProxyAPI，再用 claudem 开 Claude Code。顺手记下网关对 Claude Code 的 403。]]></description><author>Louis Wu</author><guid>https://me.micuks.click/articles/myflicker-as-cliproxyapi-provider</guid><pubDate>Fri, 24 Jul 2026 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>CLIProxyAPI 擅长把 Claude Code、Codex 这类订阅收成标准 HTTP。我想做的是补另一头：让公司的 myflicker（万擎）也成为它的 upstream。</p>
<p>配置文件里填个 base URL？不行。myflicker 不提供本地 <code>/v1</code>。请求真正打到 Takumi 的几条网关，而且还要带机器绑定的签名。我一开始路径写错，拿到一串 404；后来才发现签名其实已经过了，只是 URL 对不上。</p>
<h2><a href="#抓真实请求" aria-hidden="true" class="anchor" id="抓真实请求"></a>抓真实请求</h2>
<p>源码里能抠出签名逻辑，但路径和模型名仍容易猜偏。更省事的是让 CLI 自己发请求，用 Node hook 住 <code>fetch</code> / <code>https.request</code>，只记录发往 <code>takumi.corp.kuaishou.com</code> 的流量。</p>
<p><code>myflicker call models.test --model=wanqing/...</code> 比完整 agent 会话干净。抓完以后，路由大致是：</p>
<ul>
<li>Claude / GLM / Kimi → <code>POST /rest/wanqing/api/gateway/v1/messages</code></li>
<li>GPT-5.6 的 sol / luna / terra → <code>POST .../gateway/v1/responses?api-version=v1</code>（这个口基本要求 <code>stream: true</code>）</li>
<li>DeepSeek 等 ep 模型 → <code>POST .../gateway/v1/endpoints/chat/completions</code></li>
</ul>
<p>另外几个细节：<code>x-takumi-username</code> 是小写；body 里的 model 要用 <code>epModelName</code>（例如 <code>claude-4.6-sonnet-ep</code>、<code>GPT-5.6-Sol</code>）；版本号也要跟当前 CLI 一致。</p>
<h2><a href="#本地-openai-垫层" aria-hidden="true" class="anchor" id="本地-openai-垫层"></a>本地 OpenAI 垫层</h2>
<p>我写了个很小的 Node 代理，默认听 <code>:13456</code>。外面是 OpenAI <code>chat/completions</code>，里面按上面三种格式转发，鉴权头按真实 CLI 流量补齐。Ed25519 还是用本机 <code>~/.myflicker/cli-sig.json</code> 解出的私钥，payload 是 timestamp 加上 tools 数量。</p>
<p>没积分时，官方 CLI 和这个代理会一起 402。这反而好排查：路通了，只是账上没钱。充完以后，<code>ds-pro</code>、<code>kimi-k3</code>、<code>sol</code>、<code>opus</code> 都能正常返回。</p>
<p>GPT 那条有过一次教训：非流式 JSON 打 responses 口，会报 <code>The model does not support v1/responses</code>。代理里对这类模型强制上游流式，再把 SSE 收成一次 chat.completion。</p>
<p>Anthropic 口这边，代理默认上游非流式，再在本地拼成 OpenAI SSE。Claude Code / CLIProxyAPI 一直在等 event-stream；如果直接回整包 JSON，CPA 会变成 502，看起来像代理坏了。</p>
<p>tool 历史也要按 Anthropic 形状转：<code>tool_calls</code> 变成 <code>tool_use</code>，<code>role: tool</code> 变成带 <code>tool_result</code> 的 user 消息。早先我把 tool 结果当成普通 user 文本塞回去，网关也不吃。</p>
<h2><a href="#挂到-cliproxyapi" aria-hidden="true" class="anchor" id="挂到-cliproxyapi"></a>挂到 CLIProxyAPI</h2>
<p>本机本来就有 claudex 用的 CPA，占着 <code>:8317</code>。万擎另开一份配置听 <code>:8318</code>，<code>openai-compatibility</code> 指到 <code>http://127.0.0.1:13456/v1</code>。别名按自己习惯写：<code>opus</code>、<code>sonnet</code>、<code>sol</code>、<code>kimi-k3</code>。</p>
<p>客户端 key 我不想记，就把 <code>api-keys</code> 留空。CPA 的规则是列表为空则开放访问；服务只绑 <code>127.0.0.1</code>，可以接受。</p>
<p>早先的 402 还会把凭证打进冷却，后面全变成 <code>auth_unavailable</code>。配置加了 <code>disable-cooling: true</code>，并重启过服务。</p>
<h2><a href="#claudem" aria-hidden="true" class="anchor" id="claudem"></a>claudem</h2>
<p>HTTP 通了之后，还差一个跟 <code>claudex</code> 对称的入口。<code>claudem</code> 很薄：确认 launchd 里的 takumi-proxy 和 CPA 还活着，设 <code>ANTHROPIC_BASE_URL=http://127.0.0.1:8318</code>，然后 exec Claude Code。仓库在 <a href="https://github.com/Micuks/claudem">Micuks/claudem</a>（private）。</p>
<p>选模型：</p>
<pre class="language-bash"><span class="source shell bash"><span class="meta function-call shell"><span class="variable function shell">claudem</span></span><span class="meta function-call arguments shell"><span class="variable parameter option shell"><span class="punctuation definition parameter shell"> --</span>model          <span class="comment line number-sign shell"><span class="punctuation definition comment begin shell">#</span></span><span class="comment line number-sign shell"> 读万擎列表，选完写成默认</span><span class="comment line number-sign shell">
</span></span></span><span class="meta function-call shell"><span class="variable function shell">claudem</span></span><span class="meta function-call arguments shell"><span class="variable parameter option shell"><span class="punctuation definition parameter shell"> --</span>model</span> sol      <span class="comment line number-sign shell"><span class="punctuation definition comment begin shell">#</span></span><span class="comment line number-sign shell"> 只影响这一次</span><span class="comment line number-sign shell">
</span></span><span class="meta function-call shell"><span class="storage modifier shell">export</span> <span class="variable other readwrite assignment shell">CLAUDEM_MODEL</span><span class="keyword operator assignment shell">=</span><span class="string unquoted shell">terra</span></span>
</span></code></pre>
<p>列表默认读 <code>~/.myflicker/cli-model-list-cache.json</code>。超过 TTL（默认 6 小时）就带着本机 token 去刷 <code>/rest/codeflicker/model/list</code>，再写回缓存。默认值落在 <code>~/.config/claudem/config</code>。</p>
<h2><a href="#claude-code-的-403" aria-hidden="true" class="anchor" id="claude-code-的-403"></a>Claude Code 的 403</h2>
<p>小请求好好的，一进真实 Claude Code 会话就变成 <code>403 非法请求来源</code>。界面还会让你 <code>/login</code>。跟 Anthropic 登录无关，是万擎网关在拦。</p>
<p>我复现到的硬条件有两条：</p>
<ol>
<li>system 里出现 <code>You are Claude Code...</code>。改成普通 coding agent 表述就过。</li>
<li>工具名正好叫 <code>Edit</code> 或 <code>Read</code>。改成 <code>FileEdit</code> / <code>FileRead</code> 发出去，回程再映回原名，Claude Code 无感。</li>
</ol>
<p>代理里现在默认做这两件事。更新 <code>takumi-proxy.js</code> 后记得 <code>launchctl kickstart</code> 一下对应的 LaunchAgent。</p>
<h2><a href="#边界" aria-hidden="true" class="anchor" id="边界"></a>边界</h2>
<p>这套东西绑着你的 myflicker 登录态和当前主机名。<code>cli-sig.json</code> 换机器基本搬不走。公司网关、积分、合规都还在，别把它当公共 API。</p>
<p>对我自己，问题更窄：Claude Code 想用万擎时，不必再开另一套平行流程。</p>
]]></content:encoded></item><item><title>Blog admin smoke</title><link>https://me.micuks.click/articles/blog-admin-smoke-20260724</link><description><![CDATA[Published via blog-admin CMS]]></description><author>Louis Wu</author><guid>https://me.micuks.click/articles/blog-admin-smoke-20260724</guid><pubDate>Fri, 24 Jul 2026 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>This post was published from <strong>blog-admin</strong> in one click.</p>
<p>If you can read this on me.micuks.click, the pipeline works.</p>
<p><img src="/articles/blog-admin-smoke-20260724/ba-smoke.png" alt="smoke" /></p>
]]></content:encoded></item><item><title>How to read paper</title><link>https://me.micuks.click/articles/how-to-read-paper</link><description><![CDATA[Introduce a way to read paper easily and efficiently]]></description><author>Louis Wu</author><guid>https://me.micuks.click/articles/how-to-read-paper</guid><pubDate>Tue, 02 Jan 2024 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>After you have chosen a topic that you are interested in or you decide to take a profession in, you should find research papers related to the topic. I recommend <a href="paperswithcode.com">PapersWithCode</a>, where you can find latest papers in your region, with its datasets, code and other related materials.</p>
<p>Pick the paper that catches your attention, now it’s time to read.</p>
<h2><a href="#first-pass-gaining-context-and-understanding" aria-hidden="true" class="anchor" id="first-pass-gaining-context-and-understanding"></a>First pass: Gaining context and understanding</h2>
<p>Instead of reading the paper from beginning to end with writing notes, the first pass should get the following things:</p>
<ul>
<li>Assure the paper is relevant</li>
<li>Get the paper’s main idea from title, abstract and conclusion</li>
<li>Recognize the author’s goals, methodology and what he has done</li>
</ul>
<p>The header can tell you the main idea about the paper, and can help you know whether the paper is related quickly. The abstract is the shorten version of the full paper. By reading the abstract you can know what the paper have done and what dataset/algorithm it used. The conclusion is another abstract, which tells you what the author have done, what the author plan to do. This can help to know if the researcher’s contributions, problem domain and outcomes match your needs.</p>
<h2><a href="#second-pass-content-familiarization" aria-hidden="true" class="anchor" id="second-pass-content-familiarization"></a>Second pass: Content familiarization</h2>
<p>Read the Introduction section and figures, diagrams and tables to get familiar with the paper’s knowledge.</p>
<p>In Introduction section there’s the objective of the research efforts. It mentions and explains problem domains, research scope, prior research effects and methodologies. After getting familiar with required knowledge, it will be easier to go deeper with the paper.</p>
<p>Figures, diagrams and tables are visual representation of data and performance, which enables readers to get an intuitive understanding of the paper’s context.</p>
<h2><a href="#third-pass-deep-reading" aria-hidden="true" class="anchor" id="third-pass-deep-reading"></a>Third pass: Deep reading</h2>
<p>Read deeper into the paper, read all sections in the paper, except those complex arithmetic or technique formulations that may be difficult for you. You may mark them, and return to later.</p>
<p>Read from abstract to conclusion during this pass, and take notes about key insights and takeaways, alongside the unfamiliar terms and concepts.</p>
<p>To manage time you can use *<em>The Pomodoro Technique</em>. For example, 50/15 split is good for me, which means study for 50 mins and take 15 mins break after that. Moreover, you can take a 30 mins break after executing the split twice.</p>
<h2><a href="#forth-pass-final-pass" aria-hidden="true" class="anchor" id="forth-pass-final-pass"></a>Forth pass: Final pass</h2>
<p>The final pass involves a thorough reading of the whole paper, including all those concepts, complex algorithms you marked and skipped before. So this is an exertion of your mental and learning ability.</p>
<p>This pass have no specified time length, it may take from days to weeks. But in this pass, you can get some help with the Reference section, for it’s where the current paper draws inspiration from of builds upon.</p>
<h2><a href="#final-step-summary" aria-hidden="true" class="anchor" id="final-step-summary"></a>Final step: Summary</h2>
<p>Considering human’s short-time memory is small and easy-to-lose, it’s a good way to rewrite new information in your own way, either typed or written. This can help you retain new knowledge in your long-term memory.</p>
<p>What’s more, you can post those notes through blog or social media. If the words you wrote can help someone who is unfamiliar with the scope to understand, it means you have thoroughly obtained the new knowledge you wrote.</p>
]]></content:encoded></item><item><title></title><link>https://me.micuks.click/articles/hello-world</link><description><![CDATA[My first blogpost (not really).]]></description><author>Louis Wu</author><guid>https://me.micuks.click/articles/hello-world</guid><pubDate>Sun, 13 Feb 2022 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>I’ve had many blogs, but this is the first post on this site, so stay tuned. ❤️</p>
]]></content:encoded></item><item><title>.vim-project</title><link>https://me.micuks.click/articles/vim-projects</link><description><![CDATA[This post explains how to get project-specific Vim settings.]]></description><author>Louis Wu</author><guid>https://me.micuks.click/articles/vim-projects</guid><pubDate>Thu, 14 Aug 2014 00:00:00 +0000</pubDate><content:encoded><![CDATA[<p>If you’re using Vim, you know that feel (if you aren’t, you can skip this
article): Everytime you open a project, you toggle
<a href="https://github.com/scrooloose/nerdtree">NERDTREE</a> and
<a href="https://github.com/majutsushi/tagbar">Tagbar</a> (or similar). But you don’t
want to put that in your <code>.vimrc</code>, because then they’d open every time, even
when you just want to quickly edit a file.</p>
<!-- more -->
<h2><a href="#but-wait" aria-hidden="true" class="anchor" id="but-wait"></a>But wait</h2>
<p>Sublime Text does have a <code>&lt;name&gt;.sublime-project</code>, which holds configuration
for the curent project. Why doesn’t Vim has something like that?</p>
<h2><a href="#just-do-it-yourself" aria-hidden="true" class="anchor" id="just-do-it-yourself"></a>Just do it yourself</h2>
<p>It’s not hard, paste the following lines anywhere in your <code>.vimrc</code>:</p>
<pre class="language-vim"><span class="source viml"><span class="keyword control viml">if</span> <span class="support function any-method">filereadable</span>(<span class="support function any-method">expand</span>(<span class="string quoted double viml">&quot;.vim-project&quot;</span>))
  source <span class="storage function viml">.</span>vim-project
<span class="keyword control viml">endif</span>
</span></code></pre>
<p>You can now create a <code>.vim-project</code>-file anywhere you want and just write
stuff in it like in your <code>.vimrc</code>, this is one of mine:</p>
<pre class="language-vim"><span class="source viml"><span class="support function viml">autocmd</span> VimEnter <span class="storage function viml">*</span> NERDTree
<span class="support function viml">autocmd</span> VimEnter <span class="storage function viml">*</span> Tagbar
</span></code></pre>
<p><em>Note: You may want to close Vim automatically after all windows but NERDTree
are closed, see the <a href="https://github.com/scrooloose/nerdtree#faq">FAQs</a> for
that.</em></p>
]]></content:encoded></item></channel></rss>