[生成AI] シンプルなLangChainのサンプル

# 1.動機
Agentで試したいことができたので、下記の方針を考えています。
<dl>
<dt>・LangChain/LangGraphで試す</dt>
<dd>いろいろAI Agentのフレームワークはありますが、まずメジャーなところでやってみようと思いました。</dd>
</dt><br/>
<dt>・node.js上のJavaScript/TypeScriptを試す</dt>
<dd>LangChainは、python環境の方がより使われているのではないかと思いますが、EC2/ECS上での動作はコストがかかるし、Lambdaは実行時間が15分以内という制約があるので、S3上のWeb Hostingで動作できれば、コストが低く抑えられるかも目論んでいます。
</dd>
</dt>
</dl>

準備として、<font color="red">LangChainの簡単なサンプルをいろいろ試してみたら、なんか上手く動きませんでした。</font>:sob:

どうも、世の中のサンプルがLangChainのv0.1やv0.2を元に作られているものが多く、v0.3だとそのままでは動作しなかったようです。

試行錯誤して、動くサンプルができたので、残しておこうと思いました。
・会話履歴付きのチャットボット
・RAGチャットボット
・簡単なAI Agent（お天気検索）
・簡単なMulti AI Agent（調査とまとめ）
・試したいことのさわり（要求分析と機能設計）

# 2.簡単なサンプル
### 2.1.会話履歴付きのチャットボット
シンプルなチャットボットですが、会話履歴もAIに送っています。


下記の記事のdemo03.tsを元にしています。記事では、pnpm/typescript版ですが、ここでは、npm/javascriptで動作を確認したものになります。

https://zenn.dev/hayato94087/articles/3a9cf81d1b8dd3

（１）ライブラリの組込み
下記のコマンドを実行して、
　・LangChainのコア機能(@langchain/core)
　・OpenAI用のインタフェース(@langchain/openai)
　・環境へのアクセスモジュール(dotenv)
　・uuid作成用モジュール（uuid)
 を組み込みます。
 
 uuidは、チャット履歴のユニークな識別して、使用しました。

```
npm i langchain @langchain/core @langchain/openai dotenv uuid
```

上記を実行直後のpackage.jsonは、私の環境では以下の通りでした。
```ruby:package.json
{
  "dependencies": {
    "@langchain/core": "^0.3.38",
    "@langchain/openai": "^0.4.2",
    "dotenv": "^16.4.7",
    "langchain": "^0.3.15",
    "uuid": "^11.0.5"
  }
}
```


（２）.envファイルの作成
.envファイルを作成し、環境変数OPENAI_API_KEYにアクセスキーを設定します。XXXXのところは、実際にOpenAIから取得したAPI KEYを記載います。

```ruby:.env
OPENAI_API_KEY='xxxxxx'
```

（３）pacage.jsonの修正
下記のwarningを回避するために、package.jsonに"type": "module"を追加します。

```ruby:回避したい警告メッセージ
(node:14584) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///C:/Users/yamaz/Dropbox/work/LangChainTurtorial/12_Summry/MyChatBot/MyChatbot.js is not specified and it doesn't parse as CommonJS.
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
To eliminate this warning, add "type": "module" to C:\Users\yamaz\Dropbox\work\LangChainTurtorial\12_Summry\package.json.
```

```ruby:package.json
{
  "type": "module",
  "dependencies": {
    "@langchain/core": "^0.3.38",
    "@langchain/openai": "^0.4.2",
    "dotenv": "^16.4.7",
    "langchain": "^0.3.15",
    "uuid": "^11.0.5"
  }
}
```

（４）プログラムのソースコード
下記のソースファイルを作成します。

```ruby:MyChatBot.js
//参考『LangChain でチャットボットを構築（Node.js）』
//https://zenn.dev/hayato94087/articles/3a9cf81d1b8dd3


import { ChatOpenAI } from "@langchain/openai";
import { InMemoryChatMessageHistory } from "@langchain/core/chat_history";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { RunnablePassthrough, RunnableSequence, RunnableWithMessageHistory } from "@langchain/core/runnables";
import * as readline from 'readline';
import 'dotenv/config'
import { v4 as uuidv4 } from 'uuid';

// 保持するチャット履歴の数
const HISTORY_SIZE = 10;

// モデル生成
const model = new ChatOpenAI(
    {
      model: "gpt-4o",
      API_KEY: process.env.OPENAI_API_KEY
    });

// プロンプト
const prompt = ChatPromptTemplate.fromMessages([
    [
        "system",
        `あなたは私が送ったメッセージをすべて覚えている親切なアシスタントです。`,
    ],
    ["placeholder", "{chat_history}"],
    ["human", "{input}"],
]);

// メッセージの初期化
const messageHistories = {};

// chain
const chain = RunnableSequence.from([
    RunnablePassthrough.assign({
        chat_history: (params) => {
            return Array.isArray(params.chat_history) ? params.chat_history.slice(-1 * HISTORY_SIZE) : [];
        },
    }),
    prompt,
    model,
]);

//チャット履歴付きの呼出し
const withMessageHistory = new RunnableWithMessageHistory({
    runnable: chain,
    getMessageHistory: async (sessionId) => {
        if (messageHistories[sessionId] === undefined) {
            messageHistories[sessionId] = new InMemoryChatMessageHistory();
        }
        return messageHistories[sessionId];
    },
    inputMessagesKey: "input",
    historyMessagesKey: "chat_history",
});

//セッション情報
const config = {
    configurable: {
        sessionId: uuidv4()
    },
};

// Create interface for reading from console
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// Prompt user for input
rl.setPrompt('入力してください > ');
rl.prompt();

// 入力イベント処理
rl.on('line', async (input) => {
    const response = await withMessageHistory.invoke(
        {
            input: input
        },
        config
    );

    console.log(`AI Assistant: ${response.content}`);
    rl.prompt();
});

// 終了イベント処理
rl.on('close', () => {
    console.log('プログラムを終了します');
    process.exit(0);
});
```

（５）プログラムの実行
私の環境では、下記のような警告が出るので、--no-deprecationオプションをつけています。

```ruby:回避したい警告メッセージ
(node:40460) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
```

```ruby:プルグラムの実行
node --no-deprecation MyChatbot.js
```

実行結果は、下記のようになり、会話の履歴をおぼいていました。

<details>

