LangGraph:書類要約ワークフローの構築
最近は、以下の点からLLMの進化が遅くなってきているように感じます。
GPT-4oがClaude 3.5 SonnetやGeminiにChatbot Arenaで負け始めている
GPT-4oをはじめとしたClosedモデルに、Llama 3.1のようなOpenモデルのベンチマークスコアが追いついてきている
一方で、Sakana AIさんのThe AI ScientistのようなLLM-Based Agentにはまだまだ伸び代があると感じます。
LLM-Based Agentの実装用フレームワークとしてLangGraphがありますが、抽象度が低いフレームワークであるためか公式のチュートリアルだけだといまいち使い方がわかりませんでした。
練習としてオリジナルのワークフローを作ってみたので共有させていただきます。
環境はGoogle Colabです。
1. 作るもの
オリジナルの状態定義・ツールの利用・エージェントやエッジの動きの確認をしたいだけなので単純なワークフローを作ります。
上記が簡単な概要図です。
① ワークフローにファイルのパスのリストをいくつか渡す
② 全てのファイルをAgentが要約する(ループ)
という流れです。
Agentの中でループさせても良かったのですが、条件付きエッジ(Conditional Edge)を使ったループの実装を試してみたかったので上記の構成になりました。
ToolNodeが次のファイルを選定
→ Agentが要約
→ Conditional Edgeがファイルが残っているのかを判別
という流れでループを作っています。
2. 準備
使用するライブラリをインストールします。
!pip install langgraph langchain_openai langchain_core
次に、importやmodelの準備をしておきます。
Google Colabはシークレットキー機能を使ってAPIキーを渡しています。
import os
import glob
from typing import TypedDict, Annotated, List, Literal
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
# 環境変数・モデルの準備
from google.colab import userdata
os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")
model = ChatOpenAI(model="gpt-4o-mini")
3. 状態の定義
Agentやツールがアクセス・編集する情報は以下の4つです。
処理すべきファイルパスのリスト
現在処理中(次に処理する)ファイルのパス
各ファイルの要約結果
メッセージ履歴
これをState(状態)としてワークフローに保持させることで、Agent達が共通の情報を参照・処理していくことが可能になります。
# 状態の定義
class SummarizationState(TypedDict):
files: Annotated[List[str], "処理すべきファイルのリスト"]
current_file: Annotated[str, "現在処理中のファイル"]
summaries: Annotated[dict[str, str], "各ファイルの要約"]
messages: Annotated[List[HumanMessage | AIMessage], "メッセージ履歴"]
4. ツールやエージェントの定義
今回のワークフローにおいて、エージェントに「何をどう使うか」みたいなところを考えさせたりはしていません。決められた処理(要約)をやらせるのみです。
ツール(ツールノード)として、①ファイル読み込み、②ファイル選択ツールを用意します。
# ファイル読み込みツール(Agentから使用される)
def read_file(file_path: str) -> str:
try:
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()
except IOError as e:
print(f"ファイルの読み込みエラー: {e}")
return f"ファイル '{file_path}' の読み込みに失敗しました。"
# ファイル選択ツール(Tool Node)
def select_next_file(state: SummarizationState) -> SummarizationState:
if state['files']:
state['current_file'] = state['files'].pop(0)
else:
state['current_file'] = None
return state
エージェントは要約エージェントだけです。
Stateに入っている「次処理するファイルのパス」を使ってファイルを読み込み要約し、結果をStateに入れるという処理をします。
# 要約エージェント
def summarize_agent(state: SummarizationState) -> SummarizationState:
if state['current_file']:
file_content = read_file(state['current_file'])
human_message = HumanMessage(content=f"以下の内容を要約してください:\n\n{file_content}")
ai_message = model.invoke([human_message])
state['summaries'][state['current_file']] = ai_message.content
state['messages'].extend([human_message, ai_message])
return state
条件付きエッジでは、「処理すべきファイルリストが残っているか」を確認します。残っていればループを続け、残っていなければループを抜けてENDとします。
# 続行するかどうかを決定する関数
def should_continue(state: SummarizationState) -> Literal["select_file", END]:
if state['files']:
return "select_file"
return END
5. ワークフローの構築
これまで作ってきた要素をワークフローに追加していきます。
グラフの構築。ここでグラフにStateの形式を渡します。
ツールノード(LLMを使わない処理ノードをツールノードと呼ぶ?)、エージェントをadd_nodeを使ってノードとして追加。
エッジ、条件付きエッジを追加することでノードとノードの流れを定義します。
一番最初に呼ばれるノードをset_entry_pointで設定します。
最後にワークフローをcompileすることで実行可能なものにします。
# グラフの構築
workflow = StateGraph(SummarizationState)
# ノードの追加
workflow.add_node("select_file", select_next_file)
workflow.add_node("summarize", summarize_agent)
# エッジの追加
workflow.add_edge("select_file", "summarize")
# 条件付きエッジの追加
workflow.add_conditional_edges(
# 開始ノードを定義
"summarize",
# 次に呼び出されるノードを決定する関数を渡す
should_continue,
)
# エントリーポイントの設定
workflow.set_entry_point("select_file")
# グラフのコンパイル
app = workflow.compile()
ちなみにLangGraphのコンパイルしたworkflowは以下のコードでフロー全体を描画できる。
from IPython.display import Image, display
display(Image(app.get_graph().draw_mermaid_png()))
これによって以下が出力される。
6. ワークフローの実行
ワークフローに最初に渡す初期状態を設定します。
今回は、処理すべきファイルのパスのリストをワークフロー渡します。カレントディレクトリの下にdocumentsというディレクトリを作り、そこに2ファイル格納しました。
# documentsフォルダ内の全ファイルを取得
documents_path = os.path.join(os.getcwd(), 'documents')
all_files = glob.glob(os.path.join(documents_path, '**', '*.*'), recursive=True)
print(all_files)
# 初期状態の設定
initial_state = SummarizationState(
files=all_files,
current_file="",
summaries={},
messages=[]
)
streamでワークフローを実行することで途中の処理を出力できます。(結果だけ取得する場合はinvokeを使います。)
また、ここで先ほどのinitial_stateを渡すことで、ファイルリストをワークフローに渡すことができます。
# ワークフローの実行
for s in app.stream(
initial_state,
config={"recursion_limit": 150}
):
print(s)
print("----")
以下のような結果が得られました。
{'select_file': {'files': ['/content/documents/システム機能階層図.md'], 'current_file': '/content/documents/受注業務(標準)の業務フロー.md', 'summaries': {}, 'messages': []}}
----
{'summarize': {'files': ['/content/documents/システム機能階層図.md'], 'current_file': '/content/documents/受注業務(標準)の業務フロー.md', 'summaries': {'/content/documents/受注業務(標準)の業務フロー.md': '受注業務(標準)の業務フローは、顧客からの引き合い(見積依頼)から始まり、販売担当者、販売承認者、倉庫部を経て出荷に至る一連の流れを示しています。具体的には、顧客が見積依頼を行い、販売担当者が申し込み書類を送付後、見積書の確認や契約書の作成を行います。次に、販売承認者が注文書や契約書を確認し、受注内容を登録して出荷予定を決定します。その後、倉庫部で出荷が行われ、出荷依頼メールが送信されます。この業務フローは、各部門が異なるレーンで表現されており、システム間のデータのやり取りも存在しますが、図には明示的には示されていません。新規顧客に関するフローは別紙に記載されています。'}, 'messages': [HumanMessage(content='以下の内容を要約してください:\n\n# 受注業務(標準)の業務フロー\n\n## 3 - 1\n\n- 工事建物DBプロジェクトなどで使用したLFD(Lane Flow Diagram)を用いて業務フローを記述した例を示す。\n- 受注業務を次の3ケースのフローで表現する。\n - フローNo.1 受注業務(標準)\n - フローNo.2 受注業務(新規)\n - フローNo.3 受注業務(OEM製品)\n\n## 受注業務(標準)の業務フロー\n\n```mermaid\ngraph TD\n subgraph 顧客\n A[引き合い(見積依頼)]\n B[注文請書受領]\n end\n\n subgraph 販売担当者\n C[受付け・申込書類送付]\n D[見積書確認・注文書作成・契約書作成]\n end\n\n subgraph 販売承認者\n E[注文書、契約書確認・注文請書作成、送付・受注内容登録・出荷予定登録]\n end\n\n subgraph 倉庫部\n F[出荷]\n end\n\n subgraph システム\n G[バッチ誘導]\n H[バッチ誘導]\n I[出荷依頼メール送信]\n end\n\n subgraph 関連システム\n J[営業システム]\n K[見積システム]\n end\n\n A -->|※電話。インターネットも検討| C\n C --> D\n D --> E\n E --> B\n E --> F\n E --> I\n G --> J\n H --> K\n I -->|Mail| F\n\n style A fill:#f9f,stroke:#333,stroke-width:2px\n style B fill:#f9f,stroke:#333,stroke-width:2px\n style C fill:#bbf,stroke:#333,stroke-width:2px\n style D fill:#bbf,stroke:#333,stroke-width:2px\n style E fill:#bfb,stroke:#333,stroke-width:2px\n style F fill:#fbb,stroke:#333,stroke-width:2px\n style G fill:#ff9,stroke:#333,stroke-width:2px\n style H fill:#ff9,stroke:#333,stroke-width:2px\n style I fill:#ff9,stroke:#333,stroke-width:2px\n style J fill:#f99,stroke:#333,stroke-width:2px\n style K fill:#f99,stroke:#333,stroke-width:2px\n```\n\n### 補足説明\n- 図中の矢印は業務の流れを示しています。\n- 各部門(顧客、販売担当者、販売承認者、倉庫部、システム、関連システム)は別々のレーンで表現されています。\n- 新規顧客の場合のフロー(信用調査)は別紙で記載されているため、このフロー図には含まれていません。\n- システムと関連システムの間のデータのやり取り(受注データ、出荷データ、顧客管理データ、見積単価データ、得意先マスター)は図中に明示的に示されていませんが、存在します。\n\n## メタデータ\n\n- ID: 3-2s-00702\n- 作成日付: [記載なし]\n- 更新日付: [記載なし]\n- 作成者: [記載なし]\n- 承認者: [記載なし]\n- ソース: SoftwareEngineeringCenter SEC\n'), AIMessage(content='受注業務(標準)の業務フローは、顧客からの引き合い(見積依頼)から始まり、販売担当者、販売承認者、倉庫部を経て出荷に至る一連の流れを示しています。具体的には、顧客が見積依頼を行い、販売担当者が申し込み書類を送付後、見積書の確認や契約書の作成を行います。次に、販売承認者が注文書や契約書を確認し、受注内容を登録して出荷予定を決定します。その後、倉庫部で出荷が行われ、出荷依頼メールが送信されます。この業務フローは、各部門が異なるレーンで表現されており、システム間のデータのやり取りも存在しますが、図には明示的には示されていません。新規顧客に関するフローは別紙に記載されています。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 232, 'prompt_tokens': 873, 'total_tokens': 1105}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-fde400dc-d558-4d93-84af-3f1236e2a3e9-0', usage_metadata={'input_tokens': 873, 'output_tokens': 232, 'total_tokens': 1105})]}}
----
{'select_file': {'files': [], 'current_file': '/content/documents/システム機能階層図.md', 'summaries': {'/content/documents/受注業務(標準)の業務フロー.md': '受注業務(標準)の業務フローは、顧客からの引き合い(見積依頼)から始まり、販売担当者、販売承認者、倉庫部を経て出荷に至る一連の流れを示しています。具体的には、顧客が見積依頼を行い、販売担当者が申し込み書類を送付後、見積書の確認や契約書の作成を行います。次に、販売承認者が注文書や契約書を確認し、受注内容を登録して出荷予定を決定します。その後、倉庫部で出荷が行われ、出荷依頼メールが送信されます。この業務フローは、各部門が異なるレーンで表現されており、システム間のデータのやり取りも存在しますが、図には明示的には示されていません。新規顧客に関するフローは別紙に記載されています。'}, 'messages': [HumanMessage(content='以下の内容を要約してください:\n\n# 受注業務(標準)の業務フロー\n\n## 3 - 1\n\n- 工事建物DBプロジェクトなどで使用したLFD(Lane Flow Diagram)を用いて業務フローを記述した例を示す。\n- 受注業務を次の3ケースのフローで表現する。\n - フローNo.1 受注業務(標準)\n - フローNo.2 受注業務(新規)\n - フローNo.3 受注業務(OEM製品)\n\n## 受注業務(標準)の業務フロー\n\n```mermaid\ngraph TD\n subgraph 顧客\n A[引き合い(見積依頼)]\n B[注文請書受領]\n end\n\n subgraph 販売担当者\n C[受付け・申込書類送付]\n D[見積書確認・注文書作成・契約書作成]\n end\n\n subgraph 販売承認者\n E[注文書、契約書確認・注文請書作成、送付・受注内容登録・出荷予定登録]\n end\n\n subgraph 倉庫部\n F[出荷]\n end\n\n subgraph システム\n G[バッチ誘導]\n H[バッチ誘導]\n I[出荷依頼メール送信]\n end\n\n subgraph 関連システム\n J[営業システム]\n K[見積システム]\n end\n\n A -->|※電話。インターネットも検討| C\n C --> D\n D --> E\n E --> B\n E --> F\n E --> I\n G --> J\n H --> K\n I -->|Mail| F\n\n style A fill:#f9f,stroke:#333,stroke-width:2px\n style B fill:#f9f,stroke:#333,stroke-width:2px\n style C fill:#bbf,stroke:#333,stroke-width:2px\n style D fill:#bbf,stroke:#333,stroke-width:2px\n style E fill:#bfb,stroke:#333,stroke-width:2px\n style F fill:#fbb,stroke:#333,stroke-width:2px\n style G fill:#ff9,stroke:#333,stroke-width:2px\n style H fill:#ff9,stroke:#333,stroke-width:2px\n style I fill:#ff9,stroke:#333,stroke-width:2px\n style J fill:#f99,stroke:#333,stroke-width:2px\n style K fill:#f99,stroke:#333,stroke-width:2px\n```\n\n### 補足説明\n- 図中の矢印は業務の流れを示しています。\n- 各部門(顧客、販売担当者、販売承認者、倉庫部、システム、関連システム)は別々のレーンで表現されています。\n- 新規顧客の場合のフロー(信用調査)は別紙で記載されているため、このフロー図には含まれていません。\n- システムと関連システムの間のデータのやり取り(受注データ、出荷データ、顧客管理データ、見積単価データ、得意先マスター)は図中に明示的に示されていませんが、存在します。\n\n## メタデータ\n\n- ID: 3-2s-00702\n- 作成日付: [記載なし]\n- 更新日付: [記載なし]\n- 作成者: [記載なし]\n- 承認者: [記載なし]\n- ソース: SoftwareEngineeringCenter SEC\n'), AIMessage(content='受注業務(標準)の業務フローは、顧客からの引き合い(見積依頼)から始まり、販売担当者、販売承認者、倉庫部を経て出荷に至る一連の流れを示しています。具体的には、顧客が見積依頼を行い、販売担当者が申し込み書類を送付後、見積書の確認や契約書の作成を行います。次に、販売承認者が注文書や契約書を確認し、受注内容を登録して出荷予定を決定します。その後、倉庫部で出荷が行われ、出荷依頼メールが送信されます。この業務フローは、各部門が異なるレーンで表現されており、システム間のデータのやり取りも存在しますが、図には明示的には示されていません。新規顧客に関するフローは別紙に記載されています。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 232, 'prompt_tokens': 873, 'total_tokens': 1105}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-fde400dc-d558-4d93-84af-3f1236e2a3e9-0', usage_metadata={'input_tokens': 873, 'output_tokens': 232, 'total_tokens': 1105})]}}
----
{'summarize': {'files': [], 'current_file': '/content/documents/システム機能階層図.md', 'summaries': {'/content/documents/受注業務(標準)の業務フロー.md': '受注業務(標準)の業務フローは、顧客からの引き合い(見積依頼)から始まり、販売担当者、販売承認者、倉庫部を経て出荷に至る一連の流れを示しています。具体的には、顧客が見積依頼を行い、販売担当者が申し込み書類を送付後、見積書の確認や契約書の作成を行います。次に、販売承認者が注文書や契約書を確認し、受注内容を登録して出荷予定を決定します。その後、倉庫部で出荷が行われ、出荷依頼メールが送信されます。この業務フローは、各部門が異なるレーンで表現されており、システム間のデータのやり取りも存在しますが、図には明示的には示されていません。新規顧客に関するフローは別紙に記載されています。', '/content/documents/システム機能階層図.md': 'この図は、販売管理システム、在庫管理システム、売掛管理システムの機能階層を示しています。\n\n### 販売管理システム\n- **販売業務**には新規取引、受注、出荷が含まれる。\n - **新規取引**では信用調査、取引受付、外部調査依頼、調査報告書作成、与信設定が行われる。\n - **受注**では引き合い、見積り、注文受け、出荷指図が行われる。\n - **出荷**では在庫引当、製造指図、納品、受注台帳更新、売上計上が行われる。\n\n### 在庫管理システム\n- **在庫引当**では在庫確認と在庫引当が行われ、製品有高帳の更新も含まれる。\n\n### 売掛管理システム\n- **債権管理**では債権計上データの取り込みと請求書発行が行われ、入金管理では入金の入力と予定変更が行われる。\n\nこの図は、業務機能を実現する情報システムの階層構造を明確化することを目的としています。'}, 'messages': [HumanMessage(content='以下の内容を要約してください:\n\n# 受注業務(標準)の業務フロー\n\n## 3 - 1\n\n- 工事建物DBプロジェクトなどで使用したLFD(Lane Flow Diagram)を用いて業務フローを記述した例を示す。\n- 受注業務を次の3ケースのフローで表現する。\n - フローNo.1 受注業務(標準)\n - フローNo.2 受注業務(新規)\n - フローNo.3 受注業務(OEM製品)\n\n## 受注業務(標準)の業務フロー\n\n```mermaid\ngraph TD\n subgraph 顧客\n A[引き合い(見積依頼)]\n B[注文請書受領]\n end\n\n subgraph 販売担当者\n C[受付け・申込書類送付]\n D[見積書確認・注文書作成・契約書作成]\n end\n\n subgraph 販売承認者\n E[注文書、契約書確認・注文請書作成、送付・受注内容登録・出荷予定登録]\n end\n\n subgraph 倉庫部\n F[出荷]\n end\n\n subgraph システム\n G[バッチ誘導]\n H[バッチ誘導]\n I[出荷依頼メール送信]\n end\n\n subgraph 関連システム\n J[営業システム]\n K[見積システム]\n end\n\n A -->|※電話。インターネットも検討| C\n C --> D\n D --> E\n E --> B\n E --> F\n E --> I\n G --> J\n H --> K\n I -->|Mail| F\n\n style A fill:#f9f,stroke:#333,stroke-width:2px\n style B fill:#f9f,stroke:#333,stroke-width:2px\n style C fill:#bbf,stroke:#333,stroke-width:2px\n style D fill:#bbf,stroke:#333,stroke-width:2px\n style E fill:#bfb,stroke:#333,stroke-width:2px\n style F fill:#fbb,stroke:#333,stroke-width:2px\n style G fill:#ff9,stroke:#333,stroke-width:2px\n style H fill:#ff9,stroke:#333,stroke-width:2px\n style I fill:#ff9,stroke:#333,stroke-width:2px\n style J fill:#f99,stroke:#333,stroke-width:2px\n style K fill:#f99,stroke:#333,stroke-width:2px\n```\n\n### 補足説明\n- 図中の矢印は業務の流れを示しています。\n- 各部門(顧客、販売担当者、販売承認者、倉庫部、システム、関連システム)は別々のレーンで表現されています。\n- 新規顧客の場合のフロー(信用調査)は別紙で記載されているため、このフロー図には含まれていません。\n- システムと関連システムの間のデータのやり取り(受注データ、出荷データ、顧客管理データ、見積単価データ、得意先マスター)は図中に明示的に示されていませんが、存在します。\n\n## メタデータ\n\n- ID: 3-2s-00702\n- 作成日付: [記載なし]\n- 更新日付: [記載なし]\n- 作成者: [記載なし]\n- 承認者: [記載なし]\n- ソース: SoftwareEngineeringCenter SEC\n'), AIMessage(content='受注業務(標準)の業務フローは、顧客からの引き合い(見積依頼)から始まり、販売担当者、販売承認者、倉庫部を経て出荷に至る一連の流れを示しています。具体的には、顧客が見積依頼を行い、販売担当者が申し込み書類を送付後、見積書の確認や契約書の作成を行います。次に、販売承認者が注文書や契約書を確認し、受注内容を登録して出荷予定を決定します。その後、倉庫部で出荷が行われ、出荷依頼メールが送信されます。この業務フローは、各部門が異なるレーンで表現されており、システム間のデータのやり取りも存在しますが、図には明示的には示されていません。新規顧客に関するフローは別紙に記載されています。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 232, 'prompt_tokens': 873, 'total_tokens': 1105}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-fde400dc-d558-4d93-84af-3f1236e2a3e9-0', usage_metadata={'input_tokens': 873, 'output_tokens': 232, 'total_tokens': 1105}), HumanMessage(content='以下の内容を要約してください:\n\n# システム機能階層図\n\n```mermaid\ngraph TD\n subgraph 販売管理システム\n A[販売業務]\n A --> B[新規取引]\n A --> C[受注]\n A --> D[出荷]\n \n B --> B1[信用調査]\n B1 --> B11[新規取引受付]\n B1 --> B12[外部調査依頼]\n B1 --> B13[調査報告書作成]\n B1 --> B14[与信設定]\n \n C --> C1[引き合い]\n C --> C2[見積り]\n C --> C3[注文受け]\n C --> C4[出荷指図]\n \n D --> D1[在庫引当]\n D --> D2[製造指図]\n D --> D3[納品]\n D --> D4[受注台帳更新]\n D --> D5[売上計上]\n \n E[新規取引]\n E --> E1[新規取引申請]\n E --> E2[信用調査結果登録]\n \n F[受注管理]\n F --> F1[受注案件登録]\n F --> F2[受注内容登録]\n \n G[出荷管理]\n G --> G1[出荷予定登録]\n G --> G2[出荷依頼]\n \n E1 --> E11[新規取引申請]\n E1 --> E12[新規取引申請承認]\n \n E2 --> E21[与信限度額登録]\n E2 --> E22[販売条件登録]\n end\n \n subgraph 在庫管理システム\n H[在庫引当]\n H --> H1[在庫確認]\n H --> H2[在庫引当]\n \n I[製品有高帳更新]\n I --> I1[製品有高帳参照]\n I --> I2[製品有高帳更新]\n end\n \n subgraph 売掛管理システム\n J[債権管理]\n J --> J1[債権計上データ取込]\n J --> J2[請求書発行]\n \n K[入金管理]\n K --> K1[入金入力]\n K --> K2[入金予定変更]\n end\n```\n\n## 補足情報\n\n- ID: 3-2s-00800\n- 作成者: SoftwareEngineeringCenter\n- 承認者: SEC\n\n本図は、業務機能を実現する情報システムの階層構造を明確にすることを目的としています。\n'), AIMessage(content='この図は、販売管理システム、在庫管理システム、売掛管理システムの機能階層を示しています。\n\n### 販売管理システム\n- **販売業務**には新規取引、受注、出荷が含まれる。\n - **新規取引**では信用調査、取引受付、外部調査依頼、調査報告書作成、与信設定が行われる。\n - **受注**では引き合い、見積り、注文受け、出荷指図が行われる。\n - **出荷**では在庫引当、製造指図、納品、受注台帳更新、売上計上が行われる。\n\n### 在庫管理システム\n- **在庫引当**では在庫確認と在庫引当が行われ、製品有高帳の更新も含まれる。\n\n### 売掛管理システム\n- **債権管理**では債権計上データの取り込みと請求書発行が行われ、入金管理では入金の入力と予定変更が行われる。\n\nこの図は、業務機能を実現する情報システムの階層構造を明確化することを目的としています。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 296, 'prompt_tokens': 624, 'total_tokens': 920}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'stop', 'logprobs': None}, id='run-7435e7a0-7416-4ae9-9832-487c7309d82d-0', usage_metadata={'input_tokens': 624, 'output_tokens': 296, 'total_tokens': 920})]}}
----
最終の要約結果(上記結果の最終行)をわかりやすく表示し確認します。
# 最終結果の表示
print("処理完了。最終状態:")
for file_path, summary in s['summarize']['summaries'].items():
print(f"ファイル: {file_path}")
print(f"要約: {summary}\n")
以下の結果が出力されます。
処理完了。最終状態:
ファイル: /content/documents/受注業務(標準)の業務フロー.md
要約: 受注業務(標準)の業務フローは、顧客からの引き合い(見積依頼)から始まり、販売担当者、販売承認者、倉庫部を経て出荷に至る一連の流れを示しています。具体的には、顧客が見積依頼を行い、販売担当者が申し込み書類を送付後、見積書の確認や契約書の作成を行います。次に、販売承認者が注文書や契約書を確認し、受注内容を登録して出荷予定を決定します。その後、倉庫部で出荷が行われ、出荷依頼メールが送信されます。この業務フローは、各部門が異なるレーンで表現されており、システム間のデータのやり取りも存在しますが、図には明示的には示されていません。新規顧客に関するフローは別紙に記載されています。
ファイル: /content/documents/システム機能階層図.md
要約: この図は、販売管理システム、在庫管理システム、売掛管理システムの機能階層を示しています。
### 販売管理システム
- **販売業務**には新規取引、受注、出荷が含まれる。
- **新規取引**では信用調査、取引受付、外部調査依頼、調査報告書作成、与信設定が行われる。
- **受注**では引き合い、見積り、注文受け、出荷指図が行われる。
- **出荷**では在庫引当、製造指図、納品、受注台帳更新、売上計上が行われる。
### 在庫管理システム
- **在庫引当**では在庫確認と在庫引当が行われ、製品有高帳の更新も含まれる。
### 売掛管理システム
- **債権管理**では債権計上データの取り込みと請求書発行が行われ、入金管理では入金の入力と予定変更が行われる。
この図は、業務機能を実現する情報システムの階層構造を明確化することを目的としています。
まとめ
初めてLangGraphを触りましたが、きちんと動いて良かったです。
比較的新しく変化が激しい領域のなのでGPTやClaudeの力を借りづらい点で、まだまだこういった記事も誰かの助けになるのかなと思っています。(拙いコードですが。)
今後はマルチエージェントやReActの実装なりを試していこうと思います。