ウィークリーレポ:2025/10/20

先週は生成AIの解析ができるか全力でClaude Codeを廻していたのでこれと言ってレポートできる内容が少ない

CD8180

CIXのCD8180が実装された基板が出始めた。

このデバイスは30TOPSのNPUを積んでいて、CPU+GPU+NPUで45TOPSの性能があるらしい。

メモリも32GBで小さなLLMサーバとして利用できるのではないかと模索している。

Orionは約30,000円、Orange Piが約39,000円ぐらいの価格帯だ。

性能は30TOPSなのでHAILOと同じぐらいだと思えばいいんだけど、コンパクトに収まっているからいいなぁという感じ。

ハード面では性能があると言っても問題はNPUのSDKが整っているかというところだ。

NeuralOne AI SDKというSDKが用意されているようだが、扱いはEarly Accessのようでまだまだというところなのだろうか?

npm環境

新規環境だとついつい、npm環境をroot環境に入れてしまうのでユーザー環境へ移行する。

nvmのインストール

https://github.com/nvm-sh/nvm

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash

バージョン確認

nvm -v
0.40.3

nodeのインストール

nvm install 24
Downloading and installing node v24.10.0...
Downloading https://nodejs.org/dist/v24.10.0/node-v24.10.0-linux-x64.tar.xz...
################################################################################################################# 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v24.10.0 (npm v11.6.1)

nodeのバージョン確認

node -v
v24.10.0

npmのバージョン確認

npm -v
11.6.1

npmのパッケージインストール

npm install -g @nanocollective/nanocoder
npm install -g @anthropic-ai/claude-code
npm install -g @google/gemini-cli
npm install -g @openai/codex
npm install -g @forge/cli
npm install -g @github/copilot
npm install -g opencode-ai

nanocoder

ぼちぼちとnanocoderでAIエージェント環境を整えようとしている。

https://github.com/Nano-Collective/nanocoder

つぎのMCP Serverサンプルに続く。

MCP Serverサンプル

nanocoderで動作するMCPサーバーを作成する。

今回はサンプルを作成する程度。

npmのセットアップ

npm install
npm list @modelcontextprotocol/sdk

mcp-server-minimal.js

#!/usr/bin/env node

/**
 * 最小限のMCPサーバー - デバッグ用
 * 必要最低限の機能のみを実装
 */

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

// ログ関数(必ずstderrに出力)
function log(message) {
  process.stderr.write(`[${new Date().toISOString()}] ${message}\n`);
}

// サーバーインスタンスを作成
const server = new Server(
  {
    name: "minimal-qa-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// ツール一覧を返す
server.setRequestHandler(ListToolsRequestSchema, async () => {
  log("tools/list called");
  return {
    tools: [
      {
        name: "greet",
        description: "シンプルな挨拶ツール",
        inputSchema: {
          type: "object",
          properties: {
            name: {
              type: "string",
              description: "名前",
            },
          },
          required: ["name"],
        },
      },
    ],
  };
});

// ツール実行
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  log(`tools/call called: ${name}`);

  if (name === "greet") {
    return {
      content: [
        {
          type: "text",
          text: `こんにちは、${args.name}さん!`,
        },
      ],
    };
  }

  throw new Error(`Unknown tool: ${name}`);
});

// エラーハンドリング
process.on('uncaughtException', (error) => {
  log(`Uncaught exception: ${error.message}`);
  log(error.stack || '');
});

process.on('unhandledRejection', (reason) => {
  log(`Unhandled rejection: ${reason}`);
});

// シャットダウン処理
let isShuttingDown = false;

async function shutdown() {
  if (isShuttingDown) return;
  isShuttingDown = true;

  log('Shutting down...');
  try {
    await server.close();
    log('Server closed successfully');
  } catch (error) {
    log(`Error during shutdown: ${error.message}`);
  }
  process.exit(0);
}

process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);

// メイン処理
async function main() {
  try {
    log('=== Starting Minimal MCP Server ===');
    log(`Node version: ${process.version}`);
    log(`Platform: ${process.platform}`);

    // トランスポートを作成
    const transport = new StdioServerTransport();
    log('Transport created');

    // サーバーに接続
    await server.connect(transport);
    log('Server connected successfully');

    // 重要: プロセスを維持
    process.stdin.resume();
    log('Server is ready and listening...');

  } catch (error) {
    log(`Fatal error: ${error.message}`);
    log(error.stack || '');
    process.exit(1);
  }
}

// 起動
main();

agent.config.json

{
  "nanocoder": {
    "mcpServers": [
      {
        "name": "qa-knowledge",
        "command": "node",
        "args": [
          "/home/hidemi/nanocoder_sample/mcp-server-minimal.js"
        ],
        "env": {
          "NODE_ENV": "production"
        }
      }
    ]
  }
}
2025/10/20 10:00:00(Permanent Link)

 


ウィークリーレポ:2025/10/13

今週はエージェントCLIを調査する一週間だった。

エージェントCLIは自分に合うものを選べばいいと思う。

