動かざることバグの如し

近づきたいよ 君の理想に

UbuntuでNFSマウントが繋がらなくなったときの対処法

環境

  • Ubuntu 24.04

状況

nfs mountできなくなった。

mount -t nfs server01:/path/to/mount /mnt/server01

してもずっと実行中のままでマウントできない。

--verbose つけてみると変なログがずっと出続けていた。なにかがおかしいっぽい。

mount --verbose -t nfs server01:/path/to/mount /mnt/server01
mount.nfs: timeout set for Wed Apr 1 09:52:23 2026
mount.nfs: trying text-based options 'vers=4.2,addr=192.168.16.100,clientaddr=192.168.16.2'
mount.nfs: mount(2): Connection refused
mount.nfs: trying text-based options 'addr=192.168.16.100'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: portmap query retrying: RPC: Program not registered
mount.nfs: prog 100003, trying vers=3, prot=17
mount.nfs: portmap query failed: RPC: Program not registered
mount.nfs: trying text-based options 'vers=4.2,addr=192.168.16.100,clientaddr=192.168.16.2'
mount.nfs: mount(2): Connection refused
mount.nfs: trying text-based options 'addr=192.168.16.100'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: portmap query retrying: RPC: Program not registered
mount.nfs: prog 100003, trying vers=3, prot=17
mount.nfs: portmap query failed: RPC: Program not registered
mount.nfs: trying text-based options 'vers=4.2,addr=192.168.16.100,clientaddr=192.168.16.2'
mount.nfs: mount(2): Connection refused
mount.nfs: trying text-based options 'addr=192.168.16.100'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: portmap query retrying: RPC: Program not registered
mount.nfs: prog 100003, trying vers=3, prot=17
mount.nfs: portmap query failed: RPC: Program not registered

解決策

エラーログを見ると、原因は大きく2点に絞られる。 NFSv4.2への接続で Connection refused、NFSv3へのフォールバックでは RPC: Program not registered が発生している。 つまり、サーバー側でNFSサービスが正常に動作していない、またはrpcbind/portmapが機能していない可能性が高い。

エラー 原因
Connection refused(NFSv4.2) nfs-serverが停止 or ポート2049がブロック
RPC: Program not registered(NFSv3) rpcbindが停止 or NFSがrpcbindに未登録
portmap query retrying rpcbindは応答しているがNFSサービス未登録

サーバー側の確認

まずサービスの状態を確認するのが先決だ。

# NFSサービスの状態確認
systemctl status nfs-server rpcbind

# RPCに登録されているサービス一覧
rpcinfo -p

rpcinfo -p の結果に nfs(prog 100003)や mountd(prog 100005)が表示されていなければ、サービスが止まっている。

今回の場合はこの確認をしたところ、nfs-serverサービスが停止していた。

サーバー側で/etc/exportsを設定していたが、そのディレクトリが削除されていてサービスが停止してしまっていた。修正してサービスを再起動したら無事にマウントできるようになった。

Claude Pro1年契約ユーザーのClaude Code設定

環境

  • Claude Code 2.1.92

設定

今までCodexを使っていたが、最近ではClaude Codeがメインになった。 定額プランなのでトークンを気にする必要がなく、年額プランを契約してしまったので当分はClaude Codeを使い続けることになる。 Claude Codeは雑な要求に対してもいい感じに実装してくれるので重宝している。

そんな俺が普段使ってるClaudeCodeの ~/.claude/settings.json の設定は以下。

{
  "permissions": {
    "defaultMode": "bypassPermissions"
  },
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.py"
  },
  "enabledPlugins": {
    "typescript-lsp@claude-plugins-official": true
  },
  "language": "日本語",
  "spinnerTipsEnabled": false,
  "autoMemoryEnabled": false,
  "skipDangerousModePermissionPrompt": true
}
  • permissions.defaultMode: bypassPermissions に設定することで毎回の許可確認を省略できる 個人開発でいちいち待ってられるか
  • statusLine: カスタムスクリプトを指定してステータスラインを表示
  • enabledPlugins: TypeScript LSPを有効化
  • language: インターフェース言語を日本語に設定
  • spinnerTipsEnabled: スピナーのヒント表示を無効化
  • autoMemoryEnabled: 自動メモリ機能を無効化 必要があればAGENTS.mdに書きたい
  • skipDangerousModePermissionPrompt: 危険なモードでの許可プロンプトをスキップ

~/.claude/statusline.pyの中身は以下 作成後に chmod +x ~/.claude/statusline.py 忘れずに。

#!/usr/bin/env python3
import json
import sys

data = json.load(sys.stdin)

R = '\033[0m'
DIM = '\033[2m'
BOLD = '\033[1m'

RINGS = ['○', '◔', '◑', '◕', '●']

def gradient(pct):
    if pct < 50:
        r = int(pct * 5.1)
        return f'\033[38;2;{r};200;80m'
    else:
        g = int(200 - (pct - 50) * 4)
        return f'\033[38;2;255;{max(g, 0)};60m'

def ring(pct):
    idx = min(int(pct / 25), 4)
    return RINGS[idx]

def fmt(label, pct):
    p = round(pct)
    return f'{DIM}{label}{R} {gradient(pct)}{ring(pct)} {p}%{R}'

model = data.get('model', {}).get('display_name', 'Claude')
parts = [f'{BOLD}{model}{R}']

ctx = data.get('context_window', {}).get('used_percentage')
if ctx is not None:
    parts.append(fmt('ctx', ctx))

five = data.get('rate_limits', {}).get('five_hour', {}).get('used_percentage')
if five is not None:
    parts.append(fmt('5h', five))

week = data.get('rate_limits', {}).get('seven_day', {}).get('used_percentage')
if week is not None:
    parts.append(fmt('7d', week))

print('  '.join(parts), end='')

以下の記事のスクリプトを拝借した。

nyosegawa.com

MacOS Tahoeの角丸ダサいUIをなんとか戻そうとした話

環境

  • MacOS Tahoe 26.4

やりたいこと

Macbook M5 airを購入した。今まで使っていたM1にスペック上の不満はなかったが、 AirでローカルLLM動かしたいという欲求1つで購入してしまった。

特に外観も変わってないし良くも悪くも不満はないのだが載ってるOSには不満がある。 MacOS TahoeになってLiquid Glassを採用して見づらいしデザインがカッコ悪い。 ちなみにTahoeはタホエではなくアホと読むらしい。

特に角丸がだせ〜〜〜〜〜〜〜

picture 0

終わってんだろMacOS

アップデートしたお前が悪いみたいなこと言われそうだけどM5は初期OSがTahoeなのでどうしようもない。

対策

調べてたらdefaultsで一応前のUIに戻せるらしい。

sudo mkdir -p /Library/Preferences/FeatureFlags/Domain
sudo defaults write /Library/Preferences/FeatureFlags/Domain/SwiftUI.plist Solarium -dict Enabled -bool false
defaults write -g NSAlertGlassSolariumEnabled -bool false

実行後は再起動する。

角丸のウィンドウが消えた!!!やったー!

picture 1

元に戻す場合は以下を実行する。

sudo defaults delete /Library/Preferences/FeatureFlags/Domain/SwiftUI.plist
defaults delete -g NSAlertGlassSolariumEnabled

とはいえdefaults write com.apple.mail com.apple.SwiftUI.DisableSolariumが26.1で無効化された経緯から察するにこの設定もいつまで使えるのかは未知数

参考リンク

AIエージェント向けのGrok APIコマンド

環境

  • Python 3.13

コード

# 天気・ニュース・トレンド等はsearch.pyを使う
# uv run python search.py --question '今日の東京の天気は?'

import os
import argparse
from datetime import datetime
from openai import OpenAI

# コマンドライン引数のパース
parser = argparse.ArgumentParser(description="ウェブ検索を実行する")
parser.add_argument("--question", type=str, help="検索する質問")
args = parser.parse_args()


client = OpenAI(
    api_key=os.getenv("XAI_API_KEY"),
    base_url="https://api.x.ai/v1",
)

now = datetime.now().strftime("%Y年%m月%d日 %H時%M分")

response = client.responses.create(
    model="grok-4-1-fast-non-reasoning",
    input=[
        {"role": "user", "content": f"現在の日時:{now} 出力は簡潔に。" + args.question},
    ],
    tools=[
        {"type": "web_search"},
        {"type": "x_search"},
    ],
    stream=False,
)
print(response.output_text)

いいたいこと

世間で溢れているSkillsはGrokで回収できる。やりたいことってこれなんじゃないの

Qwen3.5-27BでローカルLLM x picoclawを試す

環境

  • Ubuntu 24.04

概要

せっかくRTX4090を持っているなら、ローカルLLMでAIエージェントを運用したくなる。picoclawを実際に試してみたメモだ。

今回はllama.cppでQwen3.5-27B-GGUFを動かしている。ここでは詳しい起動方法の説明はせず、すでに起動しているものとする。

huggingface.co

AIエージェントに手元のPC環境を壊されるのは避けたかったので、NUCにインストールしたのだが、openclawは重すぎて起動に1分以上かかってゴミだった。そこでpicoclawを試してみたところ、Go言語で書かれていて高速かつ軽量だった。

インストール

今回は自分でビルドしたが、バイナリファイルの公式配布もあったのでこっちからダウンロードするほうが早いかもしれない。

git clone https://github.com/sipeed/picoclaw.git

cd picoclaw
make deps

# Build core binary
make build

# Build Web UI Launcher (required for WebUI mode)
make build-launcher

# Build for multiple platforms
make build-all

# Build for Raspberry Pi Zero 2 W (32-bit: make build-linux-arm; 64-bit: make build-linux-arm64)
make build-pi-zero

# Build and install
make install

初期設定

エージェントと対話するコマンド

picoclaw onboard

ゲートウェイを起動 Telegram/Discord等のチャンネル連携する場合はこのコマンドを起動し続けておく必要がある

picoclaw gateway

モデルの設定

model_listの配列に以下を追記する。裏にはllama.cppが起動している。

{
  "model_name": "deep01-local",
  "model": "openai/local-model",
  "api_base": "http://192.168.xx.xx:8000/v1",
  "api_key": "dummy"
},

そしてagents.defaultsの設定を以下にする。

{
  "session": {
    "dm_scope": "per-channel-peer"
  },
  "version": 2,
  "agents": {
    "defaults": {
      "provider": "openai",
      "model_name": "deep01-local",
      (略)

会話のターン数について

picoclawでは、会話が長くなると全ての履歴をLLMに送るわけではない。コンテキスト予算に応じて動的に調整される仕様になっている。

基本の流れは以下の通りだ。

  • セッション(全履歴をJSONL保存)
  • contextManager.Assemble() でトークン予算チェック
  • 予算超過なら圧縮してLLMへ送信

LLMに送られる内容は以下の3つだ。

  1. システムプロンプト(静的情報 + 動的コンテキスト + 要約)
  2. 会話履歴(圧縮済みの過去メッセージ、古いものは削除または要約に置き換え)
  3. 現在のメッセージ(今回のユーザー入力)

3層の圧縮戦略が存在する。

フェーズ タイミング 内容
予防的圧縮 LLM呼び出し前 予算超過を検知したら実行
強制圧縮 予算大幅超過時 古い約50%のターンを削除してサマリーに追記
非同期サマリー化 ターン完了後(バックグラウンド) 20メッセージ超またはトークン75%超でLLMが要約を生成

閾値は以下の通りだ。

  • SummarizeMessageThreshold: 20メッセージを超えるとサマリー化
  • SummarizeTokenPercent: コンテキストウィンドウの75%超えでサマリー化
  • 強制圧縮: 古い50%のターンを削除し、整合性のためツール呼び出しシーケンスは分割しない

要するに、短い会話なら全部送られるが、会話が長くなると古いメッセージはLLMが生成した要約に置き換えられ、コンテキスト上限に収まるよう自動調整される仕組みだ。

結局以下の設定にした。ローカルLLMはどれだけトークン使っても無料なので思わずロングコンテキストに設定したくなるが、 コンテキスト量が増えるとAPIと違って生成がどんどん遅くなってしまう。

"agents": {
  "defaults": {
    "max_tokens": 32768,
    "context_window": 40000,
    "summarize_message_threshold": 20,
    "summarize_token_percent": 50,
  }
},

明示的に会話履歴をクリアしたい場合は「/clear」と送信する。(ターミナル、Discordともに有効)

wikipedia MCPを使う

Wikipedia MCPを使うことで、エージェントがWikipediaの情報を検索・参照できるようになる。これにより、最新の知識や詳細な事実確認が必要な質問に対して、信頼性の高い情報源に基づいた回答が可能となる。

特に、最新のニュースや専門的な知識について聞かれた際に、LLMの学習データに含まれていない情報を補完できるのがメリットだ。

github.com

設定は以下のように行う。

     "mcp": {
-      "enabled": false,
+      "enabled": true,
       "discovery": {
         "enabled": false,
         "ttl": 5,
@@ -477,7 +485,14 @@
         "use_bm25": true,
         "use_regex": false
       },
-      "max_inline_text_chars": 16384
+      "max_inline_text_chars": 16384,
+      "servers": {
+        "wikipedia": {
+          "enabled": true,
+          "command": "uvx",
+          "args": ["wikipedia-mcp", "--language", "ja"]
+        }
+      }