🚀

VSCode - GitHub CopilotをローカルLLMで動かしてみた(Ollama, gpt-oss:20b)

に公開

背景

セキュリティ上の理由でオンラインLLMを使えない環境でも、ローカルLLMはどの程度実用できるのか試してみました。

読者層

「社外にコードを出せない」「ネット制限のある環境で開発」している人向け。

Ollamaとは

Ollamaとは、大規模言語モデル(LLM)をWindows、Mac、Linuxなどのローカル環境で簡単に実行できるツールです。複雑な設定をすることなく、さまざまなオープンソースモデルをダウンロード、管理、実行できます。

https://ollama.com/

gpt-oss:20bとは

gpt-oss:20bは、OpenAIによって開発・公開されたオープンウェイトの大規模言語モデルです。Apache 2.0ライセンスで提供されており、商用利用や改変、再配布が自由にできることが大きな特徴です。

https://openai.com/ja-JP/index/introducing-gpt-oss/

GitHub Copilot拡張機能とOllamaを連携する

  1. gpt-ossをダウンロードします。

    Ollamaでgpt-oss
    ollama pull gpt-oss:20b
    

    最も簡単な方法はGUI画面でダウンロードしたいLLM(モデル)を選択してチャットを行うことです。モデルがなければ自動的にダウンロードが始まります。
    ※画像はWindowsですが、Macでも同じです。

    Ollama gpt-ossをダウンロード

  2. Ollamaでサーバーを起動します。
    ollama serve はローカルでAPIサーバーを立ち上げるコマンドです。これによりVSCodeなどの外部ツールがOllamaに接続できるようになります。

    コマンド
    ollama serve
    
  3. VSCodeのGitHub CopilotからOllamaと接続します。
    ① 表示されているモデルを選択して
    ② モデルの管理を選択します

    ① 表示されているモデルを選択して, ② モデルの管理を選択します

    ③ ollamaを選択します
    ③ ollamaを選択します

    ④ gpt-oss:20bを選択してモデルを追加します
    ④ gpt-oss:20bを選択してモデルを追加します

    ⑤ 追加されたモデルからgpt-oss:20bを選択します
    ⑤ 追加されたモデルからgpt-oss:20bを選択します

  4. LLM(モデル)がgpt-oss:20bになっていることを確認します。

エラーで詰まったポイント

③ ollamaを選択します以降、サーバーは立ち上げているのになぜか繋がらずエラー(500)になった。

エラーのターミナル
[GIN] 2025/09/22 - 11:02:35 | 200 |    2.734875ms |       127.0.0.1 | GET      "/api/version"
[GIN] 2025/09/22 - 11:02:35 | 200 |     867.417µs |       127.0.0.1 | GET      "/api/tags"
[GIN] 2025/09/22 - 11:02:35 | 500 |    1.501208ms |       127.0.0.1 | POST     "/api/show"
Ollamaのアップデート
brew upgrade ollama

Ollamaをアップデートすることで繋がるようになりました。もし接続できないエラーに遭遇した場合はアップデートを試してみてください。

GitHub Copilot拡張機能-Ollama(gpt-oss:20b)を使ってみる

実行環境

MacBook Pro M4, メモリ:16GB
Visual Studio Code:1.104.1
Ollama:0.12.0
GitHub Copilot 拡張機能:1.372.0
GitHub Copilot Chat 拡張機能:0.31.1

