AIで効率アップ！2つのウェブサイトを開発した話

**開発内容**

1. 個人ポートフォリオサイトの開発・公開
2. MBTI診断チャットボットの開発

![截屏2025-04-12 14.39.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535759/64eccd25-4cb9-41f8-9add-2d65b2a7d8c6.png) ![截屏2025-04-12 14.46.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535759/45c67045-1a9d-4522-a8a0-bd78175be954.png)







**使用技術**

- **AI開発ツール**: Cursor（AI搭載IDE）
- **AI API**: OpenAI API（GPTモデル）
- **フレームワーク**: LangChain（LLM連携）
- **その他**: フロントエンド/バックエンドの総合的な技術知識

**開発期間**

わずか3日間で:

- **要件定義**
- **UI/UXデザイン**
- **コーディング**
- **デプロイ**
    
    をすべて完了しました。
    

最近、AIツールの進化には本当に驚かされますよね。今回は、そんなAIの力を最大限に活用し、たった3日間で2つのウェブサイトを開発した経験をシェアしたいと思います。使ったのは、話題のAI搭載エディタ「Cursor」。コーディングのスピードが劇的に上がり、まるで魔法のような体験でした！

この記事では、Cursorを使った具体的なワークフローや、AIがどのように開発を加速させたのか、実際のコード例も交えながら解説します。フロントエンド開発で効率を求めている方、AIツールに興味がある方はぜひ参考にしてください！

なお、私自身はフロントエンド・バックエンド開発、ウェブUIデザイン、AI（大規模言語モデルを含む）の技術知識と実践経験を持っています。もしプログラミング経験が全くない場合、同じ効率を出すことは難しいかもしれません。

## 1つ目の開発サイト：個人ポートフォリオサイト

**1. ポートフォリオサイトの要件定義**

私の個人ポートフォリオサイト
https://houikkei-github-io.vercel.app/
主な機能として、

- ホーム
- スキル
- 学歴・職歴
- プロジェクト実績
- コンタクト
    
を設計しました。
    

**2. UI/UXにこだわったデザイン**

**【ホーム画面】**

印象的なファーストビューを実現するため、AIで生成したキャラクターがサイトの親しみやすさを引き立てます。

**【スキルセクション】**

- 技術スタックのロゴをアイコン展示
- 実務経験に基づくスキルを「動的なグラデーション文字」で表現
    
    （実際に使用したツールの知見がデザインに反映されています）
![截屏2025-04-12 14.52.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535759/2d48858f-5427-4dc6-9821-f81d1f2b6efb.png)
    

**【学歴・職歴】**

転職活動中の外国人エンジニアとして「視覚的にわかりやすい」ことを重視し、

- **左側：職歴**
- **右側：学歴**
    
    の2カラムタイムラインを採用。各企業・学校のロゴは公式サイトから直接取得しました（HTML/CSSの基礎知識が活きた場面です）。
    

職歴（左）と学歴（右）を分けた理由は、まさにこの「**中国式キャリアの可視化**」にあります。

- **日本の一般的なパターン**
    
    「大学→大学院→就職」の直線的な流れ
    
- **中国で多いパターン**
    
    「大学→就職→大学院→再就職」のループ構造
    
    → 職務経験が学術選択に影響を与えるため、分離表示が必要
![截屏2025-04-12 14.53.44 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535759/211f4daf-a0a7-4387-ad9d-7348a1ee2f21.png)


    

**【プロジェクト展示】**

プロジェクトはカード型デザインで表示しています。実際にはこれ以外にも多くのプロジェクトがありますが、転職活動に集中しているため更新が追いついていません。

現在は、外国人を積極的に受け入れ、内定書の内容通りに給与を支払い、日本の法律に基づいて社会保険を完備している企業を探すために転職活動中です。

**【コンタクト】**

スパム対策のため、フォームの内容は直接メールに転送されません。ただし、フッターにSNSリンクを設置し、技術交流希望の方とは積極的に繋がれるようにしています。


## 2つ目の開発サイト：MBTIチャットボット

**背景**

MBTI性格診断が大きな注目を集めています。多くの人々が、自己理解を深めたり、自身の性格タイプに基づいた具体的な解決策を求めるために利用しています。

**コンセプト**

このチャットボットでは、ユーザーが自身のMBTIタイプと質問を入力すると、LLM（大規模言語モデル）がその性格特性を考慮した回答を生成します。

**技術的な実装**

まずは基本的なチェーンとして、MBTIタイプと質問内容から回答を生成するシンプルなフローを定義しました。

（※実際の実装では、対話の深さやパーソナライズ度合いをさらに強化しています）

```js

  const agentPrompt = await ChatPromptTemplate.fromMessages([
    [
      "system",
      "あなたは受付担当のエージェントです。自然な会話を通じてユーザーのMBTIタイプと質問を確認し、
      十分な情報が得られたら get-mbti-chat を使用して回答を提供します。",
    ],
    new MessagesPlaceholder("history_message"),
    ["human", "{input}"],
    new MessagesPlaceholder("agent_scratchpad"),
  ]);

  const llm = new ChatOpenAI({
    modelName: "gpt-3.5-turbo",
    temperature: 0.4,
    configuration: {
      baseURL: process.env.OPENAI_API_BASE,
      apiKey: process.env.OPENAI_API_KEY,
      defaultHeaders: {
        "Content-Type": "application/json"
      }
    }
  });
  const agent = await createOpenAIToolsAgent({
    llm,
    tools,
    prompt: agentPrompt,
  });

  const agentExecutor = new AgentExecutor({
    agent,
    tools,
  });

```

このチェーンに必要なパラメータは：

```js

export async function getMBTIChatChain() {
  const prompt = ChatPromptTemplate.fromMessages([
    [
      "system",
      "あなたは共感力の高い心理カウンセラーで、MBTI（マイヤーズ・ブリッグス性格診断）の
      各タイプについて深い知識を持っています。来談者のMBTIタイプと質問に基づいて、感情豊かで
      深みのある共感的なサポートを提供し、前向きな気持ちで問題に向き合えるようにアドバイスすることが、
      あなたの役割です。",
    ],
    ["human", "ユーザーのMBTIタイプは{type}です。このタイプの特徴は{info}です。
    質問内容は{question}です。"],
  ]);

  const model = new ChatOpenAI({
    modelName: "gpt-3.5-turbo",
    configuration: {
      baseURL: process.env.OPENAI_API_BASE,
      apiKey: process.env.OPENAI_API_KEY,
      defaultHeaders: {
        "Content-Type": "application/json"
      }
    }
  });
  const mbtiChain = RunnableSequence.from([prompt, model, new StringOutputParser()]);

```

エージェントを作成し、ツールを追加し、このエージェントに履歴（history）を追加します。そして、Node.js の組み込みライブラリである readline を使用して、CLI で使用できるチャットボットを迅速に構築します。

```js
async function getAgent() {
  const mbtiChatChain = await getMBTIChatChain();

  const mbtiTool = new DynamicStructuredTool({
    name: "get-mbti-chat",
    schema: z.object({
      type: z.enum(mbtiList).describe("ユーザーのMBTIタイプ"),
      question: z.string().describe("ユーザーの質問"),
    }),
    func: async ({ type, question }) => {
      const info = mbtiInfo[type];
      const res = await mbtiChatChain.invoke({ type, question, info });
      return res;
    },
    description: "ユーザーの質問とMBTIタイプに基づいて回答を提供します",
  });

  const tools = [mbtiTool];

  const agentPrompt = await ChatPromptTemplate.fromMessages([
    [
      "system",
      "あなたは受付担当のエージェントです。自然な会話を通じてユーザーのMBTIタイプと質問を確認し、十分な情報が得られたら get-mbti-chat を使用して回答を提供します。",
    ],
    new MessagesPlaceholder("history_message"),
    ["human", "{input}"],
    new MessagesPlaceholder("agent_scratchpad"),
  ]);

```

```js
async function main() {
  const agent = await getAgent();

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  function chat() {
    rl.question("ユーザー: ", async (input) => {
      if (input.toLowerCase() === "exit") {
        rl.close();
        return;
      }

      const response = await agent.invoke(
        {
          input,
        },
        {
          configurable: {
            sessionId: "no-used",
          },
        }
      );

      console.log("アシスタント: ", response.output);

      chat();
    });
  }

  console.log("ご質問をどうぞ。チャットを終了する場合は「exit」と入力してください。");
  chat();
}
```


##### コア技術スタック: 

- OpenAI API (GPTモデルを活用)

- LangChain (LLM連携・チェーン管理)

- Node.js (バックエンド基盤)

具体的なAPI呼び出し結果は以下の通りです。

![截屏2025-04-12 15.18.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535759/7219ab7a-511b-49b4-9f94-0ec0992cea12.png)



##### 最終的にHTML + CSS + JavaScriptでフロントエンドページを生成しました。

以下が含まれます：

- MBTIタイプ選択プルダウン

- 相談カテゴリ選択（恋愛相談、キャリア相談、生活アドバイス、人間関係、資産運用）

- 質問入力欄

- チャット履歴表示エリア

- 送信ボタンとローディング状態表示

![截屏2025-04-12 15.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535759/b6ef4a00-cbf9-4221-b4ea-7d8426abd721.png)![截屏2025-04-12 15.30.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535759/99353e30-586f-4129-a53f-d88a7242f5c1.png)



###### 最後までお読みいただきありがとうございました。何かご質問や改善提案がありましたら、お気軽にご連絡ください。