Khóa học
Langflow là một công cụ low-code cho phép chúng ta tạo các quy trình (workflow) tác tử AI và tự động hóa tác vụ bằng cách sử dụng nhiều API khác nhau.
Trong bài viết này, tôi sẽ giải thích từng bước cách sử dụng Langflow để tạo các quy trình tác tử AI tùy chỉnh bằng Python. Tôi sẽ chỉ cho bạn cách xây dựng một tác tử AI giúp người dùng luyện kỹ năng đọc khi học một ngôn ngữ mới.
Langflow là gì?
Langflow cho phép chúng ta tự động hóa các workflow bằng cách kết nối nhiều thành phần khác nhau mà không cần phải viết mã. Mỗi thành phần nhận đầu ra từ các thành phần khác, thực hiện một hành động cụ thể, rồi cung cấp dữ liệu mới làm đầu ra.
Ví dụ, khi xây dựng một chatbot AI, chúng ta có thể nối một thành phần đầu vào chat với một mô hình ngôn ngữ (LLM). Đầu ra từ thành phần LLM sau đó có thể được liên kết với một thành phần đầu ra chat khác.

Bên cạnh bộ sưu tập lớn các thành phần dựng sẵn, chúng ta có thể xây dựng các thành phần tùy chỉnh bằng Python. Ở mức khái quát, một thành phần tùy chỉnh là một hàm Python nhận một số đầu vào và xuất ra một số dữ liệu.
Chúng ta sẽ học cách sử dụng các thành phần tùy chỉnh để xây dựng một gia sư ngôn ngữ AI bằng Python. Nếu bạn quan tâm đến việc xây dựng các workflow kiểu này mà không cần viết mã, tôi khuyến nghị xem hướng dẫn n8n này (n8n là một công cụ tương tự, và trong hướng dẫn đó tôi giải thích cách tiếp cận no-code để xây dựng một tác tử AI tự động xử lý hóa đơn từ hộp thư email của bạn).
Cách cài đặt Langflow?
Chúng ta có thể sử dụng Langflow miễn phí, hoặc trên trang web chính thức qua giao diện web của họ hoặc bằng cách cài đặt cục bộ.
Trong hướng dẫn này, chúng ta sẽ dùng thiết lập cục bộ với Docker. Bạn không cần biết Docker để theo dõi. Nhưng nếu muốn tìm hiểu thêm, hãy xem hướng dẫn Docker cho người mới bắt đầu này và khóa học Docker này.
Docker là một công cụ cho phép chúng ta chạy ứng dụng trong các môi trường biệt lập gọi là container, giúp việc phát triển, kiểm thử và triển khai phần mềm nhất quán và dễ dàng. Trong trường hợp của chúng ta, dùng Docker sẽ linh hoạt hơn để xây dựng các thành phần tùy chỉnh bằng Python, vì chúng ta có thể dùng cơ sở dữ liệu cục bộ và không cần kết nối tới dịch vụ bên ngoài.
Langflow cung cấp một ví dụ dựng sẵn sẵn sàng chạy, nên chúng ta sẽ không phải tự cấu hình.
Chạy Langflow cục bộ với Docker
Để chạy Langflow cục bộ với Docker, hãy làm theo các bước sau:
- Cài đặt Docker bằng cách làm theo hướng dẫn tại đây.
- Clone hoặc tải về kho lưu trữ chính thức của Langflow.
- Mở terminal trong thư mục
docker_example. - Chạy lệnh
docker compose up.
Giờ đây, Langflow sẽ chạy trên máy cục bộ của chúng ta. Bạn sẽ thấy thông báo này trong terminal:

Chúng ta có thể mở ứng dụng bằng cách truy cập URL hiển thị trong terminal, http://0.0.0.0:7860 như ví dụ trên.
Khám phá Simple Agent với Langflow
Trong phần này, chúng ta tìm hiểu cách Langflow hoạt động bằng cách xem xét mẫu tác tử AI đơn giản của Langflow. Để làm vậy, hãy chọn "Simple Agent" trên màn hình đầu tiên.