実行時間の計測はしていませんが、体感としては、オンラインのGitHub Copilotより少し待つものの、十分に実用的な速度で応答しました。ローカル環境でここまで動くのは驚きでした。

  1. このコードは何ができるの?と質問

    出力結果
    main.pyは実行するとコンソールに Hello World と表示するだけのシンプルなスクリプトです。
    これ以外の機能はありません。
    

    VSCodeのスクショを示します。
    gpt-ossにこのコードは何ができるの?と質問

  2. プログラムの作成をお願い

    プロンプト
    #codebase 
    
    cliの電卓を作成してください。
    入力例:=1+2*3
    出力例:7
    
    逆ポーランド記法やスタックなどを使用して四則演算の優先順位を考慮してください。
    記述にない仕様はベストプラクティスを採用してください。
    
    
    main.py
    import argparse
    import operator
    import sys
    
    # ------------- 逆ポーランド記法変換(Shunting‑Yard) -------------
    def to_rpn(expression: str):
        """数式を RPN(逆ポーランド記法)に変換する"""
        # 演算子の優先順位
        precedence = {'+': 1, '-': 1, '*': 2, '/': 2}
        # 演算子の種類
        operators = set(precedence.keys())
        output = []
        stack = []
    
        # トークン化(数字と演算子を分離)
        tokens = []
        num = ''
        for ch in expression:
            if ch.isdigit() or ch == '.':
                num += ch
            else:
                if num:
                    tokens.append(num)
                    num = ''
                if ch in operators or ch in '()':
                    tokens.append(ch)
        if num:
            tokens.append(num)
    
        for token in tokens:
            if token.replace('.', '', 1).isdigit():          # 数字
                output.append(token)
            elif token in operators:                         # 演算子
                while stack and stack[-1] in operators and \
                    precedence[stack[-1]] >= precedence[token]:
                    output.append(stack.pop())
                stack.append(token)
            elif token == '(':
                stack.append(token)
            elif token == ')':
                while stack and stack[-1] != '(':
                    output.append(stack.pop())
                if stack and stack[-1] == '(':
                    stack.pop()
                else:
                    raise ValueError("不正な括弧の組み合わせです")
    
        while stack:
            if stack[-1] in '()':
                raise ValueError("不正な括弧の組み合わせです")
            output.append(stack.pop())
    
        return output
    
    # ------------- RPN 評価 -------------
    def evaluate_rpn(rpn_tokens):
        """RPN を評価して結果を返す"""
        ops = {
            '+': operator.add,
            '-': operator.sub,
            '*': operator.mul,
            '/': operator.truediv,
        }
        stack = []
    
        for token in rpn_tokens:
            if token in ops:
                if len(stack) < 2:
                    raise ValueError("式が不正です")
                b = stack.pop()
                a = stack.pop()
                result = ops[token](a, b)
                stack.append(result)
            else:
                stack.append(float(token))
    
        if len(stack) != 1:
            raise ValueError("式が不正です")
        return stack[0]
    
    # ------------- CLI 部分 -------------
    def main():
        parser = argparse.ArgumentParser(description="シンプルな CLI 電卓")
        parser.add_argument('expression', help='計算したい式(例: 1+2*3)')
        args = parser.parse_args()
    
        try:
            rpn = to_rpn(args.expression)
            result = evaluate_rpn(rpn)
            # 整数なら整数で表示
            if result.is_integer():
                print(int(result))
            else:
                print(result)
        except Exception as e:
            print(f"エラー: {e}", file=sys.stderr)
            sys.exit(1)
    
    if __name__ == "__main__":
        main()
    
    実行結果
    python3 main.py "1+2*3"
    7
    
    python3 main.py "(1+2)*3"
    9
    
    python3 main.py "10/2+5*3"
    20
    

    VSCodeのスクショを示します。
    ※Pylance拡張機能を入れているのでエラーが出ていますが、実行には影響ありません。

    gpt-ossにプログラムの作成をお願い

    gpt-oss:20b 出力全文

    以下のように main.py を書き換えると、コマンドラインから式を渡して計算結果を表示できます。

    逆ポーランド記法(RPN)を作るために Shunting‑Yard アルゴリズムを使用
    RPN を評価する際はスタックを利用
    例: python [main.py] "1+2*3" → 7



    ...(コード部分は省略)...

    使い方

    ターミナル
    $ python main.py "1+2*3"
    7
    $ python main.py "(1+2)*3"
    9
    $ python main.py "10/2+5*3"
    20.0
    

    この実装は

    括弧の入れ子も正しく処理
    小数点を含む数値も扱える
    エラー時に分かりやすいメッセージを出力
    というベストプラクティスを踏まえています。

    gpt-oss:20b • 0x

まとめ

ローカルLLM(モデル)でも規模の小さなプロジェクトの場合は実用できそうな結果となりました。
大規模プロジェクトの例は割愛しましたが、大規模なプロジェクトの場合はコンテキストオーバーになり、結果が返ってこないことがありました。その場合はLLMが参照できるコードを減らす、PCのメモリやGPUを強化することで、解決できる可能性があります。

Discussion