たくさんあるので好き嫌いで構わないと思う。

エージェントCLI

Claude CodeやGemini CLI、Codexなど、たくさんのエージェントCLIがある。

今週はガンガン使っていたので1週間の制限にかかってしまい、3日ほど使用できなくなった。

Gemini CLIも制限にかかってしまったようだし、こちらは早めに制限が解除された。

前々からローカルでLLMサーバーを起動して、エージェントCLIを使えないかと調査してたんだけど、しっくり来るものがなくて…

MCP対応で探しているんだけど…

OpenHands

良さげなんだけど、なんか名前がね…

OpenCode

OpenCodeもなんとなく良さげなんだけど、MCPからの応答でファイルが操作できなかったり…

Aider

使い勝手はいいんだけど、Pythonベースというのが気に入らない。

ここは単純に好き嫌いなだけだけど…

TypeScriptがいいんだよね。

Mastra

なんかしっくりこなかった。

ForgeCode

これもしっくりこなかった。

nanocoder

あ、これがいいのかも、TypeScriptだし。

ただ、文字を入力するごとにキャラクターバッファーの先頭に戻るというのだけ、治ってくれれば…

nanocoderベースにMCP環境を整えていくかな…

2025/10/13 10:00:00(Permanent Link)

 


ウィークリーレポ:2025/10/06

今年も10月になり、残り2ヶ月になりました。

先週はAIエージェントでソフトウェアを解析していました。

reTerminal E1002向けアプリ

reTerminal向けアプリをアップデートした。

https://github.com/aquaxis/reTerminal

追加機能

  • ボタンをクリックするとWiFiの再接続を行う
  • 固定IPの設定追加

WiFi接続をしてから、時間が経つと接続をOffになるのでボタンをクリックするとWiFiのIPアドレスを再取得するようにした。

つぎに追加したい機能

  • 省電力モード
  • 省電力モードからタイマーでの再起動
  • SDカードのBitmapを再起動ごとに変更してe-Paperに表示

Claude Sonet 4.5

Claude Sonet 4.5がリリースされた。

それに伴って、Claude CodeもClaude Sonet 4.5になったけど、ずいぶんと怠けるようになった。

精度は上がっているように見えるけど、結構な頻度でインターバルを挟むようになった。

依然として変わらないのが一度、間違った方向に走り始めると明後日の方向に行ってしまい収集がつかなくなることかな。

これは他のAIエージェントでも変わらないか…

ひさびさにLinux Driverの作成

ひさびさにLinux Driverの作成をした。

FPGAに繋げる低レイヤーなDriverが欲しかったからねぇ。

Kernel Versionが3.xの頃はよく書いていたんだけど、今は6.xでお作法が変わってるかなとか思いつつ、AIエージェントで作らせてみた。

そしたら、細かいところのお作法が変わってるということだった。

AIエージェントが作成したDriverを確認したけど、自分が作るのと同じ答えなのでホント、コードを書くのをらくできるようになったなぁと思うよ。

2025/10/06 10:00:00(Permanent Link)

 


ウィークリーレポ:2025/09/29

まだ、真夏日があるけど、風が涼しくなってきたのでずいぶん涼しく感じるようになってきた。

Rokusai(六彩)

JPEGとPNGからe-Paper(Spectra6)で表示する6色(黒、白、黄、赤、緑、青)へディザリングするプログラムを作成した。

https://github.com/aquaxis/rokusai

出力はBitmapとPNGでBitmapであれば画像データそのものをe-Paperに転送するとそのまま表示できるデータ形式である。

主な機能

  • 複数画像形式対応: JPEG/PNGの入力、BMP/PNGの出力
  • ホワイトバランス調整: グレーワールド法による自動・手動調整
  • 色強調処理: 彩度・コントラスト・明度・ガンマ・色相の調整
  • Floyd-Steinbergディザリング: 7色パレットへの高品質変換
  • アスペクト比保持リサイズ: 白背景での中央配置

機能

ホワイトバランス

  • 自動ホワイトバランス: グレーワールド法による色温度補正
  • 手動調整: RGB各チャンネルのゲイン個別設定
  • ゲインクリッピング: 0.5-2.5の範囲で安全な補正

色強調

  • 彩度調整: 色の鮮やかさの制御
  • コントラスト調整: 明暗差の強調・緩和
  • 明度調整: 全体の明るさ補正
  • ガンマ補正: 階調特性の調整(ルックアップテーブル最適化)
  • 色相シフト: 色味の回転調整

リサイズ機能

  • アスペクト比保持: 元画像の縦横比を維持
  • 中央配置: リサイズした画像を出力キャンバスの中央に配置
  • 白余白埋め: 余った領域を白色で埋める
  • バイリニア補間: 高品質なリサイズアルゴリズム

画像処理

  • 高精度処理: 浮動小数点演算による精度保持
  • メモリ効率: 最適化されたメモリ管理
  • エラーハンドリング: 堅牢なメモリ管理