Thao tác này sẽ tạo một workflow của tác tử như sau:

Thành phần chính trong workflow này là thành phần "Agent" ở giữa:

Thành phần agent này đang dùng mô hình gpt-4.1 của OpenAI. Để sử dụng, chúng ta cần dán một khóa API OpenAI. Nếu bạn chưa có, bạn có thể tạo tại đây.
Bên trái thành phần agent, chúng ta thấy các đầu vào và công cụ sẵn có cho nó (xem hình dưới). Trong trường hợp này, có hai công cụ và một đầu vào:
- Một Chat Input dùng tin nhắn từ người dùng trong giao diện chat làm đầu vào.
- Một công cụ Calculator dùng để thực hiện phép tính.
- Một công cụ URL dùng để lấy thông tin từ một URL cụ thể.

Đầu vào chat có nghĩa là khi chạy workflow, chúng ta có thể dùng giao diện chat tích hợp của Langflow để gửi tin nhắn tới mô hình. Ở đầu mỗi công cụ, chúng ta thấy phần mô tả. Mô hình dùng thông tin này để quyết định có gọi từng công cụ hay không.
Bên phải, chúng ta thấy các đầu ra. Ở đây có một thành phần đầu ra duy nhất là Chat Output, cho biết câu trả lời của Agent sẽ được gửi tới khung chat.
Tìm hiểu các thành phần
Trước khi chạy Simple Agent, hãy dùng thành phần URL để hiểu cách các thành phần hoạt động nói chung. Hãy tạo một bản sao để thử nghiệm.
- Chọn thành phần URL.
- Sao chép và dán nó.
- Đừng kết nối nó với bất cứ thành phần nào.
Ở đầu thành phần mới có công tắc "Tool Mode"; hãy tắt nó.

Trong trường URLs, nhập ví dụ https://en.wikipedia.org/wiki/Data_science, trang Wikipedia về Khoa học dữ liệu. Thực thi thành phần bằng cách nhấp nút chạy hình mũi tên ở góc trên bên phải.

Thành phần sẽ chạy và tải nội dung từ URL chúng ta đã cung cấp. Chúng ta có thể xem bằng cách nhấp vào trình kiểm tra (inspector) cạnh các liên kết đầu ra. Mỗi liên kết biểu thị một định dạng đầu ra khác nhau.

Ẩn sau mỗi nút là một script Python. Chúng ta sẽ tìm hiểu thêm khi xây dựng các nút tùy chỉnh ở phần sau. Bạn có thể xem mã bằng cách nhấp nút "Code" ở phía trên:

Trong workflow Simple Agent gốc, nút URL được cấu hình là một công cụ. Điều này có nghĩa nó được dùng bởi một Agent. Trong trường hợp này, các URL không được cung cấp tường minh. Thay vào đó, chính agent sẽ cung cấp URL.
Chạy Simple Agent
Quay lại Simple Agent, chúng ta có thể chạy nó bằng cách nhấp nút "Playground" ở góc trên bên phải. Thao tác này mở giao diện chat, cho phép chúng ta trò chuyện với Agent.

Hãy yêu cầu nó tóm tắt trang Wikipedia về Khoa học dữ liệu:

Nếu chúng ta mở rộng hộp ở đầu câu trả lời, sẽ thấy các bước đã được thực thi trong workflow.

Ở đây, chẳng hạn, chúng ta thấy nó dùng hàm fetch_content_text(), được định nghĩa trong công cụ URL mà ta đã cung cấp cho agent.
Chúng ta có thể kiểm thử việc sử dụng công cụ Calculation bằng cách yêu cầu nó thực hiện một phép tính. Biểu thức sẽ được phân tích và gửi tới công cụ để đánh giá. Cách này cho câu trả lời đáng tin cậy hơn so với chỉ dựa vào LLM.
Tạo thành phần tùy chỉnh trong Langflow bằng Python
Trong phần này, chúng ta học cách tạo các thành phần tùy chỉnh. Để bắt đầu, nhấp nút "New Custom Component" ở góc dưới bên trái:

Theo mặc định, thao tác này tạo một thành phần nhận một giá trị văn bản làm đầu vào và xuất ra chính văn bản đó. Đầu vào mặc định là "Hello, World!" và nếu chúng ta chạy rồi kiểm tra đầu ra, kết quả đúng như vậy.
Khi xem mã, chúng ta thấy như sau:

- Các trường này là giá trị cấu hình cho thành phần. Phần mô tả rất quan trọng vì được tác tử AI dùng để biết khi nào sử dụng thành phần này khi nó được cung cấp như một công cụ. Trường tài liệu là một URL tùy chọn tới tài liệu của thành phần, nên ở đây ta không cần bận tâm.
- Danh sách
inputschỉ định các loại đầu vào sẵn có cho thành phần. Trường hợp này gồm một đầu vào lớpMessageTextInputtêninput_value, tương ứng với trường văn bản. Tên phải là một tên biến Python hợp lệ vì nó trở thành thuộc tính của lớp. Khi một thành phần được đặt là công cụ, các đầu vào này sẽ được tác tử AI tự động điền. Nó dùng trườnginfođể quyết định đầu vào nên là gì. Langflow hỗ trợ nhiều loại đầu vào. Đây là danh sách đầy đủ các đầu vào được hỗ trợ. - Phần này định nghĩa các đầu ra. Trường
methodchỉ định hàm được thực thi để tạo đầu ra. Hàm có thể truy cập đầu vào quaself. Ví dụ, đầu vào ở đây têninput_value, nên ta truy cập bằngself.input_value. Giá trị trả về nên là một lớp trong các lớp đầu ra được hỗ trợ.
Để biết thêm về việc tạo thành phần tùy chỉnh, hãy xem tài liệu chính thức về thành phần của Langflow.
Dưới đây là ví dụ cách tạo một thành phần cộng hai số:
from langflow.custom import Component
from langflow.io import MessageTextInput, Output
from langflow.schema import Data
class AddNumbers(Component):
display_name = "Add Numbers"
description = "This component adds two numbers together"
icon = "code"
name = "AddNumbers"
inputs = [
IntInput(
name="number1",
display_name="First Number",
info="The first number to add",
),
IntInput(
name="number2",
display_name="Second Number",
info="The second number to add",
),
]
outputs = [
Output(display_name="Output", name="output", method="add_numbers"),
]
def add_numbers(self) -> Data:
result = self.number1 + self.number2
data = Data(value=result)
return data
Xây dựng gia sư ngôn ngữ với Langflow
Hãy xây dựng một tác tử AI để giúp chúng ta luyện kỹ năng đọc khi học một ngôn ngữ mới.
Theo kinh nghiệm của tôi, khi học một ngôn ngữ mới, một trong những cách cải thiện kỹ năng là đọc. Dĩ nhiên, lúc mới bắt đầu bạn chỉ biết vài từ, nên đọc một cuốn sách là điều không thể. Do đó, chúng ta muốn có tài liệu đọc tập trung vào vốn từ vựng hiện tại của mình.
Chúng ta sẽ dùng một LLM để tạo các câu chuyện ngắn để đọc. Tuy nhiên, để có trải nghiệm học tập cá nhân hóa, chúng ta muốn các câu chuyện này tập trung vào vốn từ vựng mà ta đã biết.
Những gì chúng ta cần gồm:
- Một cơ sở dữ liệu các từ vựng đã biết.
- Tác tử AI cần quyền truy cập vào cơ sở dữ liệu để lấy từ vựng đã biết và tạo câu chuyện.
- Tác tử AI cần quyền truy cập vào cơ sở dữ liệu để thêm từ mới.
Thành phần thiết lập cơ sở dữ liệu
Khi chúng ta dùng Docker để chạy Langflow, nó sẽ khởi tạo một cơ sở dữ liệu Postgres. Chúng ta có thể truy cập bằng gói psycopg2. Để tìm hiểu thêm về Postgres, hãy xem hướng dẫn PostgreSQL này.
Chúng ta sẽ tạo một nút nơi có thể tải lên một tệp CSV chứa các từ đã biết để khởi tạo cơ sở dữ liệu. Tệp CSV của tôi trông như sau:

Tôi đã tạo một thành phần với hai đầu vào.
- Tên cột để chỉ định cột chứa các từ chúng ta muốn đưa vào.
- Đầu vào tệp để cung cấp tệp CSV chứa các từ.
Đây là mã của thành phần:
from langflow.custom import Component
from langflow.io import MessageTextInput, Output
from langflow.schema import Message
import psycopg2
import csv
def connect_to_database():
# Connect to the Postgres database provided by the Docker setup
conn = psycopg2.connect(
dbname="langflow",
user="langflow",
password="langflow",
host="postgres",
port="5432"
)
conn.autocommit = True
return conn.cursor()
def add_word(cursor, word):
# Add a word to the database
cursor.execute(
"INSERT INTO words (word) VALUES (%s) ON CONFLICT (word) DO NOTHING;",
(word,)
)
def initialize_database(cursor):
# Initialize the database by creating the word table if it doesn't yet exist
create_table_query = """
CREATE TABLE IF NOT EXISTS words (
word TEXT PRIMARY KEY
);
"""
cursor.execute(create_table_query)
class UploadWordFile(Component):
display_name = "Upload Word File"
description = "Upload a CSV file of words to the database."
icon = "code"
name = "UploadWordFile"
inputs = [
StrInput(
name="column_name",
display_name="Column Name",
info="The name of the column containing the words",
),
FileInput(
name="csv_file",
display_name="CSV file",
info="CSV input file",
file_types=["csv"]
),
]
outputs = [
Output(display_name="Output", name="output", method="load_words_into_database"),
]
def load_words_into_database(self) -> Message:
try:
cursor = connect_to_database()
initialize_database(cursor)
with open(self.csv_file, "rt") as f:
rows = list(csv.reader(f))
headers = list(map(lambda header: header.lower(), rows[0]))
column_index = headers.index(self.column_name)
for row in rows[1:]:
add_word(cursor, row[column_index])
return "Success"
except Exception as e:
return f"Error: {str(e)}"
Thành phần trông như thế này:

Nó được thiết kế để dùng độc lập và không kết nối với thành phần nào khác. Chúng ta có thể dùng nó để tải thủ công các từ vào cơ sở dữ liệu.
Công cụ thêm từ
Tại đây, chúng ta tạo một công cụ để tác tử AI có thể dùng để thêm từ mới vào cơ sở dữ liệu. Nhờ vậy, người dùng có thể dễ dàng thêm từ mới bằng cách gửi tin nhắn cho agent.
Đoạn mã này tái sử dụng các hàm connect_to_database() và add_word() từ nút trước. Với một thiết lập Docker tốt hơn, chúng ta có thể tránh lặp mã, nhưng trong hướng dẫn này, chúng ta sẽ giữ mọi thứ đơn giản.
Đây là mã cho công cụ này:
# from langflow.field_typing import Data
from langflow.custom import Component
from langflow.io import MessageTextInput, Output
from langflow.schema import Message
def connect_to_database():
# Connect to the Postgres database provided by the Docker setup
conn = psycopg2.connect(
dbname="langflow",
user="langflow",
password="langflow",
host="postgres",
port="5432"
)
conn.autocommit = True
return conn.cursor()
def add_word(cursor, word):
# Add a word to the database
cursor.execute(
"INSERT INTO words (word) VALUES (%s) ON CONFLICT (word) DO NOTHING;",
(word,)
)
class AddWordTool(Component):
display_name = "Add word tool"
description = "Use this tool to add a new word"
icon = "code"
name = "AddWordTool"
inputs = [
MessageTextInput(
name="word",
display_name="Word",
info="The word to add",
tool_mode=True,
),
]
outputs = [
Output(display_name="Output", name="output", method="add_new_word"),
]
def add_new_word(self) -> Message:
cursor = connect_to_database()
add_word(cursor, self.word)
return f"Added word: {self.word}"
Lưu ý công cụ này giả định rằng cơ sở dữ liệu đã được tạo từ trước. Nó sẽ không hoạt động nếu chưa chạy thành phần trước đó ít nhất một lần.
Hãy nhớ bật chế độ công cụ (tool mode):

Công cụ tạo câu chuyện
Để tạo câu chuyện, chúng ta dùng một thành phần tác tử AI. Cấu trúc như sau:

Trong phần hướng dẫn cho agent, thay vì thêm prompt trực tiếp trong thành phần, chúng ta dùng một thành phần Prompt vì cách này cho phép thêm tham số vào prompt. Đây là prompt chúng ta dùng:
Create a story in {language} using only words from the following list:
{words}
Prompt có hai tham số, {language} và {words}. Khi thêm các tham số như vậy, nó sẽ thêm một trường cho từng tham số vào thành phần.

Với giá trị ngôn ngữ, chúng ta chỉ cần nhập trực tiếp vào ô văn bản. Các từ cần được tải từ cơ sở dữ liệu, nên chúng ta đã tạo một thành phần tùy chỉnh để tải tất cả từ từ cơ sở dữ liệu và nối đầu ra của nút đó vào trường words.

Đây là mã của thành phần tải từ:
from langflow.custom import Component
from langflow.io import MessageTextInput, Output
from langflow.schema import Message
import psycopg2
def load_words():
conn = psycopg2.connect(
dbname="langflow",
user="langflow",
password="langflow",
host="postgres",
port="5432"
)
cursor = conn.cursor()
cursor.execute("""
SELECT * FROM words;
""")
rows = cursor.fetchall()
return map(lambda row: row[0], rows)
class WordLoader(Component):
display_name = "Word Loader"
description = "Load words from the database"
icon = "code"
name = "WordLoader"
outputs = [
Output(display_name="Output", name="output", method="build_output"),
]
def build_output(self) -> Message:
return str(", ".join(load_words()))
Tiếp theo, chúng ta đặt agent này ở chế độ công cụ. Như vậy, agent chính (được tạo ở bước sau) sẽ có thể dùng agent này để tạo câu chuyện khi cần.

Cuối cùng, chúng ta đổi tên agent và chỉnh lại mô tả công cụ để AI biết khi nào nên dùng công cụ này:

Tác tử ngôn ngữ
Với agent chính, chúng ta dùng một nút tác tử AI thông thường kết nối với hai công cụ vừa tạo. Agent này dùng thành phần đầu vào chat và đầu ra chat để chúng ta tương tác qua giao diện chat.
Đây là kiến trúc cuối cùng:

Prompt chúng ta dùng là:
You will help the user practice their language skills. You will either be asked to create a story or to add a new word to the vocabulary.
- If the user asks you to create a story, use the story generation tool.
- If the user asks you to add a word, use the word add tool.
When using a tool, your answer should just be the result from the tool and nothing else.
Chúng ta có thể chạy toàn bộ workflow bằng cách nhấp nút “Playground”. Dưới đây là một tương tác mẫu:

Kết luận
Chúng ta đã khám phá các khía cạnh nền tảng của Langflow và cách dùng nó để xây dựng một workflow tác tử AI giúp người dùng luyện kỹ năng đọc. Bằng cách dùng Python để tạo các thành phần tùy chỉnh, chúng ta mở ra nhiều khả năng hơn.
Cách tiếp cận lai này kết hợp những điều tốt nhất của cả hai: sự linh hoạt của các script Python, cho phép thực thi bất kỳ tác vụ mong muốn nào, và giao diện đồ họa trực quan của Langflow, giúp xây dựng workflow dễ dàng mà không cần đi sâu vào mã phức tạp.
Để tìm hiểu thêm về tác tử AI, tôi khuyến nghị đọc các blog sau:
