Logo Zephyrnet

Xây dựng Tác nhân mã hóa AI với LangGraph của LangChain

Ngày:

Giới thiệu

Đã có sự gia tăng lớn về số lượng ứng dụng sử dụng tác nhân mã hóa AI. Với chất lượng LLM ngày càng tăng và chi phí suy luận giảm, việc xây dựng các tác nhân AI có khả năng sẽ ngày càng dễ dàng hơn. Trên hết, hệ sinh thái công cụ đang phát triển nhanh chóng, giúp việc xây dựng các tác nhân mã hóa AI phức tạp trở nên dễ dàng hơn. Khung Langchain đã dẫn đầu trong lĩnh vực này. Nó có tất cả các công cụ và kỹ thuật cần thiết để tạo ra các ứng dụng AI sẵn sàng cho sản xuất.

Nhưng cho đến nay, nó vẫn còn thiếu một điều. Và đó là sự hợp tác đa tác nhân có tính chu kỳ. Điều này rất quan trọng để giải quyết các vấn đề phức tạp, trong đó vấn đề có thể được phân chia và giao cho các tác nhân chuyên môn. Đây là nơi LangGraph xuất hiện, một phần của khung Langchain được thiết kế để đáp ứng sự cộng tác trạng thái của nhiều tác nhân giữa các tác nhân mã hóa AI. Hơn nữa, trong bài viết này, chúng ta sẽ thảo luận về LangGraph và các khối xây dựng cơ bản của nó trong khi chúng ta xây dựng một tác nhân bằng nó.

Mục tiêu học tập

  • Hiểu LangGraph là gì.
  • Khám phá kiến ​​thức cơ bản về LangGraph để xây dựng Tác nhân có trạng thái.
  • Khám phá TogetherAI để truy cập các mô hình truy cập mở như DeepSeekCoder.
  • Xây dựng tác nhân mã hóa AI bằng LangGraph để viết bài kiểm tra đơn vị.
LangChain

Bài báo này đã được xuất bản như một phần của Blogathon Khoa học Dữ liệu.

Mục lục

LangGraph là gì?

LangGraph là một phần mở rộng của hệ sinh thái LangChain. Mặc dù LangChain cho phép xây dựng các tác nhân mã hóa AI có thể sử dụng nhiều công cụ để thực hiện các tác vụ nhưng nó không thể phối hợp nhiều chuỗi hoặc tác nhân qua các bước. Đây là hành vi quan trọng để tạo ra các tác nhân hoàn thành các nhiệm vụ phức tạp. LangGraph được hình thành để ghi nhớ những điều này. Nó xử lý quy trình làm việc của Tác nhân dưới dạng cấu trúc Biểu đồ tuần hoàn, trong đó mỗi nút đại diện cho một hàm hoặc một đối tượng Langchain Runnable và các cạnh là các kết nối giữa các nút. 

Các tính năng chính của LangGraph bao gồm 

  • Nodes: Bất kỳ chức năng hoặc đối tượng Langchain Runnable nào giống như một công cụ.
  • Cạnh: Xác định hướng giữa các nút.
  • Đồ thị có trạng thái: Loại biểu đồ chính. Nó được thiết kế để quản lý và cập nhật các đối tượng trạng thái khi xử lý dữ liệu thông qua các nút của nó.

LangGraph tận dụng điều này để tạo điều kiện thực hiện cuộc gọi LLM theo chu kỳ với tính bền vững của trạng thái, điều này rất quan trọng đối với hành vi tác nhân. Kiến trúc lấy cảm hứng từ Pregel và Chùm Apache

Trong bài viết này, chúng ta sẽ xây dựng một Tác nhân để viết các bài kiểm tra đơn vị Pytest cho một lớp Python bằng các phương thức. Và đây là quy trình làm việc.

LangChain

Chúng tôi sẽ thảo luận chi tiết về các khái niệm khi xây dựng tác nhân mã hóa AI để viết các bài kiểm tra đơn vị đơn giản. Vì vậy, hãy chuyển sang phần mã hóa.

Nhưng trước đó, hãy thiết lập môi trường phát triển của chúng ta.

Cài đặt phụ thuộc

Điều đầu tiên trước tiên. Giống như bất kỳ dự án Python nào, hãy tạo một môi trường ảo và kích hoạt nó.

