Re:ゼロから始めるML生活

どちらかといえばエミリア派です

LangGraphでAIエージェントづくりをひとめぐり

2025年はどうやらAIエージェントの年らしいので、AIエージェントの作り方について絶賛勉強中だったりします。 そんなこんなもあって、最近こちらの書籍を購入してみまして、AIエージェントについて絶賛勉強中です。

本を読むだけでは身につかない部分もあると思うので、色々ガチャガチャ作りながら勉強してみようと思います。

LangGraph

www.langchain.com

 LangGraphは、複数のエージェント(または役割を持つLLMインスタンス)が連携してタスクを処理するワークフローを作成することができるライブラリです。LLMを活用して、複数のエージェント間で情報をやり取りしながらタスクを進める複雑なワークフローを簡単に構築できます。 現場で活用するためのAIエージェント実践入門 (KS情報科学専門書) | 太田 真人, 宮脇 峻平, 西見 公宏, 後藤 勇輝, 阿田木 勇八 |本 | 通販 | Amazon

エージェントを作るだけならLangChainだけでもできたりはするんですが、エージェントを作りやすいような機能群が揃ったライブラリって感じですね。今回はこちらを利用してエージェントの作り方をなぞっていこうと思います。

Document

ちゃんと触るのは初めてなので、Documentを見ながらやってみたいと思います。

langchain-ai.github.io

便利機能

Overviewによると、LangGraphにはエージェントを作るために有用な機能がいくつか備わっているそうです。

  • Memory integration(記憶の統合)
  • Human-in-the-loop control(ヒューマン・イン・ザ・ループ制御)
  • Streaming support(ストリーミング対応)
  • Deployment tooling(デプロイ支援ツール)
  • Studio(ビジュアル IDE)
  • マルチデプロイ対応

LangGraphでエージェントを作る

LangGraphの基本コンポーネントとして、

  • Graph
  • State
  • Node
  • Edge

があり、これらを組み合わせることでエージェントの動作を定義することができるようになるようです。

zenn.dev

難しいことは考えず、作りながら慣れていこうと思います。 今回はGemini APIを使ってやってみようと思います。

langchain-ai.github.io

最初にStateを定義します。

from typing import Annotated

from typing_extensions import TypedDict

from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages


class State(TypedDict):
    # Messages have the type "list". The `add_messages` function
    # in the annotation defines how this state key should be updated
    # (in this case, it appends messages to the list, rather than overwriting them)
    messages: Annotated[list, add_messages]


graph_builder = StateGraph(State)

Stateはエージェントの動作中にノード間の遷移の際に保持される情報で、各ノードが参照および更新します。

ここではmessagesというStateを保持しています。

次にNodeを定義しています。 NodeはGraph上での実際の処理をおこなうコンポーネントで、LangChainでやり取りを記録するNodeを追加しています。

def chatbot(state: State):
    return {"messages": [llm.invoke(state["messages"])]}


# The first argument is the unique node name
# The second argument is the function or object that will be called whenever
# the node is used.
graph_builder.add_node("chatbot", chatbot)

複数のNodeをEdgeで繋いでエージェントの処理フローを定義します。

graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)

これをコンパイルすると動かせるようになります。

graph = graph_builder.compile()

可視化するとこんな感じになります。

こんなふうにしてエージェントの動作をコントロールしていくらしいです。

その他、処理の分岐を行うときはconditional_edgesでやることができるらしいです。

import random

def routing(
    state: State,
):
  random_num = random.randint(0, 1)
  if random_num == 0:
    return "chatbot"
  else:
    return END


# The `tools_condition` function returns "tools" if the chatbot asks to use a tool, and "END" if
# it is fine directly responding. This conditional routing defines the main agent loop.
graph_builder.add_conditional_edges(
    "chatbot",
    routing,
)

感想

大体雰囲気はわかったのでこの辺にしようと思います。 今度やるときはLangGraphを使ったもうちょっといい感じのエージェントを作ってみようと思います。