gangvy 96775af9b0 feat(fmode): add fmode-vision/ffmpeg/listen standalone skill packages vor 3 Monaten
..
scripts 96775af9b0 feat(fmode): add fmode-vision/ffmpeg/listen standalone skill packages vor 3 Monaten
README.md 96775af9b0 feat(fmode): add fmode-vision/ffmpeg/listen standalone skill packages vor 3 Monaten
SKILL.md 96775af9b0 feat(fmode): add fmode-vision/ffmpeg/listen standalone skill packages vor 3 Monaten

README.md

Fmode Vision Skill — 维护文档

项目结构

.claude/skills/fmode-vision/
├── SKILL.md                       # 技能入口,Claude 读取后知道何时及如何使用本技能
├── README.md                      # 本文件:开发者维护文档
├── .skillfish.json                # 技能元信息(版本、来源仓库)
└── scripts/
    ├── vision-client.mjs           # 核心:通用视觉 API 客户端
    └── prompts/
        └── room-measurement.mjs    # 领域模块:毛坯房量尺 5-pass 提示词

核心逻辑

1. Token 解析链 (resolveApiToken)

三级优先级,短路返回:

FMODE_API_TOKEN 环境变量
  → ~/.fmode/config.json 的 fmodeApiToken / newapiToken 字段
    → <cwd>/.fmode/config.json 的 fmodeApiToken / newapiToken 字段
      → 抛出异常(提示用户配置)

设计原因:环境变量适合 CI/CD;用户级配置适合个人开发机;项目级配置适合团队共享(加入 .gitignore)。

2. API 调用流程 (callVisionAPI)

输入: imagePath | imageBase64 | imageUrl | videoUrl
  |
  ├─ 解析 token
  ├─ 构造 messages 数组
  │   ├─ system prompt
  │   └─ user content:
  │       ├─ text part(用户提示词)
  │       └─ image_url / video_url part(视觉内容)
  ├─ POST https://api.fmode.cn/v1/chat/completions
  │   body: { model, messages, temperature, max_tokens }
  ├─ 响应的 content 字符串 → extractJSON()
  └─ 返回 { raw, parsed, error, usage }

3. 多轮分析模式 (callMultiPass)

核心理念:每轮独立调用 API,各自聚焦一个分析维度,最后一轮合并。这比单轮全量分析精度更高。

输入: imagePath + passes[{name, systemPrompt, userPrompt, maxTokens}]
  |
  for each pass:
  ├─ 检查 cacheDir/pass<N>.json 是否存在
  │   ├─ 存在 → 跳过,读取缓存
  │   └─ 不存在 → callVisionAPI() → 写入缓存
  ├─ sleep(delayMs) 避免限流
  |
  └─ 返回 results[]

缓存设计:

  • 每轮结果独立缓存,支持断点续跑
  • 缓存 key = pass 序号,与提示词内容无关
  • 如需强制重新分析,删除对应缓存文件即可
  • 提示词迭代时,建议手动清理缓存

4. JSON 提取 (extractJSON)

LLM 响应可能被 markdown 代码块包裹(json ...),也可能前后有解释文字。用正则 /\{[\s\S]*\}/ 提取第一个 JSON 对象。

5. 毛坯房 5-pass 专用流程 (room-measurement.mjs)

继承自 analyze-photos-v4.mjs,5 轮各有独立职责:

Pass 名称 分析焦点 tokens
1 spatial 空间结构:透视类型、墙面多边形、阴阳角、天地面 2000
2 ceiling 吊顶特征:cornice/trayStep/beam/bulkhead 1000
3 openings 门窗洞口:双层框架(outer+inner polygon) 2500
4 obstacles 障碍物:插座/开关/电箱/踢脚线/风口等 1500
5 merge 文本合并:场景描述、房间类型、测量计划、质量评估 2000

质量验证:

  • 踢脚线 height > 10% → 警告(应为 2-5%)
  • 吊顶特征 polygon 顶点 > 4 → 警告

配置说明

API Token

方式一:环境变量

export FMODE_API_TOKEN="sk-xxxxxxxx"

方式二:用户级配置 ~/.fmode/config.json

{
  "fmodeApiToken": "sk-xxxxxxxx"
}

方式三:项目级配置 <project>/.fmode/config.json(需加入 .gitignore)

{
  "fmodeApiToken": "sk-xxxxxxxx"
}

可用模型

模型 ID 用途 备注
doubao-seed-2-0-pro-260215 视觉理解(默认) 豆包视觉模型,性价比高
gpt-4o 视觉理解 如账号有权限

模型列表可能更新,以 Fmode API 返回为准。

扩展指南

添加新的提示词模板

在 scripts/prompts/ 下新建 .mjs 文件:

import { callVisionAPI, callMultiPass } from '../vision-client.mjs';

export const MY_SYSTEM_PROMPT = `...`;
export const MY_USER_PROMPT = `...`;

export async function analyzeSomething(imagePath) {
  const result = await callVisionAPI({
    imagePath,
    systemPrompt: MY_SYSTEM_PROMPT,
    userPrompt: MY_USER_PROMPT,
    maxTokens: 1000,
  });
  return result.parsed;
}

添加新模型

在 vision-client.mjs 的 DEFAULT_CONFIG 中调整默认模型,或调用时传入 model 参数:

const result = await callVisionAPI({
  imagePath: '/path/to/img.jpg',
  systemPrompt: '...',
  userPrompt: '...',
  model: 'gpt-4o',  // 覆盖默认模型
});

多轮分析自定义

import { callMultiPass } from './vision-client.mjs';

const results = await callMultiPass({
  imagePath: '/path/to/img.jpg',
  cacheDir: '/tmp/my-analysis/img-001/',
  passes: [
    { name: 'overview', systemPrompt: '...', userPrompt: '描述整体场景', maxTokens: 500 },
    { name: 'details', systemPrompt: '...', userPrompt: '标注细节元素', maxTokens: 1500 },
    { name: 'verify',  systemPrompt: '...', userPrompt: '验证前两轮一致性', maxTokens: 1000 },
  ],
});

依赖

仅使用 Node.js 内置模块:fs, path, os。无需 npm install。

全局 fetch 需要 Node.js 18+(已内置)。

源文件参考

本技能从以下文件提取和通用化:

  • d:\workspace\hundun\lami-scale-canvas\scripts\analyze-photos-v4.mjs — 原始 5-pass 量尺分析实现

版本追踪:lami-scale-canvas 仓库 analyze-photos-v4.mjs 如有更新,需同步检查本技能是否需要升级。