:::note
PS C:\Users\yamaz\Dropbox\work\LangChainTurtorial\12_Summry\MyChatBot> node --no-deprecation .\MyChatbot.js
入力してください > こんにちは。私は、山田太郎です。
AI Assistant: こんにちは、山田太郎さん。今日はどんなお手伝いをしましょうか？
入力してください > あなたの役割を教えてください。
AI Assistant: 私は親切なアシスタントで、情報提供や質問への回答、タスクの手助けなどを行います。何か知りたいことやお手伝いできることがあれば、どうぞ教えてください。
入力してください > 私の名前を憶えていますか。
AI Assistant: はい、あなたの名前は山田太郎さんですね。
入力してください >

:::

</details>


### 2.2.RAGチャットボット
RAGを検索するチャットボットのサンプルです。Windsurfで、ほぼ自動生成できましたが、v2とv3の非互換性解消のため、正しいimport文に直すところが大変でした。

https://windsurfai.org/ja

（１）ライブラリの組込み
下記のコマンドを実行して、
　・LangChainのコア機能(@langchain/core)
　・OpenAI用のインタフェース(@langchain/openai)
  ・テキスト分割(@langchain/textsplitters)
　・Third Party作成のライブラリ(@langchain/community)
　・環境へのアクセスモジュール(dotenv)
　・ベクターデータ処理用モジュール（faiss-node)
  ・HTML処理用モジュール(cheerio)
 を組み込みます。

```
npm i langchain @langchain/core @langchain/openai @langchain/community @langchain/textsplitters dotenv faiss-node cheerio

```

（２）.envファイルの作成　※上記2.1節と同様
（３）pacage.jsonの修正　※上記2.1節と同様

（４）プログラムのソースコード
下記のソースファイルを作成します。
```ruby:RagChat.js
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { RunnableSequence, RunnablePassthrough } from "@langchain/core/runnables";
import { FaissStore } from "@langchain/community/vectorstores/faiss";
import { OpenAIEmbeddings } from "@langchain/openai";
import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";

import * as readline from 'readline';
import 'dotenv/config';


// Initialize the model
const model = new ChatOpenAI({
    model: "gpt-4",
    temperature: 0.7,
});

// Initialize the embeddings
const embeddings = new OpenAIEmbeddings();

// Create a vector store
const loader = new CheerioWebBaseLoader(
    "https://js.langchain.com/docs/get_started/introduction"
);

// Load and process the documents
const docs = await loader.load();
const textSplitter = new RecursiveCharacterTextSplitter({
    chunkSize: 500,
    chunkOverlap: 0,
});

const splitDocs = await textSplitter.splitDocuments(docs);
const vectorStore = await FaissStore.fromDocuments(splitDocs, embeddings);

// Create a retriever
const retriever = vectorStore.asRetriever();

// Create the prompt template
const prompt = ChatPromptTemplate.fromTemplate(`
Answer the question based on the following context:

Context: {context}

Question: {question}

Answer the question in a helpful and informative way. If you don't know the answer, just say you don't know.
`);

// Create the chain
const chain = RunnableSequence.from([
    {
        context: retriever.pipe(docs => docs.map(doc => doc.pageContent).join("\n\n")),
        question: new RunnablePassthrough(),
    },
    prompt,
    model,
    new StringOutputParser(),
]);

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

// Prompt user for input
rl.setPrompt('Enter your question > ');
rl.prompt();

// Handle user input
rl.on('line', async (input) => {
    if (input.toLowerCase() === 'exit') {
        rl.close();
        return;
    }

    try {
        const response = await chain.invoke(input);
        console.log('\nAI: ' + response + '\n');
    } catch (error) {
        console.error('Error:', error.message);
    }
    rl.prompt();
});

// Handle close event
rl.on('close', () => {
    console.log('\nGoodbye!');
    process.exit(0);
});

```

（５）プログラムの実行

```ruby:プルグラムの実行
node --no-deprecation RagChat.js
```

実行結果は、下記のようになりました。
RAGで参照しているLangChainの情報は回答がありましたが、geminiは情報がないので、無回答。ChatGPTで処理しているので、ChatGPTはコンテキストには情報がないことを添えて、補足情報をつけてきました。

<details>

:::note
PS C:\Users\yamaz\Dropbox\work\LangChainTurtorial\12_Summry\RagChat> node --no-deprecation .\RagChat.js
Enter your question > LangChainの特徴を教えてください。

AI: LangChainは、大規模な言語モデル（LLMs）によって動くアプリケーションを開発するためのフレームワークです。LangChainはLLMアプリケーションのライフサイクルのすべての段階を簡素化します。開発段階では、LangChainのオープンソースのビルディングブロック、コンポーネント、サードパーティの統合を使用してアプリケーションを構築できます。また、LangChainには詳細なAPIリファレンスがあり、LangChain JavaScriptパッケージのすべてのクラスとメソッドの完全なドキュメンテーションを提供しています。このドキュメンテーションは主にJavaScript LangChainライブラリに焦点を当てていますが、Python LangChainライブラリに関するドキュメンテーションもあります。さらに、具体的なものを構築したい方や実践的な学習者のためのチュートリアルも提供しています。

Enter your question > Geminiの特徴を教えてください。

AI: I'm sorry, but the context provided does not include any information about Gemini.

Enter your question > ChatGPTの特徴を教えたください。

AI: 申し訳ありませんが、提供されたコンテキストではChatGPTの特徴については言及されておりません。ただし、一般的 に言えば、ChatGPTはOpenAIによって開発された人工知能ベースのチャットボットで、自然言語処理(NLP)技術を使用して人間のような会話を生成することが可能です。また、ChatGPTは大量のテキストデータから学習するため、多様なトピックに ついて人間のように対話することができます。ただし、その回答は完全に学習したデータに基づいているため、新たな情報や事実を自分で生成することはできません。

:::

</details>


# 2.3.簡単なAI Agent（お天気検索）
Windsurfで、ほぼ自動生成の簡単なAI Agentです。

https://windsurfai.org/ja

（１）ライブラリの組込み
下記のコマンドを実行して、
　・LangChainのコア機能(@langchain/core)
　・OpenAI用のインタフェース(@langchain/openai)
  ・テキスト分割(@langchain/textsplitters)
　・Third Party作成のライブラリ(@langchain/community)
　・環境へのアクセスモジュール(dotenv)
　・ベクターデータ処理用モジュール（faiss-node)
  ・HTML処理用モジュール(cheerio)
 を組み込みます。

```
npm install @langchain/core @langchain/openai @langchain/community dotenv

```

（２）SERP APIのアカウント作成と、API KEYの取得
検索にSERP APIを使用します。100回までのアクセスは無料です。

https://www.searchapi.io/

（３）.envファイルの作成
OpenAIとSERP APIのAPI KEYを設定します。