README.mdのなかでは7色パレットを記載しているが、パレットのインデックス番号を0~6まで使用しており、白を2個使っているためである。

写真をそのままディザリングすると画像が結構荒くなるのでいったん、ポスタリゼーションを挟もうかと思っている。

e-Paper 13.3inch ラズパイ用アプリ

e-Paper 13.3(Spectra6)に表示するRaspberry Pi用アプリをアップデートした。

https://github.com/aquaxis/e-Paper13.3

インデックスカラーのPNG対応だったがインデックスカラーのBitmapに変更した。

reTerminal E1002向けアプリ

reTerminal E1002向けアプリもアップデートした。

https://github.com/aquaxis/reTerminal

SDカードに4bitインデックスカラーのtest.bmpを入れておくと電源Onでe-Paperに表示する。

それとWiFi接続を追加した。

HTTPでファイルの送信とe-Paperの更新に対応させた。

ステルスSSIDにも対応させた。

これが欲しかったんだよね。

今後は省電力モードとタイマー書き換えを追加していく予定だ。

e-Paper E1002(2台目)

Seeed Studioから1台目のE-Paperは1st Lotで輝度を改善したものが出来上がったから無償送付するということで2代目がやってきた。

特に見た目は変わらず、繋げてからアプリを書きこんだけどアプリ的には変わらずだった。

e-Paper自体は1代目より黄みがかっているかなって感じでこれはe-Paperの個体差だろう。

なので、何が変わったかあまりわからなかった。

2025/09/29 10:00:00(Permanent Link)

 


ウィークリーレポ:2025/09/22

先週はESP32をいぢっていた。

13.3inchのe-PaperとreTerminalのアプリを作成していた。

成果物はGithubで公開中で、初版レベルなので継続的メンテをして機能をアップデートしていく。

13.3inch e-Paper向けアプリ

GithubにWaveShare 13.3inch E Ink Spectra 6 (E6) Full color E-Paper Displayのアプリケーションを追加した。

https://github.com/aquaxis/e-Paper13.3

つぎの仕様の画像ファイルを入力するとe-Paperに画像を転送する。

  • ラズパイ向け
  • 入力はBitmap
  • 6色のインデックスカラーのみ
  • サイズは1200 x 1600固定

E InkのSpectra6シリーズの画像転送アプリの参考になるだろう。

reTerminal向けアプリ

こちらもGithubにreTerminal E1002のアプリを追加した。

つぎの仕様の画像ファイルをreTerminalに画像を表示する。

  • ESP32-S3
  • 入力はBitmap
  • 6色のインデックスカラーのみ
  • サイズは800 x 480固定

https://github.com/aquaxis/reTerminal

開発環境はESP-IDF環境である。

現状はSDカードに入っているtest.bmpのみ読み込むようになっている。

今週のAI

最近はAIエージェントを使うことが普通のことになってきている。

PerprexityやCopilot、Geminiなどがあるけど、問いかけるときはほぼつぎのように入力することがテンプレ化している。

「xxを調査し詳細に解説してください。」

「xxを調査し詳細な一覧表にまとめてください。」

どのように回答してほしいかで使い分けるけど、ほぼこの二択である。

つぎのような問いかけではAIエージェントの検索範囲が狭まるようだ。

「xxを教えて下さい。」

今週の気になりガジェット:小さなKVM

WaveShareから新しいKVMがリリースされた。

Luckfox PicoKVM Lightweight IP KVM Remote Management Tool

Luckfox PicoKVM

価格は$55.99(執筆時で約8,200円)でスペックはつぎのとおりだ。

  • HDMI(1920x1080@60fps)
  • HID(USB-C)
  • Ethernet(100Mbps)
  • SD Card
  • GPIO
  • Size: 48.5mm x 48.5mm x 29.0mm

CPUはRockChipのRV1106G3でCortex-A7@1.2GHzで動作する。

ケースなしだとつぎのようになる。

Sipeed NanoKVM PiKVM

Sipeedもすでに小さなKVMをリリースしていて、これは使用している。

Sipeed NanoKVM PiKVM

Githubでソースコードも公開されている。

https://github.com/sipeed/NanoKVM

価格は3,732円(執筆時)、ただ、他の販売店を見ると3,000円以下で購入できる場合がある。

スペックはつぎのとおりである。

  • HDMI(1920x1080@60fps)
  • HID(USB-C)
  • Ethernet(100MHz)
  • GPIO
  • Power USB-C
  • Size: 40.0mm x 36.0mm x 36.0mm

CPUはSOPHGOのSG2002で1GHzのRISC-V C906コアが動作しているようだ。

Luckfox PicoKVMの方は電源をホストから供給されなければいけないので、ホストのUSB電源供給は必須機能になるうえに、ホストの電源が致命的に落ちた場合、KVMにアクセスできなくなる。

どちらが良いかというと、価格的にも半値というところはあるが、仕様的に別の外部電源を取れるSipeedのNanoKVMのほうが良い。

2025/09/22 10:00:00(Permanent Link)