Ứng dụng LangGraph cơ bản với chatbot và công cụ
Mục tiêu của ứng dụng.
Sử dụng LangGraph quyết định phản hồi bằng chatbot hoặc sử dụng công cụ
Chúng ta sẽ xây dựng một ứng dụng cơ bản thực hiện 4 thao tác
Sử dụng chat messages làm State
Sử dụng chat model làm Node
Liên kết một công cụ với chat model
Thực hiện lệnh gọi công cụ trong Node
I. Cài đặt
* cd project_name
* pyenv local 3.11.4
* poetry install
* poetry shell
* jupyter lab
tạo file .env
OPENAI_API_KEY=your_openai_api_key
* LANGCHAIN_TRACING_V2=true
* LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
* LANGCHAIN_API_KEY=your_langchain_api_key
* LANGCHAIN_PROJECT=your_project_name
Bạn sẽ cần đăng ký tài khoản tại smith.langchain.com để lấy API key.
Kết nối với file .env nằm trong cùng thư mục của notebook
#pip install python-dotenv
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
openai_api_key = os.environ["OPENAI_API_KEY"]
#!pip install langchain-openai
from langchain_openai import ChatOpenAI
chatModel35 = ChatOpenAI(model="gpt-3.5-turbo-0125")
chatModel4o = ChatOpenAI(model="gpt-4o")
II. Xác định State schema
from typing_extensions import TypedDict
from langchain_core.messages import AnyMessage
from typing import Annotated
from langgraph.graph.message import add_messages
class MessagesState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
from typing_extensions import TypedDict
-
TypedDict
cho phép bạn định nghĩa một kiểu dictionary có cấu trúc rõ ràng, giống nhưdataclass
, nhưng dành cho dict. -
typing_extensions
được dùng để hỗ trợ các tính năng mới khi bạn đang dùng phiên bản Python cũ hơn
from langchain_core.messages import AnyMessage
-
AnyMessage
là một kiểu tin nhắn (message) tổng quát trong LangChain. -
Có thể là tin nhắn từ người dùng (
HumanMessage
), AI (AIMessage
), hệ thống (SystemMessage
)
from typing import Annotated
-
Annotated
là một cách để gắn thêm metadata vào kiểu dữ liệu. -
Không thay đổi kiểu dữ liệu, nhưng cho phép các công cụ/phần mềm xử lý kiểu đó biết thêm thông tin phụ.
Metadata là gì? Xem tại đây
Annotated là gì? Xem tại đây
from langgraph.graph.message import add_messages
-
add_messages
là một annotation handler từ thư việnlanggraph
. -
Nó được dùng để bổ sung logic cho cách mà LangGraph xử lý trường
messages
class MessagesState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
III. Xác định Node duy nhất của ứng dụng
def simple_llm(state: MessagesState):
return {"messages": [chatModel4o.invoke(state["messages"])]}
Đây là một LangGraph Node Function. Nó:
-
Nhận vào
state
(dạng dictionary có cấu trúcMessagesState
) -
Lấy danh sách tin nhắn từ
state["messages"]
-
Gửi toàn bộ danh sách đó vào mô hình ngôn ngữ
chatModel4o
-
Nhận lại một phản hồi từ LLM
-
Trả về phản hồi đó trong một dict mới dưới dạng
{"messages": [<message>]}
Ví dụ minh họa
Giả sử:
state = {
"messages": [
HumanMessage(content="Chào bạn"),
]
}
Gọi
simple_llm(state)
Trả về
{
"messages": [
AIMessage(content="Chào bạn! Tôi có thể giúp gì?")
]
}
Tóm lại
Thành phần | Vai trò |
---|---|
state: MessagesState |
Trạng thái hiện tại (danh sách message) |
chatModel4o.invoke(...) |
Gửi prompt đến LLM |
return {"messages": [...]} |
Trả về message mới để nối thêm vào state |
Vì trong ví dụ này chúng ta chỉ có một nút nên chúng ta không cần phải xác định các cạnh.
IV. Biên dịch ứng dụng
from IPython.display import Image, display
from langgraph.graph import StateGraph, START, END
# Build graph
builder = StateGraph(MessagesState)
builder.add_node("simple_llm", simple_llm)
# Add the logic of the graph
builder.add_edge(START, "simple_llm")
builder.add_edge("simple_llm", END)
# Compile the graph
graph = builder.compile()
# Visualize the graph
display(Image(graph.get_graph().draw_mermaid_png()))
from IPython.display import Image, display
-
Dùng trong Jupyter Notebook để hiển thị hình ảnh (ở đây là sơ đồ luồng graph).
-
display(...)
dùng để hiển thị hình ảnh. -
Image(...)
nhận vào dữ liệu ảnh hoặc URL.
from langgraph.graph import StateGraph, START, END
-
StateGraph
: class để xây dựng graph gồm các bước (nodes) xử lý state. -
START
vàEND
: các node mặc định dùng để đánh dấu điểm bắt đầu và kết thúc.
Xây dựng Graph:
builder = StateGraph(MessagesState)
Khởi tạo 1 builder để tạo ra graph, với MessagesState
là định nghĩa schema cho state.
builder.add_node("simple_llm", simple_llm)
-
Thêm một node có tên
"simple_llm"
và hàm xử lý tương ứng làsimple_llm
.
Kết nối các bước xử lý:
builder.add_edge(START, "simple_llm")
builder.add_edge("simple_llm", END)
START → simple_llm → END
: bạn đang định nghĩa luồng chạy của graph theo thứ tự:
-
Bắt đầu
-
Chạy
simple_llm
-
Kết thúc
Biên dịch Graph:
graph = builder.compile()
Hiển thị sơ đồ:
display(Image(graph.get_graph().draw_mermaid_png()))