python -m venv auto-unit-tests-writer
cd auto-unit-tests-writer
source bin/activate

Bây giờ, cài đặt các phụ thuộc.

!pip install langgraph langchain langchain_openai colorama

Nhập tất cả các thư viện và các lớp của chúng.

from typing import TypedDict, List
import colorama
import os

from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage
from langchain_core.messages import HumanMessage
from langchain_core.runnables import RunnableConfig

from langgraph.graph import StateGraph, END
from langgraph.pregel import GraphRecursionError

Chúng ta cũng sẽ muốn tạo các thư mục và tập tin cho các trường hợp thử nghiệm. Bạn có thể tạo tệp theo cách thủ công hoặc sử dụng Python cho việc đó.

# Define the paths.
search_path = os.path.join(os.getcwd(), "app")
code_file = os.path.join(search_path, "src/crud.py")
test_file = os.path.join(search_path, "test/test_crud.py")

# Create the folders and files if necessary.
if not os.path.exists(search_path):
    os.mkdir(search_path)
    os.mkdir(os.path.join(search_path, "src"))
    os.mkdir(os.path.join(search_path, "test"))

Bây giờ, hãy cập nhật tệp crud.py bằng mã cho ứng dụng CRUD trong bộ nhớ. Chúng tôi sẽ sử dụng đoạn mã này để viết bài kiểm tra đơn vị. Bạn có thể sử dụng chương trình Python của mình cho việc này. Chúng tôi sẽ thêm chương trình bên dưới vào tệp code.py của chúng tôi.

#crud.py
code = """class Item:
    def __init__(self, id, name, description=None):
        self.id = id
        self.name = name
        self.description = description

    def __repr__(self):
        return f"Item(id={self.id}, name={self.name}, description={self.description})"

class CRUDApp:
    def __init__(self):
        self.items = []

    def create_item(self, id, name, description=None):
        item = Item(id, name, description)
        self.items.append(item)
        return item

    def read_item(self, id):
        for item in self.items:
            if item.id == id:
                return item
        return None

    def update_item(self, id, name=None, description=None):
        for item in self.items:
            if item.id == id:
                if name:
                    item.name = name
                if description:
                    item.description = description
                return item
        return None

    def delete_item(self, id):
        for index, item in enumerate(self.items):
            if item.id == id:
                return self.items.pop(index)
        return None

    def list_items(self):
        return self.items"""
        
with open(code_file, 'w') as f:
  f.write(code)

Thiết lập LLM

Bây giờ, chúng tôi sẽ chỉ định LLM mà chúng tôi sẽ sử dụng trong dự án này. Việc sử dụng mô hình nào ở đây phụ thuộc vào nhiệm vụ và tính sẵn có của tài nguyên. Bạn có thể sử dụng các mẫu mạnh mẽ, độc quyền như GPT-4, Gemini Ultra hoặc GPT-3.5. Ngoài ra, bạn có thể sử dụng các mô hình truy cập mở như Mixtral và Llama-2. Trong trường hợp này, vì liên quan đến việc viết mã, chúng ta có thể sử dụng mô hình mã hóa được tinh chỉnh như bộ mã hóa DeepSeekCoder-33B hoặc Llama-2. Hiện nay, có nhiều nền tảng dành cho suy luận LLM, như Anayscale, Abacus và Together. Chúng tôi sẽ sử dụng Together AI để suy ra DeepSeekCoder. Vì vậy, hãy lấy một Mã API từ Together trước khi tiếp tục. 

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(base_url="https://api.together.xyz/v1",
    api_key="your-key",
    model="deepseek-ai/deepseek-coder-33b-instruct")

Vì API tương thích với OpenAI SDK nên chúng ta có thể sử dụng OpenAI SDK của Langchain để giao tiếp với các mô hình được lưu trữ trên Together bằng cách thay đổi tham số base_url thành “https://api. together.xyz/v1”. Trong api_key, hãy chuyển khóa API Together của bạn và thay cho các mô hình, hãy chuyển khóa tên người mẫu có sẵn trên Together.

Xác định trạng thái đại lý

Đây là một trong những phần quan trọng của LangGraph. Ở đây, chúng ta sẽ xác định một AgentState, chịu trách nhiệm theo dõi trạng thái của các Agent trong suốt quá trình thực thi. Đây chủ yếu là lớp TypedDict với các thực thể duy trì trạng thái của Đại lý. Hãy xác định AgentState của chúng tôi

class AgentState(TypedDict):
    class_source: str
    class_methods: List[str]
    tests_source: str

Trong lớp AgentState ở trên, class_source lưu trữ lớp Python gốc, class_methods để lưu trữ các phương thức của lớp và test_source cho mã kiểm tra đơn vị. Chúng tôi đã xác định chúng là AgentState để sử dụng chúng trong các bước thực thi. 

Bây giờ, hãy xác định Biểu đồ bằng AgentState.

# Create the graph.
workflow = StateGraph(AgentState)

Như đã đề cập trước đó, đây là biểu đồ trạng thái và bây giờ chúng tôi đã thêm đối tượng trạng thái của mình.

Xác định nút

Bây giờ chúng ta đã xác định AgentState, chúng ta cần thêm các nút. Vậy chính xác thì các nút là gì? Trong LangGraph, các nút là các hàm hoặc bất kỳ đối tượng có thể chạy được nào, như các công cụ Langchain, thực hiện một hành động duy nhất. Trong trường hợp của chúng ta, chúng ta có thể định nghĩa một số nút, như hàm tìm phương thức lớp, hàm suy luận và cập nhật các bài kiểm tra đơn vị cho các đối tượng trạng thái và hàm để ghi nó vào tệp kiểm tra.

Chúng tôi cũng cần một cách để trích xuất mã từ tin nhắn LLM. Đây là cách thực hiện.

def extract_code_from_message(message):
    lines = message.split("n")
    code = ""
    in_code = False
    for line in lines:
        if "```" in line:
            in_code = not in_code
        elif in_code:
            code += line + "n"
    return code

Đoạn mã ở đây giả sử các mã nằm trong dấu ngoặc kép.

Bây giờ, hãy xác định các nút của chúng tôi.

import_prompt_template = """Here is a path of a file with code: {code_file}.
Here is the path of a file with tests: {test_file}.
Write a proper import statement for the class in the file.
"""
# Discover the class and its methods.
def discover_function(state: AgentState):
    assert os.path.exists(code_file)
    with open(code_file, "r") as f:
        source = f.read()
    state["class_source"] = source

    # Get the methods.
    methods = []
    for line in source.split("n"):
        if "def " in line:
            methods.append(line.split("def ")[1].split("(")[0])
    state["class_methods"] = methods

    # Generate the import statement and start the code.
    import_prompt = import_prompt_template.format(
        code_file=code_file,
        test_file=test_file
    )
    message = llm.invoke([HumanMessage(content=import_prompt)]).content
    code = extract_code_from_message(message)
    state["tests_source"] = code + "nn"

    return state


# Add a node to for discovery.
workflow.add_node(
    "discover",
    discover_function
)

Trong đoạn mã trên, chúng tôi đã xác định một hàm để khám phá mã. Nó trích xuất các mã từ AgentState lớp_source phần tử, phân chia lớp thành các phương thức riêng lẻ và chuyển nó đến LLM kèm theo lời nhắc. Đầu ra được lưu trữ trong AgentState kiểm tra_source yếu tố. Chúng tôi chỉ yêu cầu nó viết các câu lệnh nhập cho các trường hợp kiểm thử đơn vị.

Chúng tôi cũng đã thêm nút đầu tiên vào đối tượng StateGraph.

Bây giờ, vào nút tiếp theo. 

Ngoài ra, chúng tôi có thể thiết lập một số mẫu lời nhắc mà chúng tôi sẽ cần ở đây. Đây là những mẫu mẫu bạn có thể thay đổi theo nhu cầu của mình.

# System message template.

system_message_template = """You are a smart developer. You can do this! You will write unit 
tests that have a high quality. Use pytest.

Reply with the source code for the test only. 
Do not include the class in your response. I will add the imports myself.
If there is no test to write, reply with "# No test to write" and 
nothing more. Do not include the class in your response.

Example:

```
def test_function():
    ...
```

I will give you 200 EUR if you adhere to the instructions and write a high quality test. 
Do not write test classes, only methods.
"""

# Write the tests template.
write_test_template = """Here is a class:
'''
{class_source}
'''

Implement a test for the method "{class_method}".
"""

Bây giờ, hãy xác định nút.

# This method will write a test.
def write_tests_function(state: AgentState):

    # Get the next method to write a test for.
    class_method = state["class_methods"].pop(0)
    print(f"Writing test for {class_method}.")

    # Get the source code.
    class_source = state["class_source"]

    # Create the prompt.
    write_test_prompt = write_test_template.format(
        class_source=class_source,
        class_method=class_method
    )
    print(colorama.Fore.CYAN + write_test_prompt + colorama.Style.RESET_ALL)

    # Get the test source code.
    system_message = SystemMessage(system_message_template)
    human_message = HumanMessage(write_test_prompt)
    test_source = llm.invoke([system_message, human_message]).content
    test_source = extract_code_from_message(test_source)
    print(colorama.Fore.GREEN + test_source + colorama.Style.RESET_ALL)
    state["tests_source"] += test_source + "nn"

    return state

# Add the node.
workflow.add_node(
    "write_tests",
    write_tests_function
)

Ở đây, chúng tôi sẽ tạo LLM viết các trường hợp kiểm thử cho từng phương thức, cập nhật chúng vào phần tử test_source của AgentState và thêm chúng vào đối tượng StateGraph của quy trình làm việc.

Cạnh

Bây giờ chúng ta có hai nút, chúng ta sẽ xác định các cạnh giữa chúng để chỉ định hướng thực hiện giữa chúng. LangGraph chủ yếu cung cấp hai loại cạnh.

  • Cạnh có điều kiện: Luồng thực thi phụ thuộc vào phản hồi của tác nhân. Điều này rất quan trọng để thêm tính chu kỳ vào quy trình công việc. Tác nhân có thể quyết định nút nào sẽ di chuyển tiếp theo dựa trên một số điều kiện. Quay lại nút trước, lặp lại nút hiện tại hay di chuyển đến nút tiếp theo.
  • Cạnh bình thường: Đây là trường hợp bình thường, trong đó một nút luôn được gọi sau lệnh gọi các nút trước đó.

Chúng tôi không cần điều kiện để kết nối khám phá và write_tests, vì vậy chúng tôi sẽ sử dụng cạnh bình thường. Ngoài ra, hãy xác định điểm vào chỉ định nơi thực thi sẽ bắt đầu.

# Define the entry point. This is where the flow will start.
workflow.set_entry_point("discover")

# Always go from discover to write_tests.
workflow.add_edge("discover", "write_tests")

Quá trình thực thi bắt đầu bằng việc khám phá các phương thức và chuyển sang chức năng viết bài kiểm tra. Chúng tôi cần một nút khác để ghi mã kiểm tra đơn vị vào tệp kiểm tra.

# Write the file.
def write_file(state: AgentState):
    with open(test_file, "w") as f:
        f.write(state["tests_source"])
    return state

# Add a node to write the file.
workflow.add_node(
    "write_file",
    write_file)

Vì đây là nút cuối cùng của chúng tôi nên chúng tôi sẽ xác định cạnh giữa write_tests và write_file. Đây là cách chúng ta có thể làm điều này.

# Find out if we are done.
def should_continue(state: AgentState):
    if len(state["class_methods"]) == 0:
        return "end"
    else:
        return "continue"

# Add the conditional edge.
workflow.add_conditional_edges(
    "write_tests",
    should_continue,
    {
        "continue": "write_tests",
        "end": "write_file"
    }
)

Hàm add_conditional_edge lấy hàm write_tests, hàm Should_continue quyết định bước nào sẽ thực hiện dựa trên các mục nhập class_methods và ánh xạ với các chuỗi làm khóa và các hàm khác làm giá trị.

Cạnh bắt đầu tại write_tests và dựa trên đầu ra của Should_continue, thực thi một trong các tùy chọn trong ánh xạ. Ví dụ: nếu state[“class_methods”] không trống thì chúng tôi chưa viết bài kiểm tra cho tất cả các phương thức; chúng tôi lặp lại hàm write_tests và khi chúng tôi viết xong các bài kiểm tra, write_file sẽ được thực thi.

Khi các thử nghiệm cho tất cả các phương pháp đã được suy ra từ LLM, các bài kiểm tra được ghi vào tệp test.

Bây giờ, thêm cạnh cuối cùng vào đối tượng quy trình công việc để đóng.

# Always go from write_file to end.
workflow.add_edge("write_file", END)

Thực hiện quy trình làm việc

Việc cuối cùng còn lại là biên dịch quy trình làm việc và chạy nó.

# Create the app and run it
app = workflow.compile()
inputs = {}
config = RunnableConfig(recursion_limit=100)
try:
    result = app.invoke(inputs, config)
    print(result)
except GraphRecursionError:
    print("Graph recursion limit reached.")

Điều này sẽ gọi ứng dụng. Giới hạn đệ quy là số lần LLM sẽ được suy ra cho một quy trình công việc nhất định. Quy trình làm việc dừng lại khi vượt quá giới hạn.

Bạn có thể xem nhật ký trên thiết bị đầu cuối hoặc trong sổ ghi chép. Đây là nhật ký thực thi của một ứng dụng CRUD đơn giản.

chuỗi lang

Mô hình cơ bản sẽ thực hiện rất nhiều công việc nặng nhọc, đây là ứng dụng demo với mô hình bộ mã hóa Deepseek, để có hiệu suất tốt hơn, bạn có thể sử dụng GPT-4 hoặc Claude Opus, haiku, v.v.

 Bạn cũng có thể sử dụng các công cụ Langchain để lướt web, phân tích giá cổ phiếu, v.v.

LangChain và LangGraph

Bây giờ, câu hỏi đặt ra là khi nào nên sử dụng LangChain và LangGraph.

Nếu mục tiêu là tạo ra một hệ thống đa tác nhân với sự phối hợp giữa chúng thì LangGraph là lựa chọn phù hợp. Tuy nhiên, nếu bạn muốn tạo DAG hoặc chuỗi để hoàn thành nhiệm vụ thì Ngôn ngữ biểu thức LangChain là phù hợp nhất.

Tại sao nên sử dụng LangGraph?

LangGraph là một framework mạnh mẽ có thể cải thiện nhiều giải pháp hiện có. 

  • Cải thiện đường ống RAG: LangGraph có thể tăng cường RAG bằng cấu trúc đồ thị tuần hoàn của nó. Chúng tôi có thể giới thiệu một vòng phản hồi để đánh giá chất lượng của đối tượng được truy xuất và nếu cần, có thể cải thiện truy vấn và lặp lại quy trình.
  • Quy trình làm việc đa tác nhân: LangGraph được thiết kế để hỗ trợ quy trình làm việc của nhiều tác nhân. Điều này rất quan trọng để giải quyết các nhiệm vụ phức tạp được chia thành các nhiệm vụ phụ nhỏ hơn. Các tác nhân khác nhau có trạng thái chia sẻ cũng như các LLM và công cụ khác nhau có thể cộng tác để giải quyết một nhiệm vụ duy nhất.
  • Con người trong vòng lặp: LangGraph có hỗ trợ tích hợp cho quy trình làm việc của Con người trong vòng lặp. Điều này có nghĩa là con người có thể xem lại các trạng thái trước khi chuyển sang nút tiếp theo.
  • Đại lý quy hoạch: LangGraph rất phù hợp để xây dựng các tác nhân lập kế hoạch, trong đó người lập kế hoạch LLM lập kế hoạch và phân tách yêu cầu của người dùng, người thực thi gọi các công cụ và chức năng và LLM tổng hợp các câu trả lời dựa trên kết quả đầu ra trước đó.
  • Đại lý đa phương thức: LangGraph có thể xây dựng các tác nhân đa phương thức, như hỗ trợ tầm nhìn điều hướng web.

Các trường hợp sử dụng thực tế

Có rất nhiều lĩnh vực mà các tác nhân mã hóa AI phức tạp có thể hữu ích. 

  1. Đại lý cá nhâns: Hãy tưởng tượng có trợ lý giống Jarvis của riêng bạn trên các thiết bị điện tử, sẵn sàng trợ giúp thực hiện các nhiệm vụ theo lệnh của bạn, cho dù đó là thông qua văn bản, giọng nói hay thậm chí là cử chỉ. Đó là một trong những ứng dụng thú vị nhất của tác nhân AI!
  2. Giảng viên AI: Chatbot rất tuyệt nhưng chúng cũng có giới hạn. Các tác nhân AI được trang bị các công cụ phù hợp có thể vượt xa các cuộc trò chuyện cơ bản. Những người hướng dẫn AI ảo có thể điều chỉnh phương pháp giảng dạy của họ dựa trên phản hồi của người dùng có thể thay đổi cuộc chơi.
  3. Trải nghiệm người dùng phần mềm: Trải nghiệm người dùng phần mềm có thể được cải thiện nhờ các tác nhân AI. Thay vì điều hướng các ứng dụng theo cách thủ công, các tổng đài viên có thể hoàn thành nhiệm vụ bằng lệnh thoại hoặc cử chỉ.
  4. Máy tính không gian: Khi công nghệ AR/VR ngày càng phổ biến, nhu cầu về các tác nhân AI sẽ tăng lên. Các tác nhân có thể xử lý thông tin xung quanh và thực hiện các nhiệm vụ theo yêu cầu. Đây có thể là một trong những trường hợp sử dụng tốt nhất của tác nhân AI trong thời gian ngắn.
  5. Hệ điều hành LLM: Hệ điều hành AI đầu tiên nơi các đại lý là công dân hạng nhất. Đại lý sẽ chịu trách nhiệm thực hiện các nhiệm vụ từ đơn giản đến phức tạp.

Kết luận

LangGraph là một khuôn khổ hiệu quả để xây dựng các hệ thống tác nhân đa tác nhân có trạng thái tuần hoàn. Nó lấp đầy khoảng trống trong khung LangChain ban đầu. Vì đây là phần mở rộng của LangChain nên chúng ta có thể hưởng lợi từ tất cả những điều tốt đẹp của hệ sinh thái LangChain. Khi chất lượng và khả năng của LLM tăng lên, việc tạo ra các hệ thống đại lý để tự động hóa các quy trình công việc phức tạp sẽ dễ dàng hơn nhiều. Vì vậy, đây là những điểm chính rút ra từ bài viết. 

Chìa khóa chính

  • LangGraph là một phần mở rộng của LangChain, cho phép chúng tôi xây dựng các hệ thống tác nhân đa tác nhân, có trạng thái, theo chu kỳ.
  • Nó thực hiện một cấu trúc đồ thị với các nút và các cạnh. Các nút là các chức năng hoặc công cụ và các cạnh là các kết nối giữa các nút.
  • Các cạnh có hai loại: có điều kiện và bình thường. Các cạnh có điều kiện có các điều kiện khi đi từ cạnh này sang cạnh khác, điều này rất quan trọng để thêm tính chu kỳ vào quy trình làm việc.
  • LangGraph được ưa thích để xây dựng các tác nhân đa tác nhân theo chu kỳ, trong khi LangChain tốt hơn trong việc tạo chuỗi hoặc hệ thống định hướng theo chu kỳ.

Những câu hỏi thường gặp

Q1. LangGraph là gì?

Trả lời. LangGraph là một thư viện mã nguồn mở để xây dựng các hệ thống tác nhân đa tác nhân có trạng thái tuần hoàn. Nó được xây dựng trên hệ sinh thái LangChain.

Q2. Khi nào nên sử dụng LangGraph thay vì LangChain?

Trả lời. LangGraph được ưa thích để xây dựng các tác nhân đa tác nhân theo chu kỳ, trong khi LangChain tốt hơn trong việc tạo chuỗi hoặc hệ thống định hướng theo chu kỳ.

Q3. Đặc vụ AI là gì?

Trả lời. Tác nhân AI là các chương trình phần mềm tương tác với môi trường của chúng, đưa ra quyết định và hành động để đạt được mục tiêu cuối cùng.

Q4. LLM tốt nhất để sử dụng với các tác nhân AI là gì?

Trả lời. Điều này phụ thuộc vào trường hợp sử dụng và ngân sách của bạn. GPT 4 có khả năng cao nhất nhưng đắt tiền. Để mã hóa, DeepSeekCoder-33b là một lựa chọn rẻ hơn rất nhiều. 

Q5. Sự khác biệt giữa chuỗi và đại lý là gì?

Trả lời. Chuỗi là một chuỗi các hành động được mã hóa cứng để tuân theo, trong khi các đại lý sử dụng LLM và các công cụ khác (cũng là chuỗi) để suy luận và hành động theo thông tin.

Phương tiện hiển thị trong bài viết này không thuộc sở hữu của Analytics Vidhya và được sử dụng theo quyết định riêng của Tác giả.

tại chỗ_img

Tin tức mới nhất

tại chỗ_img