【初心者向け】LangChainとPythonで「計算できるAIエージェント」を作る

## はじめに
最近、AIエージェントを搭載したアプリケーションの開発に取り組み始めました。第一歩として、「簡単な計算をしてくれるAIエージェント」を作ってみたので、その内容を振り返りながら記録として残しておこうと思います。

ここで言う「AIエージェント」とは、ユーザーとの会話を理解し、必要に応じてツール（関数など）を使って処理をしてくれるAIのことです。今回は足し算・引き算・掛け算・割り算といった基本的な計算を、自然な会話を通じてこなしてくれるAIを目指します。

## 目指すところ

- AIエージェントに「3と5を足して」などと話しかけると、計算して答えてくれる
- 足し算・引き算・掛け算・割り算に対応
- 自分で定義した関数（Pythonの関数）をAIが自律的に選んで実行する

## 動作環境

- Python 3.12
- Ubuntu 20.04LTS

    ※私の実行時の環境になります。

## 手順

### 1. 必要なライブラリのインストール

```
pip install langchain langchain-openai pydantic
```

<details>
<summary>細かいバージョンを参照したい場合はこちら</summary>


```
altair==5.5.0
annotated-types==0.7.0
anyio==4.9.0
attrs==25.3.0
blinker==1.9.0
cachetools==5.5.2
certifi==2025.4.26
chardet==5.2.0
charset-normalizer==3.4.2
click==8.2.1
distro==1.9.0
gitdb==4.0.12
GitPython==3.1.44
greenlet==3.2.2
h11==0.16.0
httpcore==1.0.9
httpx==0.28.1
idna==3.10
Jinja2==3.1.6
jiter==0.10.0
jsonpatch==1.33
jsonpointer==3.0.0
jsonschema==4.24.0
jsonschema-specifications==2025.4.1
langchain==0.3.25
langchain-core==0.3.63
langchain-openai==0.3.18
langchain-text-splitters==0.3.8
langsmith==0.3.43
MarkupSafe==3.0.2
narwhals==1.41.0
numpy==2.2.6
openai==1.82.1
orjson==3.10.18
packaging==24.2
pandas==2.2.3
pillow==11.2.1
protobuf==6.31.1
pyarrow==20.0.0
pydantic==2.11.5
pydantic_core==2.33.2
pydeck==0.9.1
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.2
referencing==0.36.2
regex==2024.11.6
reportlab==4.4.1
requests==2.32.3
requests-toolbelt==1.0.0
rpds-py==0.25.1
six==1.17.0
smmap==5.0.2
sniffio==1.3.1
SQLAlchemy==2.0.41
streamlit==1.45.1
svgwrite==1.4.3
tenacity==9.1.2
tiktoken==0.9.0
toml==0.10.2
tornado==6.5.1
tqdm==4.67.1
typing-inspection==0.4.1
typing_extensions==4.13.2
tzdata==2025.2
urllib3==2.4.0
watchdog==6.0.0
zstandard==0.23.0
```
</details>

### 2. 環境変数の設定

OpenAIのAPIキーは環境変数```OPENAI_API_KEY```に設定しておきましょう。


### 3. ソースコード記述

```calc_ai_agent.py
from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent
from langchain.tools import StructuredTool
from langchain.memory import ConversationBufferMemory
from pydantic import BaseModel, Field
from typing import Callable

# --- 計算用の関数をまとめたクラス ---
class Calculator:
    @staticmethod
    def add(a: int, b: int) -> int:
        """aとbを足し算して返す"""
        return a + b
    @staticmethod
    def subtract(a: int, b: int) -> int:
        """aからbを引き算して返す"""
        return a - b
    @staticmethod
    def multiply(a: int, b: int) -> int:
        """aとbを掛け算して返す"""
        return a * b
    @staticmethod
    def divide(a: int, b: int) -> float:
        """aをbで割り算して返す"""
        return a / b

# --- ツール用の引数（a, b）を定義 ---
class CalcNumbersInput(BaseModel):
    a: int = Field(..., description="1つ目の整数")
    b: int = Field(..., description="2つ目の整数")

# --- ツール（AIが使う計算機能）を作る関数 ---
def make_tool(name: str, func: Callable[[int, int], float | int], description: str):
    def tool_func(a: int, b: int) -> str:
        return str(func(a, b))
    return StructuredTool(
        name=name,
        func=tool_func,
        description=description,
        args_schema=CalcNumbersInput
    )

# --- 各計算ごとにツールを作成 ---
add_tool = make_tool(
    name="add_numbers",
    func=Calculator.add,
    description="2つの整数a, bを足し算して返すツール。引数: a(int), b(int)"
)
subtract_tool = make_tool(
    name="subtract_numbers",
    func=Calculator.subtract,
    description="2つの整数a, bを引き算して返すツール。引数: a(int), b(int)"
)
multiply_tool = make_tool(
    name="multiply_numbers",
    func=Calculator.multiply,
    description="2つの整数a, bを掛け算して返すツール。引数: a(int), b(int)"
)
divide_tool = make_tool(
    name="divide_numbers",
    func=Calculator.divide,
    description="2つの整数a, bを割り算して返すツール。引数: a(int), b(int)"
)

# --- LangChainのAIエージェントを作成 ---
llm = ChatOpenAI(temperature=0)
tools = [add_tool, subtract_tool, multiply_tool, divide_tool]
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

agent = initialize_agent(
    tools,
    llm,
    agent="openai-functions",
    verbose=True,
    memory=memory,
)

# --- 対話形式でAIに計算を質問できる ---
if __name__ == "__main__":
    print("AIエージェントに計算を質問してください。例: 3と5を足して。終了はexit。")
    while True:
        user_input = input("あなた: ")
        if user_input.strip().lower() == "exit":
            break
        response = agent.run(user_input)
        print("AI: ", response)

```

### 4. 実行

```
python calc_ai_agent.py
```

```
AIエージェントに計算を質問してください。例: 3と5を足して。終了はexit。
あなた: 3と5を足して。
AI:  3と5を足すと、合計は8になります。
あなた: 10から7を引いて
AI:  10から7を引くと、答えは3です。
あなた: 6と4をかけて
AI:  6と4をかけると、24になります。
あなた: 20を4で割って
AI:  20を4で割ると、答えは5です。
あなた: 20+6*7-35
AI:  The result of the expression 20 + 6 * 7 - 35 is 27.
```

うまく、自身で定義した関数を利用して計算を実行してくれているようです。

## おわりに
LangChainとOpenAIのAPIを使えば、AIエージェントは簡単に作れますね。
これからもっと流行っていくと思うので、取り残されないようにしていきたいです。

## 参考

LangChainドキュメント

https://python.langchain.com/docs/introduction/

OpenAIドキュメント

https://platform.openai.com/docs/overview