1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHubのコードリーディングをするAIWebアプリ作ってみた。

Posted at

こんにちは、学生でエンジニアの勉強をしているあまみやです。

普段はWeb3関係の開発の勉強やWebアプリの開発を行っているのですが、趣味でほかの人のソースコードを読んで開発手法勉強しています。

ただコードを読むにあたっての悩みがあり、それは大規模なプロジェクトであればあるほどコードの量が膨大で追いきれないことです...(汗)

そこで複数のAPIとNextjsを用いてコードリーディングを行うWebアプリを開発しました。

注意
今回のようなケースでは頻繁にAPIにアクセスしてしまうとbot判定を食らってしまう可能性があり、迷惑にならない範囲で利用してください。

また完全な解説記事ではないので、いろいろggりながら見てもらえれば💦

実行環境

フレームワーク

  • nodejs 22.14.0 LTS
  • Nextjs 15.2
  • React 19
  • PandaCSS

エディター他

  • vscode
  • GitHub Copilot
  • Perplexity (API)
  • llama-3.1-sonar-large-128k-online(Perplexity向けLLM)

nodejsのパッケージマネージャーはお好みで。
なお今回はyarnを使用します

(補足)なぜPerplexityなのか?

もともと私がYmobileユーザーで、昨年SotbankとYmobileユーザー向けにPerplexityが一年無料になるキャンペーンを行っていました。

そこで有料プランに加入すると月当たり5ドルまでAPIが使用かのうになっており、コスパなどの面から使用しています。

Perplexityとsoftbankの関係については話が長くなるので省略。(すでに詳細がニュースや公式リリースにあがってます。)

開発手順

ライブラリインストール

yarn add @pandacss/dev @types/next @types/next @types/react @types/react-dom axios next react react-dom typescript

今回はCSSライブラリにPandaCSSを使います。

Nextjsの環境構築はすでに情報があるので割愛。

PandaCSS 初期設定

yarn add -D @pandacss/dev
yarn panda init --postcss

Nextjsのglobal.cssに以下を記載

global.css
@layer reset, base, tokens, recipes, utilities;

PerplexityとGitHubAPIキーの取得

  • PerplexityのAPI

  • GitHubのAPI

GithubのAPIに関してはレポジトリの読み取り権限くらいでいいと思います(私もググりながら設定したのでくわしくないです...w)

一応GitHubのREST APIについては公式ドキュメントを見るのが確実だと思います。

GitHubのAPIに関してはバージョン制なので注意です
2025年3月時点では2022-11-28が最新です。

Nextjsのミドルウェア作成

perplexityのAPIへのPOST要求はaxiosを使っています。
当初はfetch()を使っていたのですが、なぜかうまくいかず...以前作った別のAIチャットアプリでもaxiosをつかっていたので採用しました。

ai.ts
import axios from 'axios';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { repourl, message } = req.body;
    const msg = repourl + " " + message;
    try {
      const response = await axios.post('https://api.perplexity.ai/chat/completions', {
        model: 'llama-3.1-sonar-large-128k-online',
        messages: [{ role: 'user', content: msg }],
      }, {
        headers: {
          'Authorization': `Bearer ${process.env.PERPLEXITY_API_KEY}`,
          'Content-Type': 'application/json',
        },
      });

      res.status(200).json({ answer: response.data.choices[0].message.content });
    } catch (error) {
      console.error('Error:', error);
      res.status(500).json({ error: 'An error occurred while processing your request.' });
    }
  } else {
    res.setHeader('Allow', ['POST']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

modelの部分に関しては一期一句間違えずに記載しないとエラーになります。
ただ公式ドキュメントのモデル一覧の説明がイマイチわかりにくいです(前はもっとわかりやすかった)

今回はllama-3.1-sonar-large-128k-onlineを使用しています。これはllamaをベースに改良されたものっぽいです。

また別途GitHubのAPIにアクセスするためのミドルウェアを作成しています。

repo.ts
import { NextApiHandler } from "next"

const handler: NextApiHandler = async (req, res) => {
    const { user ,repo } = req.query
    const data = await fetch(`https://api.github.com/repos/${user}/${repo}`, {
        headers: {
            "Accept": "application/vnd.github.v3+json",
            // APIバージョン指定
            "X-Github-Api-Version": "2022-11-28",
            "Authorization": `token ${process.env.GITHUB_TOKEN}`,
        }
    })
    const data_json = await data.json()
    if (data_json.message === "Not Found") {
        res.status(404).json({ status: 66 })
        return
    } else {
        res.status(200).json({ data: data_json })
    }
    res.end()
}

export default handler

URLの形式を/user/GITHUB_USER_ID?repo=REPOSITORY_NAME としそこから得られたユーザーIDとリポジトリ名を取得、それをミドルウェアを介してGitHubからデータを取得する流れです。

フロントエンド側ではgetServerSideProps関数を用いて上記のミドルウェアに対してPOST要求を行っています。

[user].tsx
export async function getServerSideProps(context) {
    const { user, repo } = context.query
    try {
    //ミドルウェアPOST要求
        const response = await fetch(`http://<YOUR_SERVER_ADDRES>/api/repo?user=${user}&repo=${repo}`)
        if (!response.ok) {
            return {
                redirect: {
                //見つからなかった場合はリダイレクト
                    destination: '/404?status=not-found-repo',
                    permanent: false,
                }
            }
        }
        const github_code_json = await response.json()
        // 扱いやすいように形式を指定
        return {
            props: {
                data: {
                    status: "success",
                    user: user,
                    repo: repo,
                    data: github_code_json.data
                }
            },
        }
    } catch (error) {
        return {
            props: {
                data: {
                    status: "error",
                    error: error.message || "An unknown error occurred"
                }
            },
        }
    }
}

GitHubのAPI情報とフロントエンドから入力されたプロンプトをもとに先述の通りPerplexityのAPIにミドルウェア経由で要求を送信します。

最終的な動作の流れ

image.png

実際に稼働させたものがこちら

これはGitHub上のトーバルズ氏本人(?)のLinuxリポジトリです。
スクリーンショット 2025-03-20 165757.png

まとめ

今回はAPIなどの関係でGitHubのみの対応になりましたが、今後はいろんなリポジトリも読み取れるようにしたいです。

またセキュリティ上の懸念はMarkDown形式表示への対応などまだまだ改良点はあると思います。

今回はPerplexityのAPIを使いましたが、理論上はGeminiやGPT4のAPIでも可能です。

今回の記事のGitHubリポジトリ

参考リンク

  • Panda CSS

  • Perplexity

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?