```
OPENAI_API_KEY='XXXXX'
SERPAPI_API_KEY='XXXXX'
```

（４）pacage.jsonの修正　※上記2.1節と同様

（５）プログラムのソースコード
下記のソースファイルを作成します。
```ruby:SimpleAgent.js
import { ChatOpenAI } from "@langchain/openai";
import { initializeAgentExecutorWithOptions } from "langchain/agents";
import { SerpAPI } from "@langchain/community/tools/serpapi";
import { Calculator } from "@langchain/community/tools/calculator";
import 'dotenv/config';

// OpenAI API keyを設定
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
const SERPAPI_API_KEY = process.env.SERPAPI_API_KEY;

async function main() {
    // LLMの初期化
    const model = new ChatOpenAI({
        temperature: 0,
        openAIApiKey: OPENAI_API_KEY,
    });

    // ツールの設定
    const tools = [
        new SerpAPI(SERPAPI_API_KEY),
        new Calculator(),
    ];

    // エージェントの初期化
    const executor = await initializeAgentExecutorWithOptions(
        tools,
        model,
        {
            agentType: "zero-shot-react-description",
            verbose: true,
        }
    );

    // エージェントの実行例
    const input = "東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。";
    console.log("質問:", input);

    const result = await executor.run(input);
    console.log("回答:", result);
}

main().catch((error) => {
    console.error("エラーが発生しました:", error);
});

```

（６）プログラムの実行

```ruby:プルグラムの実行
node --no-deprecation SimpleAgent.js
```

実行結果は、下記のようになりました。

<details>

:::note

PS C:\Users\yamaz\Dropbox\work\LangChainTurtorial\12_Summry\SimpleAgent> node --no-deprecation SimpleAgent.js
質問: 東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。
[chain/start] [1:chain:AgentExecutor] Entering Chain run with input: {
  "input": "東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。"
}
[chain/start] [1:chain:AgentExecutor > 2:chain:LLMChain] Entering Chain run with input: {
  "input": "東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。",
  "agent_scratchpad": "",
  "stop": [
    "\nObservation: "
  ]
}
[llm/start] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:ChatOpenAI] Entering LLM run with input: {
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain_core",
          "messages",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "Answer the following questions as best you can. You have access to the following tools:\n\nsearch: a search engine. useful for when you need to answer questions about current events. input should be a search query.\ncalculator: Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.\n\nUse the following format in your response:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [\"search\", \"calculator\"]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。\nThought:", 
          "additional_kwargs": {},
          "response_metadata": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:ChatOpenAI] [1.27s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\"",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\"",
            "additional_kwargs": {},
            "response_metadata": {
              "tokenUsage": {
                "promptTokens": 224,
                "completionTokens": 29,
                "totalTokens": 253
              },
              "finish_reason": "stop",
              "model_name": "gpt-3.5-turbo-0125"
            },
            "id": "chatcmpl-AyIx0NDlPcyRyfypQJ4kVISrwKNAW",
            "tool_calls": [],
            "invalid_tool_calls": [],
            "usage_metadata": {
              "output_tokens": 29,
              "input_tokens": 224,
              "total_tokens": 253,
              "input_token_details": {
                "audio": 0,
                "cache_read": 0
              },
              "output_token_details": {
                "audio": 0,
                "reasoning": 0
              }
            }
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "promptTokens": 224,
      "completionTokens": 29,
      "totalTokens": 253
    }
  }
}
[chain/end] [1:chain:AgentExecutor > 2:chain:LLMChain] [1.28s] Exiting Chain run with output: {
  "text": "I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\""
}
[agent/action] [1:chain:AgentExecutor] Agent selected action: {
  "tool": "search",
  "toolInput": "current temperature in Tokyo",
  "log": "I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\""
}
[tool/start] [1:chain:AgentExecutor > 4:tool:SerpAPI] Entering Tool run with input: "current temperature in Tokyo"
[tool/end] [1:chain:AgentExecutor > 4:tool:SerpAPI] [2.98s] Exiting Tool run with output: "{"type":"weather_result","temperature":"40","unit":"Fahrenheit","precipitation":"10%","humidity":"41%","wind":"12 mph","location":"Tokyo, Japan","date":"Friday 10:00 PM","weather":"Clear"}"
[chain/start] [1:chain:AgentExecutor > 5:chain:LLMChain] Entering Chain run with input: {
  "input": "東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。",
  "agent_scratchpad": "I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\"\nObservation: {\"type\":\"weather_result\",\"temperature\":\"40\",\"unit\":\"Fahrenheit\",\"precipitation\":\"10%\",\"humidity\":\"41%\",\"wind\":\"12 mph\",\"location\":\"Tokyo, Japan\",\"date\":\"Friday 10:00 PM\",\"weather\":\"Clear\"}\nThought:",
  "stop": [
    "\nObservation: "
  ]
}
[llm/start] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:ChatOpenAI] Entering LLM run with input: {      
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain_core",
          "messages",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "Answer the following questions as best you can. You have access to the following tools:\n\nsearch: a search engine. useful for when you need to answer questions about current events. input should be a search query.\ncalculator: Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.\n\nUse the following format in your response:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [\"search\", \"calculator\"]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。\nThought:I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\"\nObservation: {\"type\":\"weather_result\",\"temperature\":\"40\",\"unit\":\"Fahrenheit\",\"precipitation\":\"10%\",\"humidity\":\"41%\",\"wind\":\"12 mph\",\"location\":\"Tokyo, Japan\",\"date\":\"Friday 10:00 PM\",\"weather\":\"Clear\"}\nThought:",
          "additional_kwargs": {},
          "response_metadata": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:ChatOpenAI] [669ms] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I have found the current temperature in Tokyo and it is 40 degrees Fahrenheit.\nAction: calculator\nAction Input: (40 * 9/5) + 32",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I have found the current temperature in Tokyo and it is 40 degrees Fahrenheit.\nAction: calculator\nAction Input: (40 * 9/5) + 32",
            "additional_kwargs": {},
            "response_metadata": {
              "tokenUsage": {
                "promptTokens": 309,
                "completionTokens": 34,
                "totalTokens": 343
              },
              "finish_reason": "stop",
              "model_name": "gpt-3.5-turbo-0125"
            },
            "id": "chatcmpl-AyIx3jnsoxkDE1FVaffa55c5o9XPw",
            "tool_calls": [],
            "invalid_tool_calls": [],
            "usage_metadata": {
              "output_tokens": 34,
              "input_tokens": 309,
              "total_tokens": 343,
              "input_token_details": {
                "audio": 0,
                "cache_read": 0
              },
              "output_token_details": {
                "audio": 0,
                "reasoning": 0
              }
            }
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "promptTokens": 309,
      "completionTokens": 34,
      "totalTokens": 343
    }
  }
}
[chain/end] [1:chain:AgentExecutor > 5:chain:LLMChain] [669ms] Exiting Chain run with output: {
  "text": "I have found the current temperature in Tokyo and it is 40 degrees Fahrenheit.\nAction: calculator\nAction Input: (40 * 9/5) + 32"
}
[agent/action] [1:chain:AgentExecutor] Agent selected action: {
  "tool": "calculator",
  "toolInput": "(40 * 9/5) + 32",
  "log": "I have found the current temperature in Tokyo and it is 40 degrees Fahrenheit.\nAction: calculator\nAction Input: (40 * 9/5) + 32"
}
[tool/start] [1:chain:AgentExecutor > 7:tool:Calculator] Entering Tool run with input: "(40 * 9/5) + 32"      
[tool/end] [1:chain:AgentExecutor > 7:tool:Calculator] [2ms] Exiting Tool run with output: "104"
[chain/start] [1:chain:AgentExecutor > 8:chain:LLMChain] Entering Chain run with input: {
  "input": "東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。",
  "agent_scratchpad": "I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\"\nObservation: {\"type\":\"weather_result\",\"temperature\":\"40\",\"unit\":\"Fahrenheit\",\"precipitation\":\"10%\",\"humidity\":\"41%\",\"wind\":\"12 mph\",\"location\":\"Tokyo, Japan\",\"date\":\"Friday 10:00 PM\",\"weather\":\"Clear\"}\nThought:I have found the current temperature in Tokyo and it is 40 degrees Fahrenheit.\nAction: calculator\nAction Input: (40 * 9/5) + 32\nObservation: 104\nThought:",
  "stop": [
    "\nObservation: "
  ]
}
[llm/start] [1:chain:AgentExecutor > 8:chain:LLMChain > 9:llm:ChatOpenAI] Entering LLM run with input: {      
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain_core",
          "messages",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "Answer the following questions as best you can. You have access to the following tools:\n\nsearch: a search engine. useful for when you need to answer questions about current events. input should be a search query.\ncalculator: Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.\n\nUse the following format in your response:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [\"search\", \"calculator\"]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 東京の現在の気温は何度ですか？また、その温度を華氏に変換してください。\nThought:I need to find out the current temperature in Tokyo and convert it to Fahrenheit.\nAction: search\nAction Input: \"current temperature in Tokyo\"\nObservation: {\"type\":\"weather_result\",\"temperature\":\"40\",\"unit\":\"Fahrenheit\",\"precipitation\":\"10%\",\"humidity\":\"41%\",\"wind\":\"12 mph\",\"location\":\"Tokyo, Japan\",\"date\":\"Friday 10:00 PM\",\"weather\":\"Clear\"}\nThought:I have found the current temperature in Tokyo and it is 40 degrees Fahrenheit.\nAction: calculator\nAction Input: (40 * 9/5) + 32\nObservation: 104\nThought:",
          "additional_kwargs": {},
          "response_metadata": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:AgentExecutor > 8:chain:LLMChain > 9:llm:ChatOpenAI] [626ms] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I now know the final answer\nFinal Answer: The current temperature in Tokyo is 40 degrees Celsius, which is 104 degrees Fahrenheit.",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I now know the final answer\nFinal Answer: The current temperature in Tokyo is 40 degrees Celsius, which is 104 degrees Fahrenheit.",
            "additional_kwargs": {},
            "response_metadata": {
              "tokenUsage": {
                "promptTokens": 351,
                "completionTokens": 28,
                "totalTokens": 379
              },
              "finish_reason": "stop",
              "model_name": "gpt-3.5-turbo-0125"
            },
            "id": "chatcmpl-AyIx4UYPLdh5WSvuHL3bQiGoEgcAu",
            "tool_calls": [],
            "invalid_tool_calls": [],
            "usage_metadata": {
              "output_tokens": 28,
              "input_tokens": 351,
              "total_tokens": 379,
              "input_token_details": {
                "audio": 0,
                "cache_read": 0
              },
              "output_token_details": {
                "audio": 0,
                "reasoning": 0
              }
            }
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "promptTokens": 351,
      "completionTokens": 28,
      "totalTokens": 379
    }
  }
}
[chain/end] [1:chain:AgentExecutor > 8:chain:LLMChain] [628ms] Exiting Chain run with output: {
  "text": "I now know the final answer\nFinal Answer: The current temperature in Tokyo is 40 degrees Celsius, which is 104 degrees Fahrenheit."
}
[chain/end] [1:chain:AgentExecutor] [5.57s] Exiting Chain run with output: {
  "output": "The current temperature in Tokyo is 40 degrees Celsius, which is 104 degrees Fahrenheit."        
}
回答: The current temperature in Tokyo is 40 degrees Celsius, which is 104 degrees Fahrenheit.

:::

</details>

# 2.4.簡単なMulti AI Agent（調査とまとめ）
こSER PAPIを使用して調査するエージェントと、調査結果をまとめるエージェントの二つで動作するMulti Ai Agentのサンプルです。れもWindsurfで、ほぼ自動生成しています。

（１）ライブラリの組込み　※2.3節と同じ
（２）SERP APIのアカウント作成と、API KEYの取得　※2.3節と同じ
（３）.envファイルの作成　※2.3節と同じ
（３）pacage.jsonの修正　※上記2.1節と同様

（４）プログラムのソースコード
下記のソースファイルを作成します。
```ruby:MultiAgent.js
import { ChatOpenAI } from "@langchain/openai";
import { initializeAgentExecutorWithOptions } from "langchain/agents";
import { SerpAPI } from "@langchain/community/tools/serpapi";
import { Calculator } from "@langchain/community/tools/calculator";
import { RunnableSequence } from "@langchain/core/runnables";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { PromptTemplate } from "@langchain/core/prompts";
import 'dotenv/config';



const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
const SERPAPI_API_KEY = process.env.SERPAPI_API_KEY;

// 研究者エージェントの作成
async function createResearcherAgent() {
    const model = new ChatOpenAI({
        temperature: 0,
        openAIApiKey: OPENAI_API_KEY,
    });

    const tools = [
        new SerpAPI(SERPAPI_API_KEY),
        new Calculator(),
    ];

    return await initializeAgentExecutorWithOptions(tools, model, {
        agentType: "zero-shot-react-description",
        verbose: true,
    });
}

// 執筆者エージェントの作成
async function createWriterAgent() {
    const model = new ChatOpenAI({
        temperature: 0.7,
        openAIApiKey: OPENAI_API_KEY,
    });

    const writerPrompt = PromptTemplate.fromTemplate(
        `以下の情報を元に、簡潔で分かりやすい記事を作成してください。
        情報: {research_results}
        
        記事は以下の形式で作成してください：
        - タイトル
        - 概要（100文字程度）
        - 本文（重要なポイントを3つ程度）
        - まとめ`
    );

    return RunnableSequence.from([
        writerPrompt,
        model,
        new StringOutputParser(),
    ]);
}

async function main() {
    // エージェントの初期化
    const researcher = await createResearcherAgent();
    const writer = await createWriterAgent();

    // 研究テーマ
    const topic = "量子コンピュータの最新動向について";
    console.log("研究テーマ:", topic);

    // Step 1: 研究者エージェントが情報収集
    console.log("\n=== 研究フェーズ ===");
    const researchResults = await researcher.run(
        `${topic}について、最新の進展、主要な企業の取り組み、課題点を調査してください。`
    );

    // Step 2: 執筆者エージェントが記事作成
    console.log("\n=== 執筆フェーズ ===");
    const article = await writer.invoke({
        research_results: researchResults
    });

    console.log("\n=== 最終記事 ===");
    console.log(article);
}

main().catch((error) => {
    console.error("エラーが発生しました:", error);
});

```

（５）プログラムの実行

```ruby:プルグラムの実行
node --no-deprecation MultiAgent.js
```

実行結果は、下記のようになりました。

<details>

:::note
PS C:\Users\yamaz\Dropbox\work\LangChainTurtorial\12_Summry\MultiAgent> node --no-deprecation '.\MultiAgents copy.js'
研究テーマ: 量子コンピュータの最新動向について

=== 研究フェーズ ===
[chain/start] [1:chain:AgentExecutor] Entering Chain run with input: {
  "input": "量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題点を調査してください。"
}
[chain/start] [1:chain:AgentExecutor > 2:chain:LLMChain] Entering Chain run with input: {
  "input": "量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題点を調査してください。",
  "agent_scratchpad": "",
  "stop": [
    "\nObservation: "
  ]
}
[llm/start] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:ChatOpenAI] Entering LLM run with input: {
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain_core",
          "messages",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "Answer the following questions as best you can. You have access to the following tools:\n\nsearch: a search engine. useful for when you need to answer questions about current events. input should be a search query.\ncalculator: Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.\n\nUse the following format in your response:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [\"search\", \"calculator\"]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題 点を調査してください。\nThought:",
          "additional_kwargs": {},
          "response_metadata": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:ChatOpenAI] [1.41s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"",    
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"",
            "additional_kwargs": {},
            "response_metadata": {
              "tokenUsage": {
                "promptTokens": 244,
                "completionTokens": 37,
                "totalTokens": 281
              },
              "finish_reason": "stop",
              "model_name": "gpt-3.5-turbo-0125"
            },
            "id": "chatcmpl-AyJPd3jaZZ1kq2LoOScbriFNvxQY7",
            "tool_calls": [],
            "invalid_tool_calls": [],
            "usage_metadata": {
              "output_tokens": 37,
              "input_tokens": 244,
              "total_tokens": 281,
              "input_token_details": {
                "audio": 0,
                "cache_read": 0
              },
              "output_token_details": {
                "audio": 0,
                "reasoning": 0
              }
            }
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "promptTokens": 244,
      "completionTokens": 37,
      "totalTokens": 281
    }
  }
}
[chain/end] [1:chain:AgentExecutor > 2:chain:LLMChain] [1.41s] Exiting Chain run with output: {
  "text": "I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\""
}
[agent/action] [1:chain:AgentExecutor] Agent selected action: {
  "tool": "search",
  "toolInput": "latest developments in quantum computing 2021",
  "log": "I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\""
}
[tool/start] [1:chain:AgentExecutor > 4:tool:SerpAPI] Entering Tool run with input: "latest developments in quantum computing 2021"
[tool/end] [1:chain:AgentExecutor > 4:tool:SerpAPI] [5.10s] Exiting Tool run with output: "In 2021, IBM developed a 127-qubit chip called Eagle, followed by the 433-qubit Osprey in 2022. On 4 December 2023, it unveiled the first quantum computer, consisting of more than 1,000 qubits. The computer is based on a chip called Condor, which has 1,121 superconducting qubits."
[chain/start] [1:chain:AgentExecutor > 5:chain:LLMChain] Entering Chain run with input: {
  "input": "量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題点を調査してください。",
  "agent_scratchpad": "I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"\nObservation: In 2021, IBM developed a 127-qubit chip called Eagle, followed by the 433-qubit Osprey in 2022. On 4 December 2023, it unveiled the first quantum computer, consisting of more than 1,000 qubits. The computer is based on a chip called Condor, which has 1,121 superconducting qubits.\nThought:",
  "stop": [
    "\nObservation: "
  ]
}
[llm/start] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:ChatOpenAI] Entering LLM run with input: {      
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain_core",
          "messages",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "Answer the following questions as best you can. You have access to the following tools:\n\nsearch: a search engine. useful for when you need to answer questions about current events. input should be a search query.\ncalculator: Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.\n\nUse the following format in your response:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [\"search\", \"calculator\"]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題 点を調査してください。\nThought:I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"\nObservation: In 2021, IBM developed a 127-qubit chip called Eagle, followed by the 433-qubit Osprey in 2022. On 4 December 2023, it unveiled the first quantum computer, consisting of more than 1,000 qubits. The computer is based on a chip called Condor, which has 1,121 superconducting qubits.\nThought:",
          "additional_kwargs": {},
          "response_metadata": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:ChatOpenAI] [1.03s] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\"",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\"",
            "additional_kwargs": {},
            "response_metadata": {
              "tokenUsage": {
                "promptTokens": 365,
                "completionTokens": 29,
                "totalTokens": 394
              },
              "finish_reason": "stop",
              "model_name": "gpt-3.5-turbo-0125"
            },
            "id": "chatcmpl-AyJPjWrqBGF8hiKs6Ju1iNjHHb5tX",
            "tool_calls": [],
            "invalid_tool_calls": [],
            "usage_metadata": {
              "output_tokens": 29,
              "input_tokens": 365,
              "total_tokens": 394,
              "input_token_details": {
                "audio": 0,
                "cache_read": 0
              },
              "output_token_details": {
                "audio": 0,
                "reasoning": 0
              }
            }
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "promptTokens": 365,
      "completionTokens": 29,
      "totalTokens": 394
    }
  }
}
[chain/end] [1:chain:AgentExecutor > 5:chain:LLMChain] [1.03s] Exiting Chain run with output: {
  "text": "I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\""
}
[agent/action] [1:chain:AgentExecutor] Agent selected action: {
  "tool": "search",
  "toolInput": "major companies in quantum computing",
  "log": "I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\""
}
[tool/start] [1:chain:AgentExecutor > 7:tool:SerpAPI] Entering Tool run with input: "major companies in quantum computing"
[tool/end] [1:chain:AgentExecutor > 7:tool:SerpAPI] [840ms] Exiting Tool run with output: "["Leaders In Quantum Computing · 1. IBM · 2. Google Quantum AI · 3. Amazon · 4. Microsoft · 5. Intel · 6. D-Wave · 7. Quantinuum · 8. Rigetti."]"
[chain/start] [1:chain:AgentExecutor > 8:chain:LLMChain] Entering Chain run with input: {
  "input": "量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題点を調査してください。",
  "agent_scratchpad": "I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"\nObservation: In 2021, IBM developed a 127-qubit chip called Eagle, followed by the 433-qubit Osprey in 2022. On 4 December 2023, it unveiled the first quantum computer, consisting of more than 1,000 qubits. The computer is based on a chip called Condor, which has 1,121 superconducting qubits.\nThought:I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\"\nObservation: [\"Leaders In Quantum Computing · 1. IBM · 2. Google Quantum AI · 3. Amazon · 4. Microsoft · 5. Intel · 6. D-Wave · 7. Quantinuum · 8. Rigetti.\"]\nThought:",
  "stop": [
    "\nObservation: "
  ]
}
[llm/start] [1:chain:AgentExecutor > 8:chain:LLMChain > 9:llm:ChatOpenAI] Entering LLM run with input: {      
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain_core",
          "messages",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "Answer the following questions as best you can. You have access to the following tools:\n\nsearch: a search engine. useful for when you need to answer questions about current events. input should be a search query.\ncalculator: Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.\n\nUse the following format in your response:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [\"search\", \"calculator\"]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題 点を調査してください。\nThought:I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"\nObservation: In 2021, IBM developed a 127-qubit chip called Eagle, followed by the 433-qubit Osprey in 2022. On 4 December 2023, it unveiled the first quantum computer, consisting of more than 1,000 qubits. The computer is based on a chip called Condor, which has 1,121 superconducting qubits.\nThought:I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\"\nObservation: [\"Leaders In Quantum Computing · 1. IBM · 2. Google Quantum AI · 3. Amazon · 4. Microsoft · 5. Intel · 6. D-Wave · 7. Quantinuum · 8. Rigetti.\"]\nThought:",
          "additional_kwargs": {},
          "response_metadata": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:AgentExecutor > 8:chain:LLMChain > 9:llm:ChatOpenAI] [602ms] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I should look into the current challenges in quantum computing.\nAction: search\nAction Input: \"challenges in quantum computing 2023\"",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I should look into the current challenges in quantum computing.\nAction: search\nAction Input: \"challenges in quantum computing 2023\"",
            "additional_kwargs": {},
            "response_metadata": {
              "tokenUsage": {
                "promptTokens": 451,
                "completionTokens": 28,
                "totalTokens": 479
              },
              "finish_reason": "stop",
              "model_name": "gpt-3.5-turbo-0125"
            },
            "id": "chatcmpl-AyJPle6BNP7AqMAsKxMJ7PTe0Zag4",
            "tool_calls": [],
            "invalid_tool_calls": [],
            "usage_metadata": {
              "output_tokens": 28,
              "input_tokens": 451,
              "total_tokens": 479,
              "input_token_details": {
                "audio": 0,
                "cache_read": 0
              },
              "output_token_details": {
                "audio": 0,
                "reasoning": 0
              }
            }
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "promptTokens": 451,
      "completionTokens": 28,
      "totalTokens": 479
    }
  }
}
[chain/end] [1:chain:AgentExecutor > 8:chain:LLMChain] [605ms] Exiting Chain run with output: {
  "text": "I should look into the current challenges in quantum computing.\nAction: search\nAction Input: \"challenges in quantum computing 2023\""
}
[agent/action] [1:chain:AgentExecutor] Agent selected action: {
  "tool": "search",
  "toolInput": "challenges in quantum computing 2023",
  "log": "I should look into the current challenges in quantum computing.\nAction: search\nAction Input: \"challenges in quantum computing 2023\""
}
[tool/start] [1:chain:AgentExecutor > 10:tool:SerpAPI] Entering Tool run with input: "challenges in quantum computing 2023"
[tool/end] [1:chain:AgentExecutor > 10:tool:SerpAPI] [1.47s] Exiting Tool run with output: "8 Remaining Quantum Computing Challenges"
[chain/start] [1:chain:AgentExecutor > 11:chain:LLMChain] Entering Chain run with input: {
  "input": "量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題点を調査してください。",
  "agent_scratchpad": "I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"\nObservation: In 2021, IBM developed a 127-qubit chip called Eagle, followed by the 433-qubit Osprey in 2022. On 4 December 2023, it unveiled the first quantum computer, consisting of more than 1,000 qubits. The computer is based on a chip called Condor, which has 1,121 superconducting qubits.\nThought:I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\"\nObservation: [\"Leaders In Quantum Computing · 1. IBM · 2. Google Quantum AI · 3. Amazon · 4. Microsoft · 5. Intel · 6. D-Wave · 7. Quantinuum · 8. Rigetti.\"]\nThought:I should look into the current challenges in quantum computing.\nAction: search\nAction Input: \"challenges in quantum computing 2023\"\nObservation: 8 Remaining Quantum Computing Challenges\nThought:",
  "stop": [
    "\nObservation: "
  ]
}
[llm/start] [1:chain:AgentExecutor > 11:chain:LLMChain > 12:llm:ChatOpenAI] Entering LLM run with input: {    
  "messages": [
    [
      {
        "lc": 1,
        "type": "constructor",
        "id": [
          "langchain_core",
          "messages",
          "HumanMessage"
        ],
        "kwargs": {
          "content": "Answer the following questions as best you can. You have access to the following tools:\n\nsearch: a search engine. useful for when you need to answer questions about current events. input should be a search query.\ncalculator: Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.\n\nUse the following format in your response:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [\"search\", \"calculator\"]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: 量子コンピュータの最新動向についてについて、最新の進展、主要な企業の取り組み、課題 点を調査してください。\nThought:I need to search for the latest developments in quantum computing, major companies involved, and current challenges.\nAction: search\nAction Input: \"latest developments in quantum computing 2021\"\nObservation: In 2021, IBM developed a 127-qubit chip called Eagle, followed by the 433-qubit Osprey in 2022. On 4 December 2023, it unveiled the first quantum computer, consisting of more than 1,000 qubits. The computer is based on a chip called Condor, which has 1,121 superconducting qubits.\nThought:I need to find out more about the major companies involved in quantum computing.\nAction: search\nAction Input: \"major companies in quantum computing\"\nObservation: [\"Leaders In Quantum Computing · 1. IBM · 2. Google Quantum AI · 3. Amazon · 4. Microsoft · 5. Intel · 6. D-Wave · 7. Quantinuum · 8. Rigetti.\"]\nThought:I should look into the current challenges in quantum computing.\nAction: search\nAction Input: \"challenges in quantum computing 2023\"\nObservation: 8 Remaining Quantum Computing Challenges\nThought:",
          "additional_kwargs": {},
          "response_metadata": {}
        }
      }
    ]
  ]
}
[llm/end] [1:chain:AgentExecutor > 11:chain:LLMChain > 12:llm:ChatOpenAI] [841ms] Exiting LLM run with output: {
  "generations": [
    [
      {
        "text": "I now know the final answer\nFinal Answer: The latest developments in quantum computing include IBM's 1,121-qubit computer, major companies involved are IBM, Google Quantum AI, Amazon, Microsoft, Intel, D-Wave, Quantinuum, and Rigetti, and current challenges include 8 remaining challenges in 2023.",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain_core",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "I now know the final answer\nFinal Answer: The latest developments in quantum computing include IBM's 1,121-qubit computer, major companies involved are IBM, Google Quantum AI, Amazon, Microsoft, Intel, D-Wave, Quantinuum, and Rigetti, and current challenges include 8 remaining challenges in 2023.",      
            "additional_kwargs": {},
            "response_metadata": {
              "tokenUsage": {
                "promptTokens": 490,
                "completionTokens": 68,
                "totalTokens": 558
              },
              "finish_reason": "stop",
              "model_name": "gpt-3.5-turbo-0125"
            },
            "id": "chatcmpl-AyJPnkjs8QkoU53COCz9ZykDbuwqs",
            "tool_calls": [],
            "invalid_tool_calls": [],
            "usage_metadata": {
              "output_tokens": 68,
              "input_tokens": 490,
              "total_tokens": 558,
              "input_token_details": {
                "audio": 0,
                "cache_read": 0
              },
              "output_token_details": {
                "audio": 0,
                "reasoning": 0
              }
            }
          }
        },
        "generationInfo": {
          "finish_reason": "stop"
        }
      }
    ]
  ],
  "llmOutput": {
    "tokenUsage": {
      "promptTokens": 490,
      "completionTokens": 68,
      "totalTokens": 558
    }
  }
}
[chain/end] [1:chain:AgentExecutor > 11:chain:LLMChain] [843ms] Exiting Chain run with output: {
  "text": "I now know the final answer\nFinal Answer: The latest developments in quantum computing include IBM's 1,121-qubit computer, major companies involved are IBM, Google Quantum AI, Amazon, Microsoft, Intel, D-Wave, Quantinuum, and Rigetti, and current challenges include 8 remaining challenges in 2023."
}
[chain/end] [1:chain:AgentExecutor] [11.31s] Exiting Chain run with output: {
  "output": "The latest developments in quantum computing include IBM's 1,121-qubit computer, major companies involved are IBM, Google Quantum AI, Amazon, Microsoft, Intel, D-Wave, Quantinuum, and Rigetti, and current challenges include 8 remaining challenges in 2023."
}

=== 執筆フェーズ ===

=== 最終記事 ===
タイトル: Quantum Computing: The Latest Developments and Challenges

概要: IBM's 1,121-qubit computer is a game-changer in quantum computing. Major players include IBM, Google Quantum AI, Amazon, Microsoft, Intel, D-Wave, Quantinuum, and Rigetti.

本文:
1. Quantum computing is advancing rapidly with IBM's 1,121-qubit computer leading the way, pushing the boundaries of what is possible in computing power.
2. Major companies such as IBM, Google Quantum AI, Amazon, Microsoft, Intel, D-Wave, Quantinuum, and Rigetti are heavily invested in quantum computing research and development.
3. Despite the progress, there are still 8 significant challenges remaining in 2023, such as error correction, qubit connectivity, and scaling up quantum systems.

まとめ: The field of quantum computing is rapidly evolving, with major companies making significant advancements. However, there are still challenges to overcome in order to fully harness the potential of this revolutionary technology.

:::

</details>

# 3.試したいことのさわり（要求分析と機能設計）
（１）Windsurfで下記を要求

:::note
LangChain v0.3,nodejs,JavaScriptを使用して、マルチエージェントプログラムを作成して下しさい。
・ユーザの要求をもとに、要求分析を行い、要求をブレイクダウンする要求分析エージェント
・要求分析エージェントの分析結果をもとに、必要な機能の詳細を検討し、出力する機能設計エージェント

:::

（２）ほぼ自動生成で下記のプログラムができた

```ruby:Req2Spec.js
import 'dotenv/config';
import { ChatOpenAI } from "@langchain/openai";
import { PromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { RunnableSequence } from "@langchain/core/runnables";

const OPENAI_API_KEY = process.env.OPENAI_API_KEY;

// 要求分析エージェントのプロンプト
const requirementAnalysisPrompt = PromptTemplate.fromTemplate(`
あなたは要求分析の専門家です。以下のユーザー要求を分析し、詳細な要件定義を行ってください。

ユーザー要求: {user_requirement}

以下の形式で出力してください：

1. 要求の概要
   - 主要目的
   - 期待される成果

2. 機能要件
   - 主要機能（優先度順）
   - 各機能の詳細仕様
   - 入力/出力の定義

3. 非機能要件
   - パフォーマンス要件
   - セキュリティ要件
   - 品質要件

4. 制約条件と依存関係
   - 技術的制約
   - 外部システムとの連携
   - 前提条件
`);

// 機能設計エージェントのプロンプト
const functionalDesignPrompt = PromptTemplate.fromTemplate(`
あなたは機能設計の専門家です。要求分析の結果をもとに、詳細な機能設計を行ってください。

要求分析結果: {requirement_analysis}

以下の形式で各機能の詳細設計を出力してください：

1. 機能アーキテクチャ
   - システム構成
   - コンポーネント間の関係
   - データフロー

2. 各機能の詳細設計
   【機能名】
   - 機能概要
   - 処理フロー
   - 入力パラメータ
   - 出力パラメータ
   - バリデーションルール
   - エラーハンドリング
   - パフォーマンス要件

3. データモデル
   - エンティティ定義
   - リレーションシップ
   - データ制約

4. インターフェース設計
   - API仕様
   - UI/UXガイドライン
   - 外部システム連携仕様

5. セキュリティ設計
   - 認証・認可方式
   - データ保護方針
   - セキュリティ対策
`);

// 要求分析エージェントの作成
async function createRequirementAnalyzer() {
    const model = new ChatOpenAI({
        temperature: 0.2,
        openAIApiKey: OPENAI_API_KEY,
    });

    return RunnableSequence.from([
        requirementAnalysisPrompt,
        model,
        new StringOutputParser(),
    ]);
}

// 機能設計エージェントの作成
async function createFunctionalDesigner() {
    const model = new ChatOpenAI({
        temperature: 0.3,
        openAIApiKey: OPENAI_API_KEY,
    });

    return RunnableSequence.from([
        functionalDesignPrompt,
        model,
        new StringOutputParser(),
    ]);
}

async function main() {
    // エージェントの初期化
    const analyzer = await createRequirementAnalyzer();
    const designer = await createFunctionalDesigner();

    // サンプルの要求
    const userRequirement = `チームのタスク管理システムを作りたいです。
    プロジェクトごとにタスクを管理でき、担当者のアサイン、進捗管理、
    締切管理ができるようにしたいです。また、チームメンバー間でコミュニケーションが
    取れる機能も欲しいです。`;
    
    console.log("=== ユーザー要求 ===");
    console.log(userRequirement);

    // Step 1: 要求分析の実行
    console.log("\n=== 要求分析結果 ===");
    const requirementAnalysis = await analyzer.invoke({
        user_requirement: userRequirement
    });
    console.log(requirementAnalysis);

    // Step 2: 機能設計の実行
    console.log("\n=== 機能設計結果 ===");
    const functionalDesign = await designer.invoke({
        requirement_analysis: requirementAnalysis
    });
    console.log(functionalDesign);
}

main().catch((error) => {
    console.error("エラーが発生しました:", error);
});
```

（３）実行結果は下記の通り
```
=== ユーザー要求 ===
チームのタスク管理システムを作りたいです。
    プロジェクトごとにタスクを管理でき、担当者のアサイン、進捗管理、
    締切管理ができるようにしたいです。また、チームメンバー間でコミュニケーションが
    取れる機能も欲しいです。

=== 要求分析結果 ===
1. 要求の概要
   - 主要目的: チームのタスク管理を効率化し、プロジェクトごとにタスクを管理できるシステムを提供する。
   - 期待される成果: タスクの効率的な管理、担当者のアサインや進捗管理、締切管理、チームメンバー間でのコミュニ ケーションの円滑化。

2. 機能要件
   - 主要機能（優先度順）:
     1. タスクの作成・編集・削除
     2. 担当者のアサイン
     3. 進捗管理
     4. 締切管理
     5. チームメンバー間のコミュニケーション機能
   - 各機能の詳細仕様:
     - タスクの作成・編集・削除: ユーザーがタスクの詳細を入力し、編集や削除が可能。
     - 担当者のアサイン: タスクに担当者をアサインする機能。
     - 進捗管理: タスクの進捗状況を更新できる機能。
     - 締切管理: タスクの締切日を設定し、締切に対する通知機能。
     - チームメンバー間のコミュニケーション機能: チャットやコメント機能を通じてチーム内でのコミュニケーション を実現。
   - 入力/出力の定義: 
     - 入力: タスクの詳細情報、担当者、進捗状況、締切日、チームメンバーとのコミュニケーション内容。
     - 出力: タスクリスト、進捗状況、締切通知、チーム内コミュニケーションログ。

3. 非機能要件
   - パフォーマンス要件: タスクの追加や更新がリアルタイムに反映される高速なシステム。
   - セキュリティ要件: ユーザー認証やデータの暗号化などのセキュリティ対策。
   - 品質要件: ユーザビリティの高いインターフェース、バグの少ない安定したシステム。

4. 制約条件と依存関係
   - 技術的制約: 使用するプログラミング言語やフレームワーク、データベースの選定。
   - 外部システムとの連携: メール通知やカレンダーアプリとの連携など。
   - 前提条件: チームメンバーがインターネットに接続できる環境が必要。

=== 機能設計結果 ===
1. 機能アーキテクチャ
   - システム構成: クラウドベースのWebアプリケーションとして構築される。
   - コンポーネント間の関係: フロントエンド（UI）、バックエンド（サーバー）、データベースが相互に連携する。   
   - データフロー: ユーザーがUIを介して情報を入力し、バックエンドで処理され、データベースに保存される。       

2. 各機能の詳細設計
   【タスクの作成・編集・削除】
   - 機能概要: ユーザーが新しいタスクを作成し、編集や削除を行う機能。
   - 処理フロー: ユーザーがタスク情報を入力し、保存ボタンを押すとデータがバックエンドに送信され、データベース に保存される。
   - 入力パラメータ: タスクのタイトル、詳細、締切日などの情報。
   - 出力パラメータ: 保存されたタスクの情報。
   - バリデーションルール: タイトルは必須項目、締切日は未来の日付であることなど。
   - エラーハンドリング: 入力内容にエラーがある場合はエラーメッセージを表示する。
   - パフォーマンス要件: タスクの保存や更新はリアルタイムに反映される。

3. データモデル
   - エンティティ定義: タスク（Task）、ユーザー（User）、チーム（Team）などのエンティティが定義される。       
   - リレーションシップ: タスクとユーザーの関連付け、チームとユーザーの関連付けなどが定義される。
   - データ制約: タスクの締切日はNULLを許容しない、ユーザーのメールアドレスは一意であるなど。

4. インターフェース設計
   - API仕様: RESTful APIを使用し、タスクのCRUD操作やユーザー認証などが提供される。
   - UI/UXガイドライン: ユーザビリティを考慮したシンプルで使いやすいUIが設計される。
   - 外部システム連携仕様: メール通知やカレンダーアプリとの連携が実装される。

5. セキュリティ設計
   - 認証・認可方式: OAuth2.0を使用したユーザー認証やアクセス制御が実装される。
   - データ保護方針: データの暗号化、アクセス制御、データバックアップなどの対策が取られる。
   - セキュリティ対策: SQLインジェクション、クロスサイトスクリプティングなどの脆弱性対策が実施される。    

```

# 4.参考資料
https://python.langchain.com/docs/versions/v0_3/


2025.02.07 山崎作成