1. Khởi tạo Graph Trạng thái và Định nghĩa Nodes
1.1. Thiết lập môi trường Python và cài đặt thư viện
Bước đầu tiên là tạo một môi trường ảo Python sạch và cài đặt các thư viện cần thiết cho LangGraph và LangChain.
Việc sử dụng venv giúp cô lập các thư viện của dự án, tránh xung đột với các gói hệ thống khác. Chúng ta cần langchain để kết nối LLM, langchain-community cho các công cụ hỗ trợ, và langgraph để xây dựng luồng điều khiển (workflow).
Kết quả mong đợi: Môi trường ảo được kích hoạt và các thư viện được cài đặt thành công không lỗi.
python3 -m venv venv
source venv/bin/activate
pip install langchain langchain-community langchain-openai langgraph
1.2. Định nghĩa Schema Trạng thái (State Schema)
LangGraph hoạt động dựa trên nguyên lý State Machine. Chúng ta cần định nghĩa một đối tượng chứa toàn bộ dữ liệu được truyền qua các nodes.
Chúng ta sẽ tạo file agent.py và định nghĩa class AgentState sử dụng TypedDict. Schema này sẽ lưu trữ input (dữ liệu đầu vào), messages (lịch sử hội thoại), và output (kết quả cuối cùng).
Kết quả mong đợi: File agent.py được tạo với cấu trúc dữ liệu chuẩn, sẵn sàng để các nodes đọc/ghi vào.
cat > agent.py
2. Kết nối Nodes với LLM thông qua Prompt
2.1. Cấu hình biến môi trường cho API Key
Trước khi gọi LLM, chúng ta cần cung cấp API Key. Ở đây dùng OpenAI làm ví dụ, nhưng logic áp dụng tương tự cho bất kỳ LLM nào.
Việc lưu API Key trong biến môi trường giúp bảo mật và dễ dàng quản lý khi chuyển sang môi trường production (Kubernetes). Chúng ta sẽ export biến OPENAI_API_KEY.
Kết quả mong đợi: Biến môi trường được thiết lập, LangChain sẽ tự động lấy key này khi khởi tạo client.
export OPENAI_API_KEY="sk-your-actual-api-key-here"
echo $OPENAI_API_KEY
2.2. Xây dựng Node xử lý LLM
Node là một hàm Python thực thi một tác vụ cụ thể. Trong trường hợp này, node sẽ nhận AgentState, tạo prompt, gọi LLM và trả về state mới.
Hàm llm_node sẽ lấy messages từ state, gọi ChatOpenAI, và thêm phản hồi của LLM vào danh sách messages trước khi trả về. Điều này tạo nên lịch sử hội thoại.
Kết quả mong đợi: Hàm llm_node được định nghĩa, có khả năng gọi LLM và cập nhật trạng thái hội thoại.
cat >> agent.py
3. Triển khai cơ chế vòng lặp và điều kiện chuyển trạng thái
3.1. Xây dựng Graph và kết nối các thành phần
Bây giờ chúng ta cần gắn kết các nodes vào một luồng điều khiển (Graph). LangGraph cung cấp StateGraph để làm việc này.
Chúng ta sẽ tạo instance StateGraph, thêm node llm_node, và thiết lập điểm bắt đầu (set_entry_point). Sau đó, chúng ta cần kết nối đầu vào từ người dùng vào node đầu tiên.
Kết quả mong đợi: Đối tượng graph được cấu hình, có điểm vào và node xử lý được liên kết.
cat >> agent.py
3.2. Thiết lập logic điều kiện và vòng lặp (Loop)
Để tạo một Agent thực sự, chúng ta cần cơ chế quyết định khi nào dừng và khi nào tiếp tục. Trong ví dụ đơn giản này, chúng ta sẽ thêm một node điều kiện (conditional_edge).
Hàm route_logic sẽ kiểm tra nội dung phản hồi của LLM. Nếu LLM yêu cầu thêm thông tin, graph sẽ quay lại node llm (tạo vòng lặp). Nếu không, nó chuyển đến END.
Kết quả mong đợi: Graph có khả năng tự quyết định luồng chạy, tạo thành một vòng lặp hoặc kết thúc tùy theo ngữ cảnh.
cat >> agent.py quay lại llm_node
# Nếu là AIMessage -> kết thúc
if isinstance(last_message, HumanMessage):
return "llm"
else:
return END
# Thêm conditional edge vào graph trước khi compile
# Lưu ý: Cần import lại workflow hoặc chỉnh sửa logic nếu đã compile
# Ở đây ta sẽ chỉnh sửa lại phần compile để áp dụng edge
EOF
Cần chỉnh sửa lại phần app = workflow.compile() để áp dụng logic điều kiện vừa tạo. Chúng ta sẽ ghi đè lại file agent.py với phiên bản hoàn chỉnh bao gồm cả logic điều kiện.
cat > agent.py chạy llm_node, nếu trả về END -> kết thúc
workflow.add_conditional_edges(
"llm",
route_logic,
{"llm": "llm", END: END}
)
# Kết nối input từ người dùng vào node llm (thông qua việc inject input vào messages)
# LangGraph tự động xử lý input mapping nếu key trong State khớp
app = workflow.compile()
EOF
4. Chạy thử nghiệm Agent đơn lẻ trên môi trường local
4.1. Tạo script chạy thử nghiệm (Test Runner)
Để kiểm tra agent, chúng ta cần một script gửi yêu cầu vào graph và in kết quả ra màn hình.
Script này sẽ khởi tạo một state ban đầu với input là câu hỏi của người dùng và messages chứa một HumanMessage. Sau đó gọi app.invoke().
Kết quả mong đợi: Script chạy thành công, in ra câu trả lời của LLM và trạng thái cuối cùng của graph.
cat > test_agent.py
4.2. Thực thi và kiểm tra kết quả
Bước cuối cùng là thực thi script test để xác nhận graph hoạt động đúng logic: nhận input -> gọi LLM -> tạo vòng lặp nếu cần -> trả về kết quả.
Chúng ta chạy script test_agent.py. Nếu mọi thứ đúng, bạn sẽ thấy dòng đầu là câu hỏi của bạn và dòng sau là câu trả lời chi tiết từ LLM.
Kết quả mong đợi: Xuất hiện 2 dòng message (1 User, 1 Agent), nội dung câu trả lời liên quan đến Kubernetes, không báo lỗi Exception.
python test_agent.py
4.3. Verify kết quả
Để đảm bảo agent hoạt động chính xác, hãy kiểm tra 3 điểm sau trong đầu ra:
- Trạng thái: Biến
messages trong kết quả phải chứa đúng 2 phần tử (1 HumanMessage, 1 AIMessage).
- Nội dung: Câu trả lời phải giải thích được về Kubernetes, không phải lỗi kết nối hoặc lỗi prompt.
- Logic vòng lặp: Nếu bạn sửa prompt để yêu cầu LLM hỏi lại (ví dụ: "Hỏi tôi thêm thông tin trước khi trả lời"), graph sẽ tự động chạy vòng lặp thêm lần nữa.
Thử nghiệm với một câu hỏi khác để xác nhận tính tổng quát của graph:
python -c "
from langchain_core.messages import HumanMessage
from agent import app
result = app.invoke({'input': 'Lập trình Python là gì?', 'messages': [HumanMessage(content='Lập trình Python là gì?')]})
print(result['messages'][-1].content)
"
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng AI Agent tự động hóa với LangGraph, CrewAI và Kubernetes
« Phần 1: Chuẩn bị môi trường phát triển và kiến trúc tổng quan
Phần 3: Tạo hệ thống đa Agent hợp tác với CrewAI »