先週はnanocoderの環境構築の最中だったので情報が少ない。
次のようにHugging Faceからダウンロードして、llama.cppのconvert_hf_to_gguf.pyでGGUFに変換する。
cd models
git clone https://huggingface.co/XXXXXX/REPONAME
python convert_hf_to_gguf.py models/REPONAME --outtype f16
models/REPONAME/hogehoge.gguf GGUFファイルができるのでコピーする。
cp models/REPONAME/hogehoge.gguf ~/.ollama/models/
Modelfile_hogehoge.txt を作成する。
from /home/hidemi/.ollama/models/hogehoge.gguf
ollamaに登録する。
ollama create hogehoge -f /home/hidemi/.ollama/models/Modelfile_hogehoge.txt
先週は生成AIの解析ができるか全力でClaude Codeを廻していたのでこれと言ってレポートできる内容が少ない
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環境をroot環境に入れてしまうのでユーザー環境へ移行する。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
nvm -v
0.40.3
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 -v
v24.10.0
npm -v
11.6.1
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でAIエージェント環境を整えようとしている。
https://github.com/Nano-Collective/nanocoder
つぎのMCP Serverサンプルに続く。
nanocoderで動作するMCPサーバーを作成する。
今回はサンプルを作成する程度。
npm install
npm list @modelcontextprotocol/sdk
#!/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();
{
"nanocoder": {
"mcpServers": [
{
"name": "qa-knowledge",
"command": "node",
"args": [
"/home/hidemi/nanocoder_sample/mcp-server-minimal.js"
],
"env": {
"NODE_ENV": "production"
}
}
]
}
}
今週はエージェントCLIを調査する一週間だった。
エージェントCLIは自分に合うものを選べばいいと思う。
たくさんあるので好き嫌いで構わないと思う。
Claude CodeやGemini CLI、Codexなど、たくさんのエージェントCLIがある。
今週はガンガン使っていたので1週間の制限にかかってしまい、3日ほど使用できなくなった。
Gemini CLIも制限にかかってしまったようだし、こちらは早めに制限が解除された。
前々からローカルでLLMサーバーを起動して、エージェントCLIを使えないかと調査してたんだけど、しっくり来るものがなくて…
MCP対応で探しているんだけど…
良さげなんだけど、なんか名前がね…
OpenCodeもなんとなく良さげなんだけど、MCPからの応答でファイルが操作できなかったり…
使い勝手はいいんだけど、Pythonベースというのが気に入らない。
ここは単純に好き嫌いなだけだけど…
TypeScriptがいいんだよね。
なんかしっくりこなかった。
これもしっくりこなかった。
あ、これがいいのかも、TypeScriptだし。
ただ、文字を入力するごとにキャラクターバッファーの先頭に戻るというのだけ、治ってくれれば…
nanocoderベースにMCP環境を整えていくかな…
今年も10月になり、残り2ヶ月になりました。
先週はAIエージェントでソフトウェアを解析していました。
reTerminal向けアプリをアップデートした。
https://github.com/aquaxis/reTerminal
追加機能
WiFi接続をしてから、時間が経つと接続をOffになるのでボタンをクリックするとWiFiのIPアドレスを再取得するようにした。
つぎに追加したい機能
Claude Sonet 4.5がリリースされた。
それに伴って、Claude CodeもClaude Sonet 4.5になったけど、ずいぶんと怠けるようになった。
精度は上がっているように見えるけど、結構な頻度でインターバルを挟むようになった。
依然として変わらないのが一度、間違った方向に走り始めると明後日の方向に行ってしまい収集がつかなくなることかな。
これは他のAIエージェントでも変わらないか…
ひさびさにLinux Driverの作成をした。
FPGAに繋げる低レイヤーなDriverが欲しかったからねぇ。
Kernel Versionが3.xの頃はよく書いていたんだけど、今は6.xでお作法が変わってるかなとか思いつつ、AIエージェントで作らせてみた。
そしたら、細かいところのお作法が変わってるということだった。
AIエージェントが作成したDriverを確認したけど、自分が作るのと同じ答えなのでホント、コードを書くのをらくできるようになったなぁと思うよ。

まだ、真夏日があるけど、風が涼しくなってきたのでずいぶん涼しく感じるようになってきた。
JPEGとPNGからe-Paper(Spectra6)で表示する6色(黒、白、黄、赤、緑、青)へディザリングするプログラムを作成した。
https://github.com/aquaxis/rokusai
出力はBitmapとPNGでBitmapであれば画像データそのものをe-Paperに転送するとそのまま表示できるデータ形式である。
README.mdのなかでは7色パレットを記載しているが、パレットのインデックス番号を0~6まで使用しており、白を2個使っているためである。
写真をそのままディザリングすると画像が結構荒くなるのでいったん、ポスタリゼーションを挟もうかと思っている。
e-Paper 13.3(Spectra6)に表示するRaspberry Pi用アプリをアップデートした。
https://github.com/aquaxis/e-Paper13.3
インデックスカラーのPNG対応だったがインデックスカラーのBitmapに変更した。
reTerminal E1002向けアプリもアップデートした。
https://github.com/aquaxis/reTerminal
SDカードに4bitインデックスカラーのtest.bmpを入れておくと電源Onでe-Paperに表示する。
それとWiFi接続を追加した。
HTTPでファイルの送信とe-Paperの更新に対応させた。
ステルスSSIDにも対応させた。
これが欲しかったんだよね。
今後は省電力モードとタイマー書き換えを追加していく予定だ。
Seeed Studioから1台目のE-Paperは1st Lotで輝度を改善したものが出来上がったから無償送付するということで2代目がやってきた。

特に見た目は変わらず、繋げてからアプリを書きこんだけどアプリ的には変わらずだった。
e-Paper自体は1代目より黄みがかっているかなって感じでこれはe-Paperの個体差だろう。
なので、何が変わったかあまりわからなかった。