
はじめに
LabVIEW 2026 Q3のアップデートによりNigel AIによるコード生成ができるようになりました。早速使ってみましょう。
…と思いましたが、LabVIEW Communityでは使えないことが分かっているので、インストール項目から外しました。ちなみに、インストールして使おうとするとこうなります。

…ログインできません。なので、会話もできません。記事作成時点ではProfessional Development SystemやLabVIEW+でないと使えないのですが、年5万円とかの課金で使えるようにならないかな?と思っています。NigelはAzure OpenAIを利用しているので、NI側としてもタダで使わせるとMicrosoftに使った分だけ支払いが発生しますからね。
とはいっても、生成AIは今のトレンドなので使いたいじゃないですか。コード生成もしたいです。LabVIEWのコードは自分で作るので、テキスト言語のソースコードを生成AIさんに任せたいと思っています。
コードを作る生成AI
LabVIEWでコードを作れるか?
→できません。…そのうちYesになるのかな?
ですが、コードを生成するAIさんはいろいろあります。Nigel AIもベースはAzure OpenAIなので、機嫌がよければLabVIEW以外のコードも作ってくれます。汎用の生成AIのSaaSでも作ってくれますが、コード生成に特化しているのは Github Copilot ですね。Visual Studio Codeなどでもインストールできるので、利用している人も多いと思います。…所属組織のセキュリティや情報漏えい対策次第ですが。このGithub Copilotにはアプリケーションに組み込むための部品(SDK)があるので、それを通して自作アプリにコードを作成させることができます。Copilot SDKやその前提となるCopilot CLI(コマンドラインでGithub Copilotを使う)のインストール方法などについてはGithubを参照してください。
github/copilot-sdk: Multi-platform SDK for integrating GitHub Copilot Agent into apps and services

これはターミナルからGithub Copilot CLIを起動したものです。簡単なコードを作ってもらっています。左上のキャラクターがかわいいですね。
Github Copilot SDKにはNode.js、Python、Go、Rustなどの定番な開発環境がありますが、LabVIEWは当然のごとくありません。なので、LabVIEWで利用するなら
- Webアプリを作ってJavaScriptでアクセスする
- .NETで作って、Constructir Nodeで.NETを呼び出す
- Pythonで作ってPythonノードで呼び出す
- 何でもいいので実行形式にしてSystem Exec.viのビルトインのサブVIで呼び出す
ぐらいしかないと思います。LabVIEWアプリにはHTTPクライアントとして動かすための関数がありますが、Github CopilotはHTTP用のインターフェースは公開されていないんですよね。LabVIEWでやる必要性は置いといて、LabVIEWにGithub Copilotを組み込むなら、楽なのは次の順番になるかな?
Python > Node.js > .NET
GoやRustをLabVIEWに組み込めるかは私は分かりません。Node.jsもWebアプリを作って、JavaScriptを召喚したり、Callbackを検出する形になるので、WebView2のツールキットをVIパッケージマネージャーから入れるとすごく難しいわけではないですが、自分でWebView2と格闘するとなると難易度は激増します。.NETは何かうまくいかなかった記憶があります。いずれにしても、Pythonが一番楽です。Pythonはインタープリターなので動作確認のためにいちいちコンパイルしなくてもいいし。
しかし、私はPythonのコードを無から生成できるほどくわしくはありません。なので、コード生成は生成AIさん(Claudeさん)にお任せしました。指示内容はこんな感じです。
LabVIEWからGithub Copilotを呼び出してコード生成してみたいです。
前提条件
・Github Copilot SDKはPythonのものをインストール済み。Copilot v1.0.79-9 uses AI.
・Pythonはさっき3.14.7を入れました。
・LabVIEWは2026 Q3 64bit
Python関数
・Github Copilotのセッションをオープンする。
・チャットする
・セッションを終了する。
制約
・LabVIEWではasync defだったかの関数は呼べない。defのみ
実は、LabVIEWのPythonノードではasync def(非同期関数)を直接呼び出すことはできません。なので、LabVIEWからは通常のdefを呼び出す形にして、Python内部でセッションを保持しながらdef関数内でasync defを扱う形になります。この指示でClaudeさんに作ってもらった関数はこんな感じです。
Claudeさんに作ってもらったGithub Copilotを呼び出すPythonコードを開く
"""
labview_copilot_bridge.py
LabVIEW の Python Node から呼び出すための同期ラッパーです。
GitHub Copilot SDK (github-copilot-sdk, `from copilot import CopilotClient`) は
中身が asyncio ベース(async def)ですが、LabVIEW の Python Node は
async def を直接呼び出せないため、内部で asyncio イベントループを
persistent に保持し、run_until_complete() 経由で叩く def 関数として
公開しています。
前提:
pip install github-copilot-sdk
GitHub Copilot CLI が認証済みであること
(SDKが内部でCLIをspawnして使うので、事前に `gh auth login` 等で
Copilotが使える状態にしておく必要があります)
LabVIEW側の呼び出し順序(重要):
1) Open Python Session でこのモジュールを開く(1回だけ)
2) open_session() … VI起動時に1回だけ呼ぶ
3) chat(prompt) … 何回でも呼べる
4) close_session() … VI停止時に1回だけ呼ぶ
5) Close Python Session
★注意★
open_session/chat/close_session はモジュールレベルの変数
(_loop, _client, _session) で状態を持ち回します。
LabVIEWが「Open Python Session」を3回とも同じセッションで
呼び出している(=同じPythonインタプリタが生き続けている)ことが
前提です。呼び出しごとに新しいPython Sessionを開いてしまうと、
グローバル変数がリセットされ、chat()やclose_session()が
「ERROR: no open session」を返します。
"""
import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler
# LabVIEWからの複数回呼び出しをまたいで保持する状態
_loop = None
_client = None
_session = None
def open_session(model="gpt-5"):
"""Copilot CLIを起動し、チャットセッションを1つ開く。
引数:
model (str): 使用するモデル名。省略時は "gpt-5"。
戻り値:
str: 成功時 "OK"、失敗時 "ERROR: <詳細>"
"""
global _loop, _client, _session
if _session is not None:
return "ERROR: session already open. call close_session() first."
try:
_loop = asyncio.new_event_loop()
asyncio.set_event_loop(_loop)
async def _open():
client = CopilotClient()
await client.start()
# on_permission_request は必須パラメータです。
# approve_all はツール呼び出し(シェル実行やファイル書き込み含む)を
# 無条件に許可するので、動作確認が済むまでは自己責任で。
# 厳しくしたい場合は自作のハンドラ関数に差し替えてください。
session = await client.create_session(
on_permission_request=PermissionHandler.approve_all,
model=model,
)
return client, session
_client, _session = _loop.run_until_complete(_open())
return "OK"
except Exception as exc:
_client = None
_session = None
return "ERROR: " + str(exc)
def chat(prompt):
"""1つのプロンプトを送り、Copilotの返答テキストを返す。
open_session() を先に呼んでおく必要があります。
引数:
prompt (str): ユーザーからの入力文
戻り値:
str: 成功時はCopilotの返答テキスト、失敗時は "ERROR: <詳細>"
"""
global _loop, _session
if _session is None or _loop is None:
return "ERROR: no open session. call open_session() first."
try:
async def _chat():
response = await _session.send_and_wait(prompt)
if response is None:
return "ERROR: timed out waiting for a reply."
return response.data.content
return _loop.run_until_complete(_chat())
except Exception as exc:
return "ERROR: " + str(exc)
def close_session():
"""チャットセッションを閉じ、Copilot CLIプロセスを停止する。
戻り値:
str: 成功時 "OK"、失敗時 "ERROR: <詳細>"
"""
global _loop, _client, _session
if _session is None and _client is None:
return "OK" # 既に閉じている
try:
async def _close():
if _session is not None:
await _session.disconnect()
if _client is not None:
await _client.stop()
if _loop is not None:
_loop.run_until_complete(_close())
_loop.close()
return "OK"
except Exception as exc:
return "ERROR: " + str(exc)
finally:
_client = None
_session = None
_loop = None
if __name__ == "__main__":
# ------------------------------------------------------------------
# python labview_copilot_bridge.py で直接実行したときの動作確認用エントリ
# ポイント:
# open_session/chat/close_session は LabVIEW からの呼び出しと同じ
# 「モジュールレベル変数で状態を持ち回す」経路をそのまま通すので、
# ここで正しく動けば LabVIEW 側でも同じ挙動になるはず、という確認になる。
# ------------------------------------------------------------------
# 動作確認用の固定プロンプト。内容は何でもよい。
TEST_PROMPT = "こんにちは。あなたは今何ができますか?一言で自己紹介してください。"
print("=== open_session() ===")
result = open_session()
print(result)
try:
if result != "OK":
print("open_session に失敗したため、以降の処理を中止します。")
else:
print()
print("=== chat() ===")
print(f"[prompt] {TEST_PROMPT}")
reply = chat(TEST_PROMPT)
print(f"[reply] {reply}")
finally:
print()
print("=== close_session() ===")
print(close_session())
…生成AIさんってすごいなぁと実感します。def関数の中にasync defを入れるか、async defを先に書いてdefではasync defを呼び出すだけにするか…この規模なら好みの問題かもしれません。LabVIEWからasync defを呼び出すとエラーになるのでdef関数の中に入れる方が安全かもですが。Pythonコードのできのよさについては私は判断できません。でも、そんな私がコードを読んで何を意図しているか何となくは分かるのでていねいに作っているんじゃないかな?まあ、最初はdefしかなかったので、ターミナルからPythonコードを直接呼んだときに確認できるように追加でお願いしましたが。
LabVIEWからPythonコードを呼び出す
あとは、PythonコードをLabVIEWのPythonノードで呼び出すだけですが、PythonノードがLabVIEWに実装されたのは2018年です。あるプロジェクトで別の担当者が作ったデータ解析用のPythonコードをLabVIEWから呼び出す処理を入れていましたが、関数の配列引数がnumpy.arrayでLabVIEWにはそのまま入れられなかったのでわざわざ通常のリストにして…話がそれますね。何で今さらPythonノードを紹介するようなことをしているかというと…
LabVIEW 2026 Q3からCommunityでも64bit版を使えるようになったから
です。私はこれをリリース直後にインストールしようとしましたが、どうしてもアクティブ化できず、日本NIに問い合わせて、通常は不要のはずのアクティブ化コードをもらって…ということをしましたが、これも話がそれますね。Pythonを使うなら64bitが一般的だと思いますし、LabVIEWとPythonのビット数は合わせないと使えないので、やっとCommunityでもPythonノードでいろいろできるようになったと感じます。
それで、実際に作ったVIはこんな感じです。

今回はUTF-8のブランクVIから作り始めたので、UTF-8が使えるところはUTF-8がデフォルト担っています。PythonのパスはLabVIEWが期待していた場所と違うようでユーザーフォルダのAppDataのどこかに入ったので、そこのpython.exeのパスを入れるようにしました。Pythonをインストールするときにパスの設定に問題でもあったのかな?LabVIEW側ではClaudeさんが作ったPythonノードの関数を呼び出すだけなので、VIはかなりシンプルです。実行するとこんな感じになります。

文字列制御器はUTF-8なので、絵文字も表現できます。色はないですが。昔からLabVIEWを使っていた人からするとこれはこれで驚きですが、話がそれるので深入りはしないでおきます。このプロンプトの1つ前にPythonで機械学習するのに必要なパッケージとそれをインストールするコマンドを質問して答えてもらっています。こんな答えだったかな?
pip install scikit-learn numpy pandas matplotlib graphviz scipy
あと、最初実行したときはエラーが発生して、その原因も要約すると「copilot loginをしていないから」と教えてもらいました。生成AIさんはすごいですね。でも、作成したpyファイルが何でそんな億なのかは分からないです。カレントディレクトリはそこじゃないはず。最終的に作ってもらったコードはこんな感じです。
Github Copilotさんに作ってもらった決定木のPythonコード
"""
決定木のサンプルコード
scikit-learnを使用した基本的な実装例
"""
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report
import matplotlib.pyplot as plt
# ============================================
# 1. サンプルデータの読み込み
# ============================================
print("=" * 50)
print("決定木の例:アイリス(あやめ)データセット")
print("=" * 50)
iris = load_iris()
X = iris.data # 特徴量(花の大きさなど)
y = iris.target # ターゲット(花の種類)
print(f"\nデータセット情報:")
print(f" サンプル数: {X.shape[0]}")
print(f" 特徴量の数: {X.shape[1]}")
print(f" クラス数: {len(set(y))}")
print(f" 特徴量の名前: {iris.feature_names}")
print(f" クラスの名前: {iris.target_names}")
# ============================================
# 2. データセットを訓練用とテスト用に分割
# ============================================
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
print(f"\nデータ分割:")
print(f" 訓練用: {X_train.shape[0]}件")
print(f" テスト用: {X_test.shape[0]}件")
# ============================================
# 3. 決定木モデルの作成と訓練
# ============================================
dt_classifier = DecisionTreeClassifier(
max_depth=5, # 木の最大深さ
random_state=42
)
dt_classifier.fit(X_train, y_train)
print(f"\n✅ 決定木の訓練が完了しました")
# ============================================
# 4. 予測と精度評価
# ============================================
y_pred = dt_classifier.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"\n📊 精度: {accuracy:.2%}")
print(f"\n詳細な分類レポート:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
# ============================================
# 5. 特定のサンプルで予測
# ============================================
sample = X_test[0].reshape(1, -1)
prediction = dt_classifier.predict(sample)
prediction_proba = dt_classifier.predict_proba(sample)
print(f"\n🔍 サンプル予測:")
print(f" 入力値: {sample[0]}")
print(f" 予測結果: {iris.target_names[prediction[0]]}")
print(f" 確信度: {prediction_proba[0].max():.2%}")
# ============================================
# 6. 決定木の可視化
# ============================================
print(f"\n📈 決定木を可視化しています...")
plt.figure(figsize=(20, 10))
plot_tree(
dt_classifier,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True
)
plt.title("アイリスデータセットの決定木")
plt.tight_layout()
plt.savefig("decision_tree.png", dpi=100, bbox_inches='tight')
print(" ✅ 'decision_tree.png' に保存しました")
# ============================================
# 7. 特徴量の重要度
# ============================================
print(f"\n🎯 特徴量の重要度:")
for name, importance in zip(iris.feature_names, dt_classifier.feature_importances_):
print(f" {name}: {importance:.4f}")
print("\n" + "=" * 50)
print("完了!")
print("=" * 50)

…正直なところ、自分自身が把握しているデータじゃないと、クラス分類の妥当性の判断はできないですね。でも、決定木をやろうとしているのは図示されています。あと、この手のデータサイエンス(特徴量の調査)は、PythonならJupyter LabやJupyter Notebookでいろいろ関数やパラメーターを触りながらやるんじゃないかな?と思っています。まあ、Pythonはほとんど使ったことないですが。MATLABなら多少はやったことがありますが、スクリプト(.m)を作るよりライブスクリプト(.mlx)でいろいろ設定を変えたり検証結果をメモしたりしながらやる感じだろうと思っています。
感想
今回は、私のプライベートの環境でNigel AIを使えないので、VIに生成AIさんを召喚してコードを生成するものを作りました。これではLabVIEWのようなグラフィカルなコードは作れませんが、テキスト言語のコードは作れます。改めて生成AIさんのすごさや技術進歩の早さを実感しました。
…LabVIEWから呼び出す意味?そんなものはないです。
LabVIEWがMCPクライアントになって、NIのハードウェアから取った計測データをサーバーに送ってサーバーに登録した関数を呼び出すとかできれば意味があるかもしれませんね。…知らんけど。

