<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>渊 YuanLog</title>
  <link>https://yuanclaw.eu.cc</link>
  <description>在代码与未来之间，保持好奇。技术笔记、项目实验与读书心得。</description>
  <language>zh-CN</language>
  <lastBuildDate>Fri, 21 Aug 2026 11:50:12 GMT</lastBuildDate>
  <item>
  <title>Claude Code 指令（中文版）</title>
  <link>https://yuanclaw.eu.cc/article/claude-code-instructions-zh</link>
  <guid>https://yuanclaw.eu.cc/article/claude-code-instructions-zh</guid>
  <pubDate>Mon, 13 Jul 2026 00:00:00 GMT</pubDate>
  <description>Claude Code 指令文件中文版 — AI 编程助手最佳实践参考，涵盖规则、工作流、验证、技能路由与代理使用。</description>
  <content:encoded><![CDATA[<pre><code># Claude Code 指令

## 全局规则

- 在编辑之前，先理解目标及现有上下文。
- 仅在歧义会实质性改变结果时才发问。
- 不捏造文件、命令、API、来源、测试结果或完成状态。
- 除非明确指示，否则不覆盖、回退或删除用户的修改。
- 不暴露 token、API 密钥、本地机密或私有配置。
- 区分已确认的事实、假设、猜测、失败尝试和未验证的主张。

## 工作流

- 小型任务可直接处理；复杂、跨文件或高风险任务需先制定简短计划。
- 独立的搜索、读取和检查可并行执行；有依赖或有重叠的工作串行执行。
- 遵循项目现有的风格、工具、脚本、框架和惯例。
- 用最少的代码解决实际问题。
- 不为假设的未来用途创建抽象。
- 每次代码变更都应可追溯到用户的请求。
- 避免无关的格式化、重命名、清理或重构。

## 验证与报告

- 代码变更后，运行最相关的可用检查：测试、类型检查、lint、构建、复现或手动验证。
- 若未运行验证，说明原因并提示剩余风险。
- 不将已尝试视为已解决，也不将部分完成视为完全成功。
- 最终回复应简洁：改了什么、验证了什么、哪些仍待验证或存在风险。

## 技能路由

- 多步骤工作、子代理、状态标签、部分完成、受阻工作或验证敏感型报告，使用 agent-integrity。
- 调试反复失败、推测性修复堆积或下一步需要假设驱动证据时，使用 anti-stuck-debugging。
- 非平凡的代码变更、重构、bug 修复、高风险编辑或跨文件修改时，使用 code-change-discipline。

## 代理使用

- Explore：只读搜索、文件发现和结构检查。
- Plan / Architect：设计、架构或高风险变更规划。
- General-purpose：具体实现。
- Reviewer：复杂、高风险、跨文件或面向用户的代码审查；小型集中式修改无需重量级审查。
- 不要让多个代理并行编辑同一文件。</code></pre>]]></content:encoded>
</item>
  <item>
  <title>Claude Code Instructions</title>
  <link>https://yuanclaw.eu.cc/article/claude-code-instructions-en</link>
  <guid>https://yuanclaw.eu.cc/article/claude-code-instructions-en</guid>
  <pubDate>Mon, 13 Jul 2026 00:00:00 GMT</pubDate>
  <description>My Claude Code instruction file — a reference for AI coding assistant best practices covering rules, workflow, verification, skill routing and agent usage.</description>
  <content:encoded><![CDATA[<pre><code># Claude Code Instructions

## Global Rules

- Understand the goal and existing context before editing.
- Ask only when ambiguity would materially change the result.
- Do not fabricate files, commands, APIs, sources, test results, or completion status.
- Do not overwrite, revert, or delete user changes unless explicitly instructed.
- Do not expose tokens, API keys, local secrets, or private config.
- Separate confirmed facts, assumptions, guesses, failed attempts, and unverified claims.

## Workflow

- Small tasks can be handled directly; complex, cross-file, or risky tasks need a short plan first.
- Parallelize independent searches, reads, and checks; run dependent or overlapping work serially.
- Match existing project style, tools, scripts, frameworks, and conventions.
- Use the least code needed to solve the actual problem.
- Do not create abstractions for hypothetical future use.
- Keep every code change traceable to the user's request.
- Avoid unrelated formatting, renaming, cleanup, or refactors.

## Verification &amp; Reporting

- After code changes, run the most relevant available check: test, type check, lint, build, reproduction, or manual verification.
- If verification was not run, say why and mention the remaining risk.
- Do not treat "attempted" as "resolved" or partial completion as full success.
- Final responses should be concise: what changed, what was verified, what remains unverified or risky.

## Skill Routing

- Use agent-integrity for multi-step work, subagents, status labels, partial completion, blocked work, or verification-sensitive reporting.
- Use anti-stuck-debugging when debugging repeats, speculative fixes accumulate, or the next step needs hypothesis-driven evidence.
- Use code-change-discipline for non-trivial code changes, refactors, bug fixes, risky edits, or multi-file changes.

## Agent Usage

- Explore: read-only search, file discovery, and structure inspection.
- Plan / Architect: design, architecture, or risky change planning.
- General-purpose: implementation.
- Reviewer: complex, risky, cross-file, or user-facing code review; small focused edits do not need a heavyweight review.
- Do not let multiple agents edit the same files in parallel.</code></pre>]]></content:encoded>
</item>
  <item>
  <title>Claude 接入微信完整教程</title>
  <link>https://yuanclaw.eu.cc/article/claude-wechat-tutorial</link>
  <guid>https://yuanclaw.eu.cc/article/claude-wechat-tutorial</guid>
  <pubDate>Tue, 23 Jun 2026 00:00:00 GMT</pubDate>
  <description>让 Claude Code 通过企业微信收发微信消息的完整教程：从架构设计、VPS 部署、LLM 代理到任务同步，约 2 小时完成。</description>
  <content:encoded><![CDATA[<h1>Claude 接入微信完整教程</h1>

<blockquote>适用场景：让 Claude Code 通过企业微信收发微信消息，支持文字对话、图片识图和任务进度查询</blockquote>
<blockquote>难度：中等，需一台 Linux VPS + 一个企微账号 + Docker 基本操作</blockquote>
<blockquote>耗时：约 2 小时</blockquote>

<hr>

<h2>一、架构总览</h2>

<pre><code>微信扫码发消息
    ↓
企微回调 → your.domain.com (:80)
    ↓ nginx 反向代理
VPS 回调服务 (:18909) → 解密/存储消息 → 调用 deepseek-vision 代理 (:8000)
    ↓                                    ↓
企微 API 回复 ← 生成回复              ├── 文字 → DeepSeek / 其他 LLM
                                       └── 图片 → Qwen 识图 → LLM 生成描述</code></pre>

<h3>涉及的主机</h3>

<tr><td>主机</td><td>角色</td></tr>
<tr><td>---</td><td>---</td></tr>
<tr><td>本地桌面</td><td>Claude Code 终端 + 微信消息轮询</td></tr>
<tr><td>VPS</td><td>回调服务 + deepseek-vision 代理 + nginx</td></tr>
<tr><td>企微后台</td><td>消息回调 URL 配置 + 微信插件</td></tr>

<hr>

<h2>二、前置准备</h2>

<tr><td>资源</td><td>说明</td><td>获取方式</td></tr>
<tr><td>---</td><td>---</td><td>---</td></tr>
<tr><td>企业微信账号</td><td>需管理员权限</td><td><a href="https://work.weixin.qq.com">work.weixin.qq.com</a> 注册</td></tr>
<tr><td>Linux VPS</td><td>1 核 1G 即可</td><td>任意云厂商</td></tr>
<tr><td>域名</td><td>需公网可达，有 SSL 更佳</td><td>任意域名商</td></tr>
<tr><td>DeepSeek API Key</td><td>文本对话</td><td><a href="https://platform.deepseek.com">platform.deepseek.com</a></td></tr>
<tr><td>DashScope API Key</td><td>图片识图（免费额度够用）</td><td><a href="https://dashscope.aliyun.com">dashscope.aliyun.com</a></td></tr>
<tr><td>Docker</td><td>VPS 上需预装</td><td><code>curl -fsSL https://get.docker.com | sh</code></td></tr>

<hr>

<h2>三、本地配置</h2>

<h3>3.1 目录结构</h3>

<pre><code>~/.claude/
├── .mcp.json              # MCP 服务器配置
├── settings.json          # 钩子配置
├── cache/
│   └── task-session.json  # 任务状态缓存
└── test/wework-bot/
    ├── server.js           # 本地 MCP 服务器（可选，提供 wework_* 工具）
    ├── wework-client.js    # 企微 API 客户端
    ├── config.json         # 配置
    ├── config.legacy.json  # 企微凭证 ⚠️ 需 gitignore
    ├── server-vps.mjs      # VPS 回调服务（核心）
    ├── wework-poll.sh      # 轮询脚本
    ├── task-status.sh      # 手工任务状态同步
    ├── sync-task-status.py # Stop 钩子自动同步
    └── .gitignore</code></pre>

<h3>3.2 MCP 配置 (<code>~/.claude/.mcp.json</code>)</h3>

<pre><code>{
  "mcpServers": {
    "wework": {
      "type": "stdio",
      "command": "node",
      "args": ["&lt;你的路径&gt;/test/wework-bot/server.js"],
      "env": {
        "WEWORK_CONFIG": "&lt;你的路径&gt;/test/wework-bot/config.json",
        "WEWORK_LOG_DIR": "&lt;你的路径&gt;/test/wework-bot/logs"
      }
    }
  }
}</code></pre>

<blockquote>⚠️ <code>.mcp.json</code> 必须放在 Claude Code 实际读取的配置目录下。部分环境（如 Windows 软链接目录）可能导致路径不被识别，确认 <code>settings.json</code> 所在目录即为正确位置。</blockquote>

<h3>3.3 钩子配置</h3>

<p>在 <code>settings.json</code> 中添加：</p>

<p><strong>SessionStart</strong>：启动微信轮询</p>
<pre><code>{
  "hooks": {
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "bash &lt;你的路径&gt;/test/wework-bot/wework-poll.sh",
        "async": true
      }]
    }]
  }
}</code></pre>

<p><strong>Stop</strong>：自动同步任务状态到 VPS</p>
<pre><code>{
  "hooks": {
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python &lt;你的路径&gt;/test/wework-bot/sync-task-status.py"
      }]
    }]
  }
}</code></pre>

<hr>

<h2>四、VPS 部署</h2>

<h3>4.1 VPS 目录规划</h3>

<pre><code>/opt/
├── wecom-callback/         # 回调服务
│   ├── server.mjs          # 主服务（Node.js）
│   ├── config.json         # 凭证 + autoReply 配置 ⚠️ 600 权限
│   ├── merge-tasks.py      # 任务合并脚本
│   ├── task-status.json    # 任务状态数据
│   ├── events.log          # 运行日志
│   └── inbox.jsonl         # 消息收件箱
│
└── deepseek-vision/        # LLM 代理
    ├── .env                # 环境变量 ⚠️ 600 权限
    └── ...</code></pre>

<h3>4.2 回调服务 (<code>server.mjs</code>)</h3>

<p>核心功能：</p>
<li>解密企微回调消息</li>
<li>文本消息 → 自动调 AI 回复（带对话记忆 20 轮）</li>
<li>图片消息 → 下载 → 调 deepseek-vision 代理识图 → AI 回复</li>
<li>检测"任务/进度"关键词 → 注入 <code>task-status.json</code> → AI 回答</li>
<li>提供 <code>/inbox</code> 相关 API（供本地轮询使用）</li>

<p>服务绑定 <code>127.0.0.1:18909</code>，不直接对外暴露。</p>

<blockquote>完整代码见附录 A。</blockquote>

<h3>4.3 deepseek-vision 代理</h3>

<p>基于开源项目 <a href="https://github.com/ErlichLiu/deepseek-vision">ErlichLiu/deepseek-vision</a> 部署，为纯文本 LLM API 补齐视觉理解能力。</p>

<p><strong>部署步骤</strong>：</p>

<pre><code>cd /opt
git clone https://github.com/ErlichLiu/deepseek-vision.git
cd deepseek-vision

# ⚠️ 修复 Dockerfile 缺少 README.md 的问题
sed -i 's/^COPY pyproject.toml .\/$/COPY pyproject.toml README.md .\//' Dockerfile</code></pre>

<p><strong>创建 <code>.env</code></strong>（权限 600）：</p>
<pre><code># 必填
ADMIN_PASSWORD=&lt;你自己设的密码&gt;
MASTER_API_KEY=&lt;客户端访问本代理的 Key&gt;
DEEPSEEK_API_KEY=&lt;你的 DeepSeek Key&gt;

# 视觉识别（去 dashscope.aliyun.com 申请免费 Key）
VISION_API_KEY=&lt;你的 DashScope Key&gt;

# 高级
DEEPSEEK_BASE_URL=https://api.deepseek.com/anthropic
PORT=8000</code></pre>

<p><strong>构建并启动</strong>：</p>
<pre><code>docker build -t deepseek-vision .
docker run -d --name deepseek-vision --restart unless-stopped \
  --env-file /opt/deepseek-vision/.env \
  -p 127.0.0.1:8000:8000 deepseek-vision</code></pre>

<blockquote>⚠️ 修改 <code>.env</code> 后必须 <code>docker rm -f deepseek-vision</code> 再 <code>docker run</code>，单纯的 <code>docker restart</code> 不会重读 <code>.env</code>。</blockquote>

<h3>4.4 nginx 配置</h3>

<pre><code>server {
    listen 80;
    server_name your.domain.com;

    # 企微回调 — 必须公网可达
    location / {
        proxy_pass http://127.0.0.1:18909;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 收件箱/回复/聊天管理 API — 仅本地访问
    location /inbox {
        allow 127.0.0.1;
        deny all;
        proxy_pass http://127.0.0.1:18909;
    }
    location /reply {
        allow 127.0.0.1;
        deny all;
        proxy_pass http://127.0.0.1:18909;
    }
    location /chat {
        allow 127.0.0.1;
        deny all;
        proxy_pass http://127.0.0.1:18909;
    }
}</code></pre>

<hr>

<h2>五、企微后台配置</h2>

<h3>5.1 创建应用</h3>

<p>1. 登录 <a href="https://work.weixin.qq.com/wework_admin">企业微信管理后台</a></p>
<p>2. 应用管理 → 创建应用 → 记录 <strong>AgentID</strong> 和 <strong>Secret</strong></p>
<p>3. 记下 <strong>企业 ID (corpId)</strong>：在「我的企业」→「企业信息」页底部</p>

<h3>5.2 API 接收消息</h3>

<p>应用详情 → 接收消息 → 设置 API 接收：</p>

<tr><td>字段</td><td>说明</td></tr>
<tr><td>---</td><td>---</td></tr>
<tr><td>URL</td><td><code>http://your.domain.com/</code></td></tr>
<tr><td>Token</td><td>随机字符串（自己生成，记下来）</td></tr>
<tr><td>EncodingAESKey</td><td>随机 43 位（后台可自动生成）</td></tr>

<p>三项填写后与 VPS 回调服务 <code>config.json</code> 保持一致即可。保存时企微会发起 URL 验证，服务正常返回即通过。</p>

<h3>5.3 微信插件（关键步骤）</h3>

<p><strong>路径</strong>：管理后台 → <strong>我的企业</strong> → 微信插件（⚠️ 不在应用管理里）</p>

<p>关键设置：</p>
<li>✅ 勾选「允许成员在微信插件中接收和回复聊天消息」</li>
<li>❌ <strong>不要</strong>勾选「成员使用微信插件时需要使用企业微信客户端」</li>
<li>生成邀请二维码（有效期 7 天），发给微信好友扫码即可在微信里对话</li>

<hr>

<h2>六、VPS 回调服务配置 (<code>config.json</code>)</h2>

<pre><code>{
  "token": "&lt;你的 Token&gt;",
  "encodingAESKey": "&lt;你的 EncodingAESKey&gt;",
  "corpId": "&lt;你的企业 ID&gt;",
  "secret": "&lt;你的应用 Secret&gt;",
  "agentId": "&lt;你的 AgentID&gt;",
  "autoReply": {
    "enabled": true,
    "proxyUrl": "http://127.0.0.1:8000/v1/messages",
    "proxyKey": "&lt;MASTER_API_KEY&gt;",
    "model": "deepseek-v4-flash",
    "apiKey": "&lt;你的 DeepSeek Key&gt;",
    "systemPrompt": "你的 System Prompt，定义 AI 的人设和回复风格"
  }
}</code></pre>

<hr>

<h2>七、任务状态同步机制</h2>

<h3>原理</h3>

<pre><code>Claude Code 会话结束
    → Stop 钩子触发
    → sync-task-status.py 读取本地 cache/task-session.json
    → SSH stdin 管道 → VPS merge-tasks.py（按任务名 upsert）
    → task-status.json 原子写入
    → 微信问"进度"时自动注入 AI 上下文</code></pre>

<h3>手工同步</h3>

<pre><code>bash task-status.sh --add "任务名" "详情"
bash task-status.sh --done "任务名"
bash task-status.sh --list
bash task-status.sh --clear</code></pre>

<hr>

<h2>八、安全措施清单</h2>

<tr><td>检查项</td><td>措施</td></tr>
<tr><td>---</td><td>---</td></tr>
<tr><td>VPS 配置文件</td><td><code>chmod 600 config.json .env</code></td></tr>
<tr><td>收件箱 API</td><td>nginx <code>allow 127.0.0.1; deny all;</code></td></tr>
<tr><td>密钥文件</td><td>加入 <code>.gitignore</code>（config.legacy.json, .mcp.json, .env）</td></tr>
<tr><td>Docker 容器</td><td>非 root 用户运行</td></tr>
<tr><td>回调服务</td><td>仅绑定 <code>127.0.0.1</code>，不对外监听</td></tr>
<tr><td>API Key 存放</td><td>单一配置文件，不硬编码在代码中</td></tr>

<h3>注意</h3>

<li>Claude Code 的 <code>~/.claude/projects/</code> 目录下的 transcript <code>.jsonl</code> 文件会包含会话中出现的 API Key</li>
<li><code>~/.claude/file-history/</code> 有文件历史版本，同样可能含 Key</li>
<li>这些是 Claude Code 内部日志，用于会话恢复和审计，建议定期清理旧会话</li>

<hr>

<h2>九、常见问题 &amp; 踩坑记录</h2>

<h3>9.1 启动/部署相关</h3>

<tr><td>问题</td><td>原因</td><td>解决</td></tr>
<tr><td>---</td><td>---</td><td>---</td></tr>
<tr><td>MCP 工具未加载</td><td><code>.mcp.json</code> 不在正确配置目录</td><td>确认目录与 <code>settings.json</code> 同路径</td></tr>
<tr><td>Docker 容器启动后识图不工作</td><td><code>docker restart</code> 不重读 <code>.env</code></td><td><code>docker rm -f</code> 后重新 <code>docker run</code></td></tr>
<tr><td>DashScope 视觉 API 400 错误</td><td>测试图片分辨率过小（<10×10）</td><td>使用真实尺寸图片测试</td></tr>
<tr><td>Python <code>-c</code> 在 ssh 里语法错误</td><td>多行脚本被 shell 截断</td><td>改为 VPS 驻留脚本 + stdin 传数据</td></tr>
<tr><td>Dockerfile 构建失败 <code>README.md missing</code></td><td>上游 bug</td><td><code>COPY pyproject.toml</code> → <code>COPY pyproject.toml README.md</code></td></tr>

<h3>9.2 功能相关</h3>

<tr><td>问题</td><td>原因</td><td>解决</td></tr>
<tr><td>---</td><td>---</td><td>---</td></tr>
<tr><td>微信插件入口找不到</td><td>在应用管理里找</td><td>正确路径：<strong>我的企业 → 微信插件</strong></td></tr>
<tr><td>识图返回"无法查看"</td><td>用了不支持 vision 的 API 端点</td><td>用 deepseek-vision 代理自动分流</td></tr>
<tr><td>task-status.json 被清空</td><td>Shell <code>echo '$var'</code> 遇单引号截断 JSON</td><td>改用 stdin 管道传数据</td></tr>
<tr><td>撤回消息无效</td><td>微信插件端不支持 API 撤回</td><td>企微客户端的消息可撤回，微信侧不行</td></tr>

<h3>9.3 设计决策</h3>

<li><strong>为什么用 deepseek-vision 代理而不直接用 Claude API？</strong> 代理兼容 Anthropic Messages 格式，同时提供视觉能力，一份代码两种 LLM 都可用</li>
<li><strong>为什么回调不直接放本地？</strong> 企微要求回调 URL 公网可达，VPS 是必要条件</li>
<li><strong>对话记忆存在哪？</strong> 内存（Map），服务重启会丢失。如需持久化可改为 Redis</li>

<hr>

<h2>十、恢复检查清单</h2>

<p>服务挂了按顺序排查：</p>

<pre><code># 1. VPS 回调服务
ssh root@&lt;你的VPS&gt; "pgrep -f 'node server.mjs'" || echo "需要重启"
# 重启：
ssh root@&lt;你的VPS&gt; "cd /opt/wecom-callback &amp;&amp; nohup node server.mjs &gt; /tmp/wecom.log 2&gt;&amp;1 &amp;"

# 2. deepseek-vision 代理
ssh root@&lt;你的VPS&gt; "docker ps | grep deepseek-vision" || echo "需要重启"

# 3. nginx
ssh root@&lt;你的VPS&gt; "systemctl status nginx"

# 4. 公网可达性
curl -s http://your.domain.com/ &amp;&amp; echo "OK" || echo "不可达"

# 5. 代理健康检查
ssh root@&lt;你的VPS&gt; "curl -s http://127.0.0.1:8000/health"</code></pre>

<hr>

<h2>附录 A：回调服务核心代码</h2>

<p>完整 <code>server.mjs</code> 约 300 行，关键逻辑：</p>

<pre><code>POST / （企微回调）
  → 解密 Encrypt → 解析 XML → 提取消息字段
  → 文本消息 → callAI(历史 + 新消息) → sendReply
  → 图片消息 → downloadImage → callAI(历史 + base64) → sendReply
  → 任务查询检测 → 注入 task-status.json → callAI

GET /inbox/unread → 返回未回复消息
POST /inbox/mark → 标记已回复
POST /reply → 手动回复
POST /chat/clear → 清除某用户对话历史</code></pre>

<p>服务绑定 <code>127.0.0.1:18909</code>，通过 nginx 反向代理暴露企微回调路径（<code>/</code>），其余 API 仅本地可访问。</p>

<hr>
]]></content:encoded>
</item>
</channel>
</rss>
