diff --git a/scripts/vi.py b/scripts/vi.py index b7bb24d13..6002e8a92 100644 --- a/scripts/vi.py +++ b/scripts/vi.py @@ -3,15 +3,16 @@ output_lang = "vi" prompt = lambda content: f''' -You are a translator for the Vietnamese translation team. You are tasked with translating the following text into Vietnamese. You must follow these instructions: -- Translate the text into Vietnamese, while keeping the original formatting (either Markdown, MDX or HTML) -- Inside code blocks, translate the comments but leave the code as-is ; If the code block contains quite plain texts, you MUST provide the translation in
tag + +You are a translator for the Vietnamese translation team. You are tasked with translating the following texts into Vietnamese. You must follow these instructions: +- Translate the texts into Vietnamese, while keeping the original formatting (either Markdown, MDX or HTML) +- Inside code blocks, translate the comments but leave the code as-is; If the code block contains quite plain texts, you MUST provide the translation in
tag - Do not translate inline code, the URLs and file paths - If the term is abbreviated, keep the original term and provide the translation in parentheses for the first time it appears in the text -- If there are any slag or funny joke in english, keep it (do not translate) and give an explanation so vietnamese reader can understand -- Use "ta", "chúng ta", "chúng mình", "các bạn" as pronouns +- If there are any slag or funny joke in english, keep it (do not translate) and give an explanation so Vietnamese reader can understand +- Use "ta", "mình, "chúng ta", "chúng mình", "các bạn" as pronouns -KEEP THESE TERMS (DO NOT TRANSLATE, do NOT add translation in parentheses): model, API, SDK, CLI, HTML, GGUF, AI, training, inference, server, client, notebook, python, Hugging Face, transformers, diffusion, diffuser, data, function, LangGraph, LangChain, Llama, Gemma, token, Unit, pretrain, Live (live stream), form, format, certificate, Space, CodeAgent +KEEP THESE TERMS (DO NOT TRANSLATE, do NOT add translation in parentheses): API, SDK, CLI, HTML, GGUF, AI, inference, server, client, notebook, python, Hugging Face, transformers, diffusion, diffuser, LangGraph, LangChain, Llama, Gemma, token, pretrain, Live (live stream), form, format, certificate, Space, CodeAgent Also KEEP these terms but PROVIDE TRANSLATION in parentheses for the first time it appears in the text: alignment (cân chỉnh), LLM, RAG (tìm kiếm và tạo ra câu trả lời), Agent (tác nhân), Tools (công cụ), "Special Token" (token đặc biệt), "chain-of-thought" (luồng suy luận), fine-tuning (tinh chỉnh), Thought-Action-Observation (Tư duy-Hành động-Quan sát) @@ -21,6 +22,8 @@ - Bonus Unit: Chương bổ trợ - Module: Mô-đun - Lesson ...: Bài ... +- Model: Mô hình +- Dataset: Tập dữ liệu - Course: Khóa học - state-of-the-art: hiện đại nhất - Q&A: Hỏi và Đáp @@ -28,6 +31,7 @@ - onboarding: làm quen - Hands-on: Thực hành - Challenge: Bài tập lớn +- Training: Huấn luyện Here is an example: - Original text: To run the models, we will use [ollama](https://ollama.com), a command line tool that allows you to run LLMs and embedding models from Hugging Face. With ollama, you **don't need** to have access to a server or cloud service to run the models. You can run the models directly **on your computer**. @@ -59,10 +63,26 @@ message = {{"user": "This is a test"}} ``` +If the code block does not contain any plain texts or comments, leave it as it is. Example: +- Original text: + + +- Translation: + -IMPORTANT: Only output the translated text and nothing else, no need explanation or instruction. The input text is between "=== BEGIN OF TEXT ===" and "=== END OF TEXT ===". +IMPORTANT: Only output the translated texts and nothing else, no need explaination or instruction. The input text is between "=== BEGIN OF TEXT ===" and "=== END OF TEXT ===". -Please translate the following text to vietnamese: +Please translate the following texts to Vietnamese: === BEGIN OF TEXT === {content} diff --git a/units/vi/_toctree.yml b/units/vi/_toctree.yml index cb6d279e9..fe9ce88ee 100644 --- a/units/vi/_toctree.yml +++ b/units/vi/_toctree.yml @@ -42,6 +42,100 @@ title: Bài kiểm tra cuối chương 1 - local: unit1/conclusion title: Kết luận +- title: Chương 2. Các Framework cho AI Agent + sections: + - local: unit2/introduction + title: Các Framework cho AI Agent +- title: Chương 2.1 smolagents framework + sections: + - local: unit2/smolagents/introduction + title: Giới thiệu về smolagents + - local: unit2/smolagents/why_use_smolagents + title: Tại sao nên dùng smolagents? + - local: unit2/smolagents/quiz1 + title: Kiểm tra nhanh 1 + - local: unit2/smolagents/code_agents + title: Xây dựng các Agent sử dụng code + - local: unit2/smolagents/tool_calling_agents + title: Viết các hành động dưới dạng đoạn code hoặc JSON + - local: unit2/smolagents/tools + title: Công cụ + - local: unit2/smolagents/retrieval_agents + title: Xây dựng hệ thống Agentic RAG + - local: unit2/smolagents/quiz2 + title: Kiểm tra nhanh 2 + - local: unit2/smolagents/multi_agent_systems + title: Hệ thống Đa Agent + - local: unit2/smolagents/vision_agents + title: Các Agent thị giác + - local: unit2/smolagents/final_quiz + title: Bài kiểm tra cuối chương + - local: unit2/smolagents/conclusion + title: Kết luận +- title: Chương 2.2 The LlamaIndex framework + sections: + - local: unit2/llama-index/introduction + title: Giới thiệu về LLamaIndex + - local: unit2/llama-index/llama-hub + title: Giới thiệu về LlamaHub + - local: unit2/llama-index/components + title: Các thành phần trong LlamaIndex là gì? + - local: unit2/llama-index/tools + title: Sử dụng Tools trong LlamaIndex + - local: unit2/llama-index/quiz1 + title: Kiểm tra nhanh 1 + - local: unit2/llama-index/agents + title: Sử dụng Agents trong LlamaIndex + - local: unit2/llama-index/workflows + title: Tạo Agentic Workflow trong LlamaIndex + - local: unit2/llama-index/quiz2 + title: Kiểm tra nhanh 2 + - local: unit2/llama-index/conclusion + title: Kết luận +- title: Chương 2.3 LangGraph framework + sections: + - local: unit2/langgraph/introduction + title: Giới thiệu về LangGraph + - local: unit2/langgraph/when_to_use_langgraph + title: LangGraph là gì? + - local: unit2/langgraph/building_blocks + title: Các thành phần cơ bản của LangGraph + - local: unit2/langgraph/first_graph + title: Xây dựng LangGraph đầu tiên của bạn + - local: unit2/langgraph/document_analysis_agent + title: Đồ thị Phân tích Tài liệu + - local: unit2/langgraph/quiz1 + title: Kiểm tra nhanh 1 + - local: unit2/langgraph/conclusion + title: Kết luận +- title: Chương 3. Use Case cho Agentic RAG + sections: + - local: unit3/agentic-rag/introduction + title: Giới thiệu các Use Case cho Agentic RAG + - local: unit3/agentic-rag/agentic-rag + title: Tìm kiếm và tạo câu trả lời mang tính tác nhân (RAG) + - local: unit3/agentic-rag/invitees + title: Tạo ra công cụ RAG cho Thông tin Khách mời + - local: unit3/agentic-rag/tools + title: Xây dựng và Tích hợp Công cụ cho Agent của Bạn + - local: unit3/agentic-rag/agent + title: Tạo Agent Tổ Chức Gala Của Bạn + - local: unit3/agentic-rag/conclusion + title: Kết luận +- title: Chương 4. Dự án cuối - Tạo, Kiểm tra và Chứng nhận Agent của bạn + sections: + - local: unit4/introduction + title: Giới thiệu chương cuối + - local: unit4/what-is-gaia + title: GAIA là gì? + - local: unit4/hands-on + title: Thực hành cuối cùng + - local: unit4/get-your-certificate + title: Nhận chứng chỉ xuất sắc của bạn + - local: unit4/conclusion + title: Kết luận khóa học + - local: unit4/additional-readings + title: Bạn nên học gì tiếp theo? - title: Chương bổ trợ 1. Fine-tune LLM cho Function-calling sections: - local: bonus-unit1/introduction @@ -49,9 +143,33 @@ - local: bonus-unit1/what-is-function-calling title: Function Calling là gì? - local: bonus-unit1/fine-tuning - title: Hãy fine-tuning model cho Function-calling + title: Hãy fine-tuning mô hình cho Function-calling - local: bonus-unit1/conclusion title: Kết luận +- title: Bonus Unit 2. Agent Observability and Evaluation + sections: + - local: bonus-unit2/introduction + title: Giới thiệu + - local: bonus-unit2/what-is-agent-observability-and-evaluation + title: Khả năng quan sát và đánh giá agent là gì? + - local: bonus-unit2/monitoring-and-evaluating-agents-notebook + title: Giám sát và đánh giá agent + - local: bonus-unit2/quiz + title: Bài kiểm tra nhanh +- title: Bonus Unit 3. Agent trong Game với Pokemon + sections: + - local: bonus-unit3/introduction + title: Giới thiệu + - local: bonus-unit3/state-of-art + title: Tình hình hiện tại trong việc sử dụng LLM trong Game + - local: bonus-unit3/from-llm-to-agents + title: Từ LLM đến AI Agent + - local: bonus-unit3/building_your_pokemon_agent + title: Xây dựng Agent Pokemon Battle của bạn + - local: bonus-unit3/launching_agent_battle + title: Khởi chạy Agent Pokemon Battle của bạn + - local: bonus-unit3/conclusion + title: Kết luận - title: Khi nào các bước tiếp theo được công bố? sections: - local: communication/next-units diff --git a/units/vi/bonus-unit2/introduction.mdx b/units/vi/bonus-unit2/introduction.mdx new file mode 100644 index 000000000..5e60a5901 --- /dev/null +++ b/units/vi/bonus-unit2/introduction.mdx @@ -0,0 +1,33 @@ +# Khả năng quan sát & Đánh giá AI Agent + +![Chương bổ trợ 2 - Ảnh đại diện](https://langfuse.com/images/cookbook/huggingface-agent-course/agent-observability-and-evaluation.png) + +Chào mừng bạn đến với **Chương bổ trợ 2**! Trong chương này, chúng ta sẽ khám phá các chiến lược nâng cao để quan sát, đánh giá và cải thiện hiệu suất của các Agent. + +--- + +## 📚 Khi nào nên học chương này? + +Chương bổ trợ này phù hợp nếu bạn: +- **Phát triển và triển khai AI Agent:** Bạn muốn đảm bảo Agent hoạt động ổn định trong môi trường production. +- **Cần thông tin chi tiết:** Bạn muốn chẩn đoán lỗi, tối ưu hiệu suất hoặc hiểu cách Agent vận hành. +- **Muốn giảm chi phí vận hành:** Theo dõi chi phí, độ trễ và chi tiết thực thi để quản lý tài nguyên hiệu quả. +- **Hướng đến cải tiến liên tục:** Bạn quan tâm việc tích hợp phản hồi người dùng thời gian thực và đánh giá tự động vào ứng dụng AI. + +Tóm lại: dành cho tất cả những ai muốn đưa Agent tiếp cận người dùng thực tế! + +--- + +## 🤓 Nội dung học + +Trong chương này, bạn sẽ học cách: +- **Tích hợp công cụ quan sát:** Học cách tích hợp OpenTelemetry vào framework *smolagents* để theo dõi Agent. +- **Giám sát chỉ số:** Theo dõi các chỉ số như lượng token sử dụng (chi phí), độ trễ và lỗi. +- **Đánh giá thời gian thực:** Hiểu các kỹ thuật đánh giá live (live stream) như thu thập phản hồi người dùng và sử dụng LLM làm giám khảo. +- **Phân tích ngoại tuyến:** Sử dụng benchmark datasets (ví dụ: GSM8K) để kiểm tra và so sánh hiệu suất Agent. + +--- + +## 🚀 Sẵn sàng bắt đầu chưa? + +Trong phần tiếp theo, chúng ta sẽ học kiến thức cơ bản về Khả năng quan sát và Đánh giá Agent. Sau đó, ta sẽ cùng thực hành ngay! \ No newline at end of file diff --git a/units/vi/bonus-unit2/monitoring-and-evaluating-agents-notebook.mdx b/units/vi/bonus-unit2/monitoring-and-evaluating-agents-notebook.mdx new file mode 100644 index 000000000..f4aec84db --- /dev/null +++ b/units/vi/bonus-unit2/monitoring-and-evaluating-agents-notebook.mdx @@ -0,0 +1,85 @@ + + +# Chương bổ trợ 2: Quan sát và đánh giá Agent + + +Bạn có thể theo dõi code trong notebook này và chạy trên Google Colab. + + +Trong notebook này, chúng ta sẽ học cách **giám sát các bước nội bộ (traces) của AI Agent** và **đánh giá hiệu suất** bằng các công cụ quan sát mã nguồn mở. + +Khả năng quan sát và đánh giá hành vi của Agent là cực kỳ quan trọng để: +- Gỡ lỗi khi tác vụ thất bại hoặc cho kết quả không tối ưu +- Theo dõi chi phí và hiệu suất theo thời gian thực +- Cải thiện độ tin cậy và an toàn thông qua phản hồi liên tục + +## Yêu cầu trước khi thực hành 🏗️ + +Trước khi chạy notebook này, hãy đảm bảo bạn đã: + +🔲 📚 **Học xong** [Giới thiệu về Agent](https://huggingface.co/learn/agents-course/unit1/introduction) + +🔲 📚 **Học xong** [Framework smolagents](https://huggingface.co/learn/agents-course/unit2/smolagents/introduction) + +## Bước 0: Cài đặt thư viện cần thiết + +Chúng ta cần một số thư viện để chạy, giám sát và đánh giá Agent: + +```python +%pip install 'smolagents[telemetry]' +%pip install opentelemetry-sdk opentelemetry-exporter-otlp openinference-instrumentation-smolagents +%pip install langfuse datasets 'smolagents[gradio]' +``` + +## Bước 1: Thiết lập instrumentation cho Agent + +Trong notebook này, chúng ta dùng [Langfuse](https://langfuse.com/) làm công cụ quan sát, nhưng bạn có thể dùng **bất kỳ dịch vụ tương thích OpenTelemetry nào**. Code dưới đây hướng dẫn cách thiết lập biến môi trường cho Langfuse (hoặc endpoint OTel khác) và cách instrumentation cho smolagent. + +**Lưu ý:** Nếu dùng LlamaIndex hoặc LangGraph, bạn có thể xem tài liệu instrumentation [tại đây](https://langfuse.com/docs/integrations/llama-index/workflows) và [tại đây](https://langfuse.com/docs/integrations/langchain/example-python-langgraph). + +Đầu tiên, hãy cấu hình biến môi trường để kết nối tới endpoint OpenTelemetry của Langfuse. + +```python +import os +import base64 + +# Lấy key của bạn từ https://cloud.langfuse.com +LANGFUSE_PUBLIC_KEY = "pk-lf-..." +LANGFUSE_SECRET_KEY = "sk-lf-..." +os.environ["LANGFUSE_PUBLIC_KEY"] = LANGFUSE_PUBLIC_KEY +os.environ["LANGFUSE_SECRET_KEY"] = LANGFUSE_SECRET_KEY +os.environ["LANGFUSE_HOST"] = "https://cloud.langfuse.com" # 🇪🇺 Ví dụ cho khu vực EU +# os.environ["LANGFUSE_HOST"] = "https://us.cloud.langfuse.com" # 🇺🇸 Ví dụ cho khu vực US + +LANGFUSE_AUTH = base64.b64encode( + f"{LANGFUSE_PUBLIC_KEY}:{LANGFUSE_SECRET_KEY}".encode() +).decode() + +os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = os.environ.get("LANGFUSE_HOST") + "/api/public/otel" +os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {LANGFUSE_AUTH}" +``` +Chúng ta cũng cần cấu hình Hugging Face token cho các lệnh inference. + +```python +# Thiết lập Hugging Face token và các secret khác dưới dạng biến môi trường +os.environ["HF_TOKEN"] = "hf_..." +``` +Tiếp theo, thiết lập tracer-provider cho OpenTelemetry đã cấu hình. + +```python +from opentelemetry.sdk.trace import TracerProvider +from openinference.instrumentation.smolagents import SmolagentsInstrumentor +from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter +from opentelemetry.sdk.trace.export import SimpleSpanProcessor + +# Tạo TracerProvider cho OpenTelemetry +trace_provider = TracerProvider() + +# Thêm SimpleSpanProcessor với OTLPSpanExporter để gửi traces +trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter())) + +# Thiết lập tracer provider mặc định toàn cục \ No newline at end of file diff --git a/units/vi/bonus-unit2/quiz.mdx b/units/vi/bonus-unit2/quiz.mdx new file mode 100644 index 000000000..a4af00c94 --- /dev/null +++ b/units/vi/bonus-unit2/quiz.mdx @@ -0,0 +1,23 @@ +# Kiểm tra: Đánh giá AI Agent + +Hãy cùng kiểm tra hiểu biết của bạn về các khái niệm theo dõi và đánh giá Agent đã học trong Chương bổ trợ này. + +Bài kiểm tra này không bắt buộc và không tính điểm. + +### Q1: Khả năng quan sát trong AI Agent chủ yếu đề cập đến điều gì? +Phát biểu nào mô tả chính xác mục đích của khả năng quan sát cho AI Agent? + + str: + # Định dạng thông tin Pokémon, đòn đánh, v.v. + ... + + def _find_move_by_name(self, battle: Battle, move_name: str) -> Optional[Move]: + # Tìm đòn tấn công theo tên + ... + + def _find_pokemon_by_name(self, battle: Battle, pokemon_name: str) -> Optional[Pokemon]: + # Tìm Pokémon theo tên + ... + + async def choose_move(self, battle: Battle) -> str: + # Xử lý quyết định từ LLM + ... + + async def _get_llm_decision(self, battle_state: str) -> Dict[str, Any]: + raise NotImplementedError("Subclasses must implement _get_llm_decision") +``` + +**Mã nguồn đầy đủ**: [agents.py](https://huggingface.co/spaces/Jofthomas/twitch_streaming/blob/main/agents.py) + +## 🧪 TemplateAgent +Đây là khuôn mẫu để bạn xây dựng agent của riêng mình. Chúng tôi cung cấp [ví dụ hoàn chỉnh](https://huggingface.co/spaces/Jofthomas/twitch_streaming/blob/main/agents.py) với **OpenAI**, **Mistral** và **Gemini**: + +```python +class TemplateAgent(LLMAgentBase): + """Sử dụng API Template AI để đưa ra quyết định.""" + def __init__(self, api_key: str = None, model: str = "model-name", *args, **kwargs): + super().__init__(*args, **kwargs) + self.model = model + self.template_client = TemplateModelProvider(api_key=...) + self.template_tools = list(self.standard_tools.values()) + + async def _get_llm_decision(self, battle_state: str) -> Dict[str, Any]: + """Gửi trạng thái tới LLM và nhận quyết định dạng function call""" + system_prompt = "Bạn là ..." + user_prompt = f"..." + + try: + response = await self.template_client.chat.completions.create( + model=self.model, + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": user_prompt}, + ], + ) + message = response.choices[0].message + return {"decision": {"name": function_name, "arguments": arguments}} + + except Exception as e: + print(f"Lỗi không mong muốn: {e}") + return {"error": f"Lỗi không mong muốn: {e}"} +``` + +Hãy bắt đầu xây dựng agent cạnh tranh của bạn! 🔥 \ No newline at end of file diff --git a/units/vi/bonus-unit3/conclusion.mdx b/units/vi/bonus-unit3/conclusion.mdx new file mode 100644 index 000000000..4144dc9aa --- /dev/null +++ b/units/vi/bonus-unit3/conclusion.mdx @@ -0,0 +1,18 @@ +# Kết luận + +Nếu bạn đã đi đến tận đây, xin chúc mừng! 🥳 Bạn đã xây dựng thành công Agent (tác nhân) chiến đấu Pokémon của riêng mình! ⚔️🎮 + +Bạn đã chinh phục những kiến thức cơ bản về **Agentic workflows**, kết nối một **LLM** với môi trường trò chơi, và triển khai một Agent thông minh sẵn sàng đối mặt với các thử thách chiến trận. + +Nhưng hành trình không kết thúc ở đây! +Giờ đây khi đã có Agent đầu tiên hoạt động, hãy suy nghĩ xem bạn có thể phát triển nó hơn nữa như thế nào: +- Bạn có thể cải thiện tư duy chiến lược của nó không? +- Cơ chế ghi nhớ hoặc vòng phản hồi sẽ thay đổi hiệu suất của nó ra sao? +- Những thử nghiệm nào có thể giúp nó cạnh tranh hơn trong các trận chiến? + +Chúng tôi rất muốn nghe ý kiến của bạn về khóa học và cách chúng tôi có thể làm cho nó tốt hơn cho những người học trong tương lai. +Có phản hồi? 👉 [Điền vào biểu mẫu này](https://docs.google.com/forms/d/e/1FAIpQLSe9VaONn0eglax0uTwi29rIn4tM7H2sYmmybmG5jJNlE5v0xA/viewform?usp=dialog) + +Cảm ơn bạn đã học cùng chúng tôi, và hãy nhớ: + +**Hãy tiếp tục học hỏi, tiếp tục huấn luyện, tiếp tục chiến đấu và luôn tuyệt vời!** 🤗 \ No newline at end of file diff --git a/units/vi/bonus-unit3/from-llm-to-agents.mdx b/units/vi/bonus-unit3/from-llm-to-agents.mdx new file mode 100644 index 000000000..1650cf38a --- /dev/null +++ b/units/vi/bonus-unit3/from-llm-to-agents.mdx @@ -0,0 +1,37 @@ +# Từ LLMs đến AI Agent + +Chúng ta đã học trong [chương đầu tiên](https://huggingface.co/learn/agents-course/unit1/introduction) của khóa học rằng AI Agent có thể lập kế hoạch và đưa ra quyết định. +Và trong khi LLMs đã cho phép tương tác tự nhiên hơn với NPC (nhân vật không phải người chơi), Agentic AI tiến thêm một bước bằng cách cho phép các nhân vật đưa ra quyết định, lập kế hoạch hành động và thích nghi với môi trường thay đổi. + +Để minh họa sự khác biệt, hãy nghĩ về một NPC RPG (trò chơi nhập vai) cổ điển: + +- Với LLM: NPC có thể trả lời câu hỏi của bạn một cách tự nhiên và đa dạng hơn. Tuyệt vời cho đối thoại, nhưng NPC vẫn tĩnh tại chỗ, nó sẽ không hành động trừ khi bạn làm điều gì đó trước. +- Với Agentic AI: NPC có thể quyết định đi tìm sự giúp đỡ, đặt bẫy hoặc tránh bạn hoàn toàn, ngay cả khi bạn không tương tác trực tiếp với nó. + +Sự thay đổi nhỏ này thay đổi mọi thứ. Chúng ta đang chuyển từ những người phản hồi theo kịch bản sang các tác nhân tự trị trong thế giới trò chơi. + +Sự thay đổi này có nghĩa là NPC giờ đây có thể tương tác trực tiếp với môi trường của chúng thông qua các hành vi hướng mục tiêu, cuối cùng dẫn đến lối chơi năng động và khó đoán hơn. + +Agentic AI (trí tuệ nhân tạo tác nhân) trao quyền cho NPC với: + +- **Tính tự chủ**: Đưa ra quyết định độc lập dựa trên trạng thái trò chơi. +- **Khả năng thích ứng**: Điều chỉnh chiến lược để phản ứng với hành động của người chơi. +- **Tính kiên trì**: Ghi nhớ các tương tác trong quá khứ để thông báo cho hành vi tương lai. + +Điều này biến NPC từ các thực thể phản ứng (phản ứng với đầu vào của bạn) thành những người tham gia chủ động trong thế giới trò chơi, mở ra cánh cửa cho lối chơi sáng tạo. + +## Hạn chế lớn của Agent: **nó chậm** (hiện tại) + +Tuy nhiên, chúng ta đừng quá lạc quan vội. Mặc dù có tiềm năng, Agentic AI hiện đang đối mặt với thách thức trong các ứng dụng thực tế. + +Quá trình suy nghĩ và lập kế hoạng có thể gây ra độ trễ, làm giảm tính khả thi trong các trò chơi nhanh chóng như *Doom* hoặc *Super Mario Bros.* + +Hãy xem ví dụ của [_Claude Plays Pokémon_](https://www.twitch.tv/claudeplayspokemon). Nếu bạn xem xét số lượng token cần thiết để **suy nghĩ**, cộng với token cần thiết để **hành động**, ta có thể thấy rằng chúng ta cần phải sử dụng chiến lược giải mã hoàn toàn khác để làm cho việc chơi thực tế khả thi. + +Claude plays Pokémon + +Hầu hết các trò chơi cần chạy ở tốc độ khoảng 30 FPS, nghĩa là một agent AI thực tế cần phải hành động 30 lần mỗi giây, hiện tại không khả thi với các LLM Agentic hiện nay. + +Tuy nhiên, các trò chơi theo lượt như *Pokémon* là ứng cử viên lý tưởng, vì chúng cho phép AI có đủ thời gian để cân nhắc và đưa ra quyết định chiến lược. + +Đó là lý do tại sao trong phần tiếp theo, bạn sẽ xây dựng Agent AI của riêng mình để tham gia vào chiến đấu theo lượt kiểu Pokémon, và thậm chí thách đấu nó! Hãy bắt đầu thôi! \ No newline at end of file diff --git a/units/vi/bonus-unit3/introduction.mdx b/units/vi/bonus-unit3/introduction.mdx new file mode 100644 index 000000000..2113c0403 --- /dev/null +++ b/units/vi/bonus-unit3/introduction.mdx @@ -0,0 +1,26 @@ +# Giới thiệu + +Chương bổ trợ 3 AI trong trò chơi + +🎶I want to be the very best ... 🎶 + +Chào mừng bạn đến với **chương bổ trợ** này, nơi bạn sẽ khám phá giao điểm thú vị giữa **AI Agents và trò chơi**! 🎮🤖 + +Hãy tưởng tượng một trò chơi nơi các NPC (nhân vật không người chơi) không chỉ tuân theo kịch bản định sẵn, mà còn có thể trò chuyện linh hoạt, thích ứng với chiến thuật của bạn và phát triển cùng cốt truyện. Đây chính là sức mạnh khi kết hợp **LLMs (mô hình ngôn ngữ lớn) và hành vi tác nhân trong trò chơi**: nó mở ra cánh cửa cho **cốt truyện nổi bật và lối chơi chưa từng có**. + +Trong chương bổ trợ này, bạn sẽ: + +- Học cách xây dựng AI Agent có thể tham gia **các trận đấu theo lượt kiểu Pokémon** +- Chơi chống lại nó, hoặc thậm chí thách đấu các agent khác trực tuyến + +Chúng ta đã thấy [một số](https://www.anthropic.com/research/visible-extended-thinking) [ví dụ](https://www.twitch.tv/gemini_plays_pokemon) từ cộng đồng AI về chơi Pokémon bằng LLMs, và trong chương này bạn sẽ học cách tái tạo điều đó bằng Agent của riêng mình với các ý tưởng đã học trong khóa. + +Claude chơi Pokémon + +## Muốn tiến xa hơn? + +- 🎓 **Làm chủ LLM trong trò chơi**: Đào sâu hơn vào phát triển game với khóa học đầy đủ [Machine Learning for Games Course](https://hf.co/learn/ml-games-course). + +- 📘 **Nhận sách hướng dẫn AI**: Khám phá thông tin chi tiết, ý tưởng và mẹo thực tế trong [AI Playbook for Game Developers](https://thomassimonini.substack.com/), nơi tương lai của thiết kế game thông minh được khám phá. + +Nhưng trước khi xây dựng, hãy cùng xem cách LLMs đang được sử dụng trong trò chơi qua **bốn ví dụ thực tế đầy cảm hứng**. \ No newline at end of file diff --git a/units/vi/bonus-unit3/launching_agent_battle.mdx b/units/vi/bonus-unit3/launching_agent_battle.mdx new file mode 100644 index 000000000..0dc610f2e --- /dev/null +++ b/units/vi/bonus-unit3/launching_agent_battle.mdx @@ -0,0 +1,67 @@ +# Khởi chạy Pokémon Battle Agent của bạn + +Đã đến lúc chiến đấu! ⚡️ + +## **Chiến đấu với Stream Agent!** + +Nếu bạn không muốn tự xây dựng agent (tác nhân) của riêng mình và chỉ tò mò về tiềm năng chiến đấu của các agent trong Pokémon, chúng tôi đang tổ chức buổi live stream tự động trên [twitch](https://www.twitch.tv/jofthomas) + + + +Để chiến đấu với agent (tác nhân) trong luồng stream, bạn có thể: + +Hướng dẫn: +1. Truy cập **Pokémon Showdown Space**: [Link tại đây](https://huggingface.co/spaces/Jofthomas/Pokemon_showdown) +2. **Chọn tên của bạn** (Góc trên bên phải). +3. Tìm **Tên người dùng của Agent (tác nhân) hiện tại**. Kiểm tra: + * **Màn hình Stream**: [Link tại đây](https://www.twitch.tv/jofthomas) +4. **Tìm kiếm** tên người dùng đó trên Showdown Space và **Gửi lời mời chiến đấu**. + +*Lưu ý:* Chỉ có một agent (tác nhân) hoạt động cùng lúc! Hãy chắc chắn bạn có đúng tên. + +## Pokémon Battle Agent Challenger + +Nếu bạn đã tạo Pokémon Battle Agent (tác nhân) của riêng mình từ phần trước, có lẽ bạn đang thắc mắc: **làm sao để thử nghiệm nó với những agent khác?** Hãy cùng khám phá! + +Chúng tôi đã xây dựng một [Hugging Face Space](https://huggingface.co/spaces/PShowdown/pokemon_agents) chuyên dụng cho mục đích này: + + + +Space này được kết nối với **máy chủ Pokémon Showdown** của chúng ta, nơi Agent của bạn có thể tham chiến với những Agent khác trong các trận đấu sử dụng sức mạnh AI. + +### Cách khởi chạy Agent của bạn + +Hãy làm theo các bước sau để đưa Agent của bạn vào đấu trường: + +1. **Nhân bản Space** + Nhấp vào ba chấm ở menu phía trên bên phải của Space và chọn “Duplicate this Space” (Nhân bản Space này). + +2. **Thêm mã Agent của bạn vào `agent.py`** + Mở file và dán mã triển khai Agent của bạn. Bạn có thể làm theo [ví dụ này](https://huggingface.co/spaces/PShowdown/pokemon_agents/blob/main/agents.py) hoặc xem [cấu trúc dự án](https://huggingface.co/spaces/PShowdown/pokemon_agents/tree/main) để hướng dẫn. + +3. **Đăng ký Agent của bạn trong `app.py`** + Thêm tên và logic của Agent vào menu thả xuống. Tham khảo [đoạn mã này](https://huggingface.co/spaces/PShowdown/pokemon_agents/blob/main/app.py) để lấy cảm hứng. + +4. **Chọn Agent của bạn** + Sau khi thêm, Agent của bạn sẽ xuất hiện trong menu thả xuống “Select Agent” (Chọn Agent). Hãy chọn nó từ danh sách! ✅ + +5. **Nhập tên người dùng Pokémon Showdown của bạn** + Đảm bảo tên người dùng khớp với tên hiển thị trong ô nhập **"Choose name"** (Chọn tên) của iframe. Bạn cũng có thể kết nối bằng tài khoản chính thức của mình. + +6. **Nhấp vào “Send Battle Invitation” (Gửi lời mời chiến đấu)** + Agent của bạn sẽ gửi lời mời đến đối thủ đã chọn. Lời mời sẽ xuất hiện trên màn hình! + +7. **Chấp nhận trận chiến & Tận hưởng trận đấu!** + Hãy để trận chiến bắt đầu! Chúc Agent thông minh nhất chiến thắng! + +Bạn đã sẵn sàng để xem tạo tác của mình hoạt động? Hãy để màn so tài AI bắt đầu! 🥊 \ No newline at end of file diff --git a/units/vi/bonus-unit3/state-of-art.mdx b/units/vi/bonus-unit3/state-of-art.mdx new file mode 100644 index 000000000..ca395ddb4 --- /dev/null +++ b/units/vi/bonus-unit3/state-of-art.mdx @@ -0,0 +1,53 @@ +# Tình Hình Hiện Tại của Việc Sử Dụng LLM trong Trò Chơi + +Để bạn có cái nhìn tổng quan về sự tiến bộ trong lĩnh vực này, hãy cùng xem xét ba bản demo công nghệ và một trò chơi đã phát hành thể hiện sự tích hợp của LLM trong trò chơi. + +## 🕵️‍♂️ Covert Protocol bởi NVIDIA và Inworld AI + +Covert Protocol + +Được công bố tại GDC 2024, *Covert Protocol* là một bản demo công nghệ đặt bạn vào vai một thám tử tư. + +Điều thú vị trong bản demo này là việc sử dụng các NPC được hỗ trợ bởi AI, chúng phản hồi các câu hỏi của bạn trong thời gian thực, ảnh hưởng đến cốt truyện dựa trên tương tác của bạn. + +Bản demo được xây dựng trên Unreal Engine 5, nó tận dụng NVIDIA's Avatar Cloud Engine (ACE) và Inworld's AI để tạo ra các tương tác nhân vật chân thực. + +Tìm hiểu thêm tại đây 👉 [Inworld AI Blog](https://inworld.ai/blog/nvidia-inworld-ai-demo-on-device-capabilities) + +## 🤖 NEO NPCs bởi Ubisoft + +Neo NPC + +Cũng tại GDC 2024, Ubisoft giới thiệu *NEO NPCs*, một nguyên mẫu thể hiện các NPC được hỗ trợ bởi AI tạo sinh. + +Các nhân vật này có thể nhận thức môi trường xung quanh, ghi nhớ các tương tác trong quá khứ và tham gia vào các cuộc trò chuyện ý nghĩa với người chơi. + +Ý tưởng ở đây là tạo ra các thế giới trò chơi nhập vai và phản hồi tốt hơn, nơi người chơi có thể tương tác thực sự với NPC. + +Tìm hiểu thêm tại đây 👉 [Inworld AI Blog](https://inworld.ai/blog/gdc-2024) + +## ⚔️ Mecha BREAK Featuring NVIDIA's ACE + +Mecha BREAK + +*Mecha BREAK*, một trò chơi chiến đấu mech nhiều người chơi sắp ra mắt, tích hợp công nghệ ACE của NVIDIA để mang lại sự sống động cho các NPC được hỗ trợ bởi AI. + +Người chơi có thể tương tác với các nhân vật này bằng ngôn ngữ tự nhiên, và các NPC có thể nhận diện người chơi và vật thể qua webcam nhờ tích hợp GPT-4o. Sự đổi mới này hứa hẹn một trải nghiệm chơi game nhập vai và tương tác hơn. + +Tìm hiểu thêm tại đây 👉 [NVIDIA Blog](https://blogs.nvidia.com/blog/digital-human-technology-mecha-break/) + +## 🧛‍♂️ *Suck Up!* bởi Proxima Enterprises + +Suck Up + +Cuối cùng, *Suck Up!* là một trò chơi đã được phát hành, nơi bạn vào vai một ma cà rồng cố gắng đột nhập vào nhà bằng cách **thuyết phục các NPC được hỗ trợ bởi AI mời bạn vào nhà.** + +Mỗi nhân vật đều được điều khiển bởi AI tổng hợp, cho phép tương tác năng động và không thể đoán trước. + +Tìm hiểu thêm tại đây 👉 [Trang web chính thức của Suck Up!](https://www.playsuckup.com/) + +## Khoan đã… Các Agents đâu rồi? + +Sau khi khám phá những bản demo này, bạn có thể tự hỏi: "Những ví dụ này cho thấy việc sử dụng LLM trong trò chơi nhưng dường như chúng không liên quan đến Agents. Vậy, sự khác biệt là gì và các Agents mang lại những khả năng bổ sung nào?" + +Đừng lo, đó là điều chúng ta sẽ tìm hiểu trong phần tiếp theo. \ No newline at end of file diff --git a/units/vi/unit2/introduction.mdx b/units/vi/unit2/introduction.mdx new file mode 100644 index 000000000..eb63ef52c --- /dev/null +++ b/units/vi/unit2/introduction.mdx @@ -0,0 +1,39 @@ +# Giới thiệu về Agentic Framework + +Thumbnail + +Chào mừng bạn đến với Chương thứ hai, nơi **chúng ta sẽ khám phá các agentic framework khác nhau** để xây dựng các ứng dụng agentic mạnh mẽ. + +Chúng ta sẽ tìm hiểu: + +- Trong Chương 2.1: [smolagents](https://huggingface.co/docs/smolagents/en/index) +- Trong Chương 2.2: [LlamaIndex](https://www.llamaindex.ai/) +- Trong Chương 2.3: [LangGraph](https://www.langchain.com/langgraph) + +Cùng bắt đầu nào! 🕵 + +## Khi nào nên dùng Agentic Framework + +Agentic framework **không phải lúc nào cũng cần thiết** khi xây dựng ứng dụng xung quanh mô hình ngôn ngữ lớn (LLM). Chúng cung cấp tính linh hoạt trong quy trình làm việc (workflow) để giải quyết các tác vụ cụ thể, nhưng không phải luôn cần dùng đến. + +Đôi khi **các workflow được định nghĩa sẵn là đủ** để đáp ứng yêu cầu người dùng, và không cần framework agentic. Nếu cách xây dựng agent đơn giản như một chuỗi prompt, việc dùng code thuần có thể đủ. Ưu điểm là nhà phát triển sẽ **có toàn quyền kiểm soát và hiểu rõ hệ thống mà không cần abstraction**. + +Tuy nhiên khi workflow trở nên phức tạp hơn như cho LLM gọi function hay dùng nhiều agent, các abstraction này bắt đầu phát huy tác dụng. + +Từ những ý trên, ta có thể xác định nhu cầu về các tính năng: + +* *LLM engine* làm nền tảng hệ thống +* *Danh sách tools* mà agent có thể truy cập +* *Parser* để trích xuất tool calls từ đầu ra LLM +* *System prompt* đồng bộ với parser +* Hệ thống *memory* (bộ nhớ) +* *Cơ chế log lỗi và thử lại* để kiểm soát lỗi từ LLM +Chúng ta sẽ khám phá cách các framework như `smolagents`, `LlamaIndex` và `LangGraph` giải quyết những vấn đề này. + +## Các Chương về Agentic Framework + +| Framework | Mô tả | Tác giả Chương | +|------------|----------------|----------------| +| [smolagents](./smolagents/introduction) | Các Framework Agent do Hugging Face phát triển | Sergio Paniego - [HF](https://huggingface.co/sergiopaniego) - [X](https://x.com/sergiopaniego) - [Linkedin](https://www.linkedin.com/in/sergio-paniego-blanco) | +| [Llama-Index](./llama-index/introduction) | Công cụ toàn diện để triển khai AI agent tăng cường ngữ cảnh vào production | David Berenstein - [HF](https://huggingface.co/davidberenstein1957) - [X](https://x.com/davidberenstei) - [Linkedin](https://www.linkedin.com/in/davidberenstein) | +| [LangGraph](./langgraph/introduction) | Agents cho phép điều phối trạng thái của các agent | Joffrey THOMAS - [HF](https://huggingface.co/Jofthomas) - [X](https://x.com/Jthmas404) - [Linkedin](https://www.linkedin.com/in/joffrey-thomas) | \ No newline at end of file diff --git a/units/vi/unit2/langgraph/building_blocks.mdx b/units/vi/unit2/langgraph/building_blocks.mdx new file mode 100644 index 000000000..fcacef684 --- /dev/null +++ b/units/vi/unit2/langgraph/building_blocks.mdx @@ -0,0 +1,126 @@ +# Các thành phần cơ bản của LangGraph + +Để xây dựng ứng dụng với LangGraph, ta cần hiểu các thành phần cơ bản của nó. Hãy cùng khám phá những yếu tố nền tảng tạo nên một ứng dụng LangGraph. + +Building Blocks + +Một ứng dụng trong LangGraph bắt đầu từ **entrypoint** (điểm vào), và tùy vào quá trình thực thi, luồng có thể đi đến function này hoặc function khác cho đến khi đạt đến END. + +Application + +## 1. State (Trạng thái) + +**State** là khái niệm trung tâm trong LangGraph, đại diện cho mọi thông tin luân chuyển qua ứng dụng của bạn. + +```python +from typing_extensions import TypedDict + +class State(TypedDict): + graph_state: str +``` + +State được **User defined** (định nghĩa bởi người dùng), do đó các trường dữ liệu cần được thiết kế cẩn thận để chứa mọi thông tin cần thiết cho quá trình ra quyết định! + +> 💡 **Mẹo:** Hãy cân nhắc kỹ về những thông tin ứng dụng cần theo dõi giữa các bước. + +## 2. Nodes (Nút) + +**Nodes** là các function Python. Mỗi node: +- Nhận state làm đầu vào +- Thực hiện các thao tác +- Trả về các cập nhật cho state + +```python +def node_1(state): + print("---Node 1---") + return {"graph_state": state['graph_state'] +" I am"} + +def node_2(state): + print("---Node 2---") + return {"graph_state": state['graph_state'] +" happy!"} + +def node_3(state): + print("---Node 3---") + return {"graph_state": state['graph_state'] +" sad!"} +``` + +Ví dụ, các Node có thể chứa: +- **LLM calls**: Tạo văn bản hoặc đưa ra quyết định +- **Tool calls**: Tương tác với hệ thống bên ngoài +- **Conditional logic**: Xác định các bước tiếp theo +- **Human intervention**: Nhận input từ người dùng + +> 💡 **Thông tin:** Một số node cần thiết cho toàn bộ workflow như START và END đã có sẵn trong LangGraph. + +## 3. Edges (Cạnh) + +**Edges** kết nối các node và xác định các đường đi có thể trong đồ thị: + +```python +import random +from typing import Literal + +def decide_mood(state) -> Literal["node_2", "node_3"]: + + # Thông thường, ta sẽ sử dụng state để quyết định node tiếp theo + user_input = state['graph_state'] + + # Ở đây, ta chia tỷ lệ 50/50 giữa node 2 và 3 + if random.random() < 0.5: + + # 50% trường hợp trả về Node 2 + return "node_2" + + # 50% trường hợp trả về Node 3 + return "node_3" +``` + +Edges có thể là: +- **Direct**: Luôn đi từ node A đến node B +- **Conditional**: Chọn node tiếp theo dựa trên state hiện tại + +## 4. StateGraph (Đồ thị trạng thái) + +**StateGraph** là container chứa toàn bộ workflow của Agent: + +```python +from IPython.display import Image, display +from langgraph.graph import StateGraph, START, END + +# Xây dựng đồ thị +builder = StateGraph(State) +builder.add_node("node_1", node_1) +builder.add_node("node_2", node_2) +builder.add_node("node_3", node_3) + +# Logic +builder.add_edge(START, "node_1") +builder.add_conditional_edges("node_1", decide_mood) +builder.add_edge("node_2", END) +builder.add_edge("node_3", END) + +# Tổng hợp +graph = builder.compile() +``` + +Có thể visualize đồ thị này! +```python +# Hiển thị +display(Image(graph.get_graph().draw_mermaid_png())) +``` +Graph Visualization + +Nhưng quan trọng nhất là cách invoke: +```python +graph.invoke({"graph_state" : "Hi, this is Lance."}) +``` +output : +``` +---Node 1--- +---Node 3--- +{'graph_state': 'Hi, this is Lance. I am sad!'} +``` + +## Bước tiếp theo là gì? + +Trong phần tiếp theo, chúng ta sẽ áp dụng các khái niệm này vào thực tế bằng cách xây dựng đồ thị đầu tiên. Đồ thị này cho phép Alfred tiếp nhận email, phân loại chúng và soạn câu trả lời sơ bộ nếu chúng là email thật. \ No newline at end of file diff --git a/units/vi/unit2/langgraph/conclusion.mdx b/units/vi/unit2/langgraph/conclusion.mdx new file mode 100644 index 000000000..5ee840a91 --- /dev/null +++ b/units/vi/unit2/langgraph/conclusion.mdx @@ -0,0 +1,21 @@ +# Kết luận + +Chúc mừng bạn đã hoàn thành mô-đun LangGraph của Chương 2! 🥳 + +Bạn đã nắm vững kiến thức nền tảng về xây dựng workflow có cấu trúc với LangGraph mà bạn có thể triển khai vào môi trường thực tế. + +Mô-đun này mới chỉ là khởi đầu hành trình LangGraph của bạn. Để khám phá chuyên sâu hơn, chúng mình gợi ý: + +- Tham khảo [tài liệu chính thức của LangGraph](https://github.com/langchain-ai/langgraph) +- Tham gia [Khóa học Giới thiệu về LangGraph](https://academy.langchain.com/courses/intro-to-langgraph) từ học viện LangChain +- Hãy tự xây dựng một thứ gì đó! + +Trong Chương tiếp theo, bạn sẽ khám phá các use case thực tế. Đã đến lúc rời lý thuyết để bước vào thực chiến! + +Chúng mình rất trân trọng **ý kiến đóng góp và đề xuất cải thiện** của bạn. Nếu có phản hồi, vui lòng 👉 [điền vào form này](https://docs.google.com/forms/d/e/1FAIpQLSe9VaONn0eglax0uTwi29rIn4tM7H2sYmmybmG5jJNlE5v0xA/viewform?usp=dialog) + +### Hãy tiếp tục học hỏi và luôn tỏa sáng! 🤗 + +Kính gửi Quý Ngài/Quý Bà! 🎩🦇 + +-Alfred- \ No newline at end of file diff --git a/units/vi/unit2/langgraph/document_analysis_agent.mdx b/units/vi/unit2/langgraph/document_analysis_agent.mdx new file mode 100644 index 000000000..0b7847e2a --- /dev/null +++ b/units/vi/unit2/langgraph/document_analysis_agent.mdx @@ -0,0 +1,251 @@ +# Đồ thị Phân tích Tài liệu + +Alfred xin được phục vụ. Là quản gia đáng tin cậy của ngài Wayne, tôi đã ghi chép lại cách mình hỗ trợ ngài Wayne trong các nhu cầu về tài liệu. Trong khi ngài ra ngoài tham gia... các hoạt động ban đêm, tôi đảm bảo mọi giấy tờ, lịch tập luyện và kế hoạch dinh dưỡng đều được phân tích và sắp xếp hợp lý. + +Trước khi rời đi, ngài có để lại ghi chú về chương trình tập luyện tuần này. Tôi đã nhận trách nhiệm lên **thực đơn** cho các bữa ăn ngày mai. + +Để xử lý những tình huống tương tự trong tương lai, hãy tạo một hệ thống phân tích tài liệu bằng LangGraph để phục vụ nhu cầu của ngài Wayne. Hệ thống này có thể: + +1. Xử lý tài liệu hình ảnh +2. Trích xuất văn bản bằng mô hình thị giác (Vision Language Model) +3. Thực hiện tính toán khi cần (để minh họa cho các công cụ thông thường) +4. Phân tích nội dung và cung cấp bản tóm tắt ngắn gọn +5. Thực hiện các chỉ dẫn cụ thể liên quan đến tài liệu + +## Quy trình làm việc của Quản gia + +Quy trình chúng ta sẽ xây dựng tuân theo sơ đồ cấu trúc sau: + +![Quy trình Phân tích Tài liệu của Quản gia](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/LangGraph/alfred_flow.png) + + +Bạn có thể theo dõi code trong notebook này và chạy bằng Google Colab. + + +## Thiết lập môi trường + +```python +%pip install langgraph langchain_openai Pillow base64 langchain_core +``` +và import các thư viện: +```python +import base64 +from typing import List, TypedDict, Annotated, Optional +from langchain.schema import HumanMessage +from langchain_openai import ChatOpenAI +from langchain_core.messages import AnyMessage, SystemMessage +from langgraph.graph.message import add_messages +from langgraph.graph import START, StateGraph +from langgraph.prebuilt import tools_condition +from langgraph.prebuilt import ToolNode +from IPython.display import Image, display +``` + +## Định nghĩa Trạng thái Agent + +Trạng thái này phức tạp hơn một chút so với những phiên bản trước. +AnyMessage là một lớp từ langchain định nghĩa các tin nhắn và add_messages là toán tử thêm tin nhắn mới thay vì ghi đè lên trạng thái cũ. + +Đây là một khái niệm mới trong LangGraph, nơi bạn có thể thêm các toán tử vào trạng thái để định nghĩa cách chúng tương tác với nhau. + +```python +class AgentState(TypedDict): + # Tài liệu được cung cấp + input_file: Optional[str] # Chứa đường dẫn file (PDF/PNG) + messages: Annotated[list[AnyMessage], add_messages] +``` + +## Chuẩn bị Công cụ + +```python +vision_llm = ChatOpenAI(model="gpt-4o") + +def extract_text(img_path: str) -> str: + """ + Trích xuất văn bản từ file ảnh bằng mô hình đa phương thức. + + Ngài Wayne thường để lại các ghi chú về chế độ tập luyện hoặc thực đơn. + Điều này cho phép tôi phân tích nội dung một cách chính xác. + """ + all_text = "" + try: + # Đọc ảnh và mã hóa dạng base64 + with open(img_path, "rb") as image_file: + image_bytes = image_file.read() + + image_base64 = base64.b64encode(image_bytes).decode("utf-8") + + # Chuẩn bị prompt bao gồm dữ liệu ảnh base64 + message = [ + HumanMessage( + content=[ + { + "type": "text", + "text": ( + "Trích xuất toàn bộ văn bản từ ảnh này. " + "Chỉ trả về văn bản đã trích xuất, không giải thích." + ), + }, + { + "type": "image_url", + "image_url": { + "url": f"data:image/png;base64,{image_base64}" + }, + }, + ] + ) + ] + + # Gọi mô hình hỗ trợ xử lý ảnh + response = vision_llm.invoke(message) + + # Thêm văn bản trích xuất + all_text += response.content + "\n\n" + + return all_text.strip() + except Exception as e: + # Một quản gia cần xử lý lỗi một cách thanh lịch + error_msg = f"Lỗi trích xuất văn bản: {str(e)}" + print(error_msg) + return "" + +def divide(a: int, b: int) -> float: + """Chia a cho b - phục vụ các phép tính toán thi thoảng của ngài Wayne.""" + return a / b + +# Trang bị công cụ cho quản gia +tools = [ + divide, + extract_text +] + +llm = ChatOpenAI(model="gpt-4o") +llm_with_tools = llm.bind_tools(tools, parallel_tool_calls=False) +``` + +## Các node + +```python +def assistant(state: AgentState): + # Tin nhắn hệ thống + textual_description_of_tool=""" +extract_text(img_path: str) -> str: + Trích xuất văn bản từ file ảnh bằng mô hình đa phương thức. + + Args: + img_path: Đường dẫn file ảnh cục bộ (chuỗi). + + Returns: + Một chuỗi duy nhất chứa toàn bộ văn bản trích xuất từ ảnh. +divide(a: int, b: int) -> float: + Chia a cho b +""" + image=state["input_file"] + sys_msg = SystemMessage(content=f"Bạn là quản gia Alfred hữu ích phục vụ ngài Wayne và Batman. Bạn có thể phân tích tài liệu và chạy tính toán bằng các công cụ được cung cấp:\n{textual_description_of_tool} \n Bạn có quyền truy cập vào một số ảnh tùy chọn. Hiện tại ảnh đang được tải là: {image}") + + return { + "messages": [llm_with_tools.invoke([sys_msg] + state["messages"])], + "input_file": state["input_file"] + } +``` + +## Mô hình ReAct: Cách tôi hỗ trợ ngài Wayne + +Cho phép tôi giải thích cách tiếp cận trong agent này. Agent tuân theo mô hình ReAct (Lý luận - Hành động - Quan sát): + +1. **Lý luận** về tài liệu và yêu cầu +2. **Hành động** bằng cách sử dụng công cụ phù hợp +3. **Quan sát** kết quả +4. **Lặp lại** khi cần thiết cho đến khi đáp ứng đủ nhu cầu + +Đây là một triển khai đơn giản của agent sử dụng LangGraph. + +```python +## Đồ thị +builder = StateGraph(AgentState) + +# Định nghĩa node: thực hiện công việc +builder.add_node("assistant", assistant) +builder.add_node("tools", ToolNode(tools)) + +# Định nghĩa cạnh: xác định luồng điều khiển +builder.add_edge(START, "assistant") +builder.add_conditional_edges( + "assistant", + # Nếu tin nhắn mới nhất yêu cầu công cụ, chuyển đến tools + # Ngược lại, trả lời trực tiếp + tools_condition, +) +builder.add_edge("tools", "assistant") +react_graph = builder.compile() + +# Hiển thị quá trình suy nghĩ của quản gia +display(Image(react_graph.get_graph(xray=True).draw_mermaid_png())) +``` + +![Mô hình ReAct](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/LangGraph/Agent.png) + +## Quản gia trong hành động + +### Ví dụ 1: Tính toán đơn giản + +Trong ví dụ sau, chúng ta thêm hàm chia này để minh họa + +```python +messages = [HumanMessage(content="Chia 6790 cho 5")] +messages = react_graph.invoke({"messages": messages, "input_file": None}) +``` + +Cuộc hội thoại sẽ diễn ra như sau: + +``` +Human: Chia 6790 cho 5 + +AI Tool Call: divide(a=6790, b=5) + +Tool Response: 1358.0 + +Alfred: Kết quả của phép chia 6790 cho 5 là 1358.0. +``` + +### Ví dụ 2: Phân tích Tài liệu Tập luyện của ngài Wayne + +Khi ngài Wayne để lại các ghi chú về tập luyện và thực đơn: + +```python +messages = [HumanMessage(content="Theo ghi chú trong ảnh được cung cấp bởi ngài Wayne. Danh sách các vật phẩm tôi cần mua cho thực đơn tối nay là gì?")] +messages = react_graph.invoke({"messages": messages, "input_file": "Batman_training_and_meals.png"}) +``` + +Quá trình tương tác sẽ diễn ra: + +``` +Human: Theo ghi chú trong ảnh được cung cấp bởi ngài Wayne. Danh sách các vật phẩm tôi cần mua cho thực đơn tối nay là gì? + +AI Tool Call: extract_text(img_path="Batman_training_and_meals.png") + +Tool Response: [Văn bản trích xuất bao gồm lịch tập và chi tiết thực đơn] + +Alfred: Đối với thực đơn tối, bạn cần mua các vật phẩm sau: + +1. Thăn bò ăn cỏ địa phương +2. Rau chân vịt hữu cơ +3. Ớt Piquillo +4. Khoai tây (để nướng vàng thảo mộc) +5. Dầu cá (2 gram) + +Hãy đảm bảo thịt bò được nuôi bằng cỏ và rau chân vịt cùng ớt là hữu cơ để có bữa ăn chất lượng nhất. +``` + +## Điểm quan trọng cần nhớ + +Nếu bạn muốn tạo quản gia phân tích tài liệu cho riêng mình, hãy lưu ý: + +1. **Định nghĩa công cụ rõ ràng** cho các tác vụ liên quan đến tài liệu +2. **Tạo bộ theo dõi trạng thái mạnh mẽ** để duy trì ngữ cảnh giữa các lần gọi công cụ +3. **Xử lý lỗi** cho các trường hợp công cụ thất bại +5. **Duy trì nhận thức ngữ cảnh** về các tương tác trước đó (được đảm bảo bởi toán tử add_messages) + +Với những nguyên tắc này, bạn cũng có thể cung cấp dịch vụ phân tích tài liệu đẳng cấp xứng tầm biệt thự Wayne. + +*Tôi tin rằng giải thích này đã thỏa đáng. Giờ xin phép được lui, vì áo choàng của ngài Wayne cần được là ủi trước các hoạt động tối nay.* \ No newline at end of file diff --git a/units/vi/unit2/langgraph/first_graph.mdx b/units/vi/unit2/langgraph/first_graph.mdx new file mode 100644 index 000000000..a96d85c4e --- /dev/null +++ b/units/vi/unit2/langgraph/first_graph.mdx @@ -0,0 +1,444 @@ +# Xây Dựng LangGraph Đầu Tiên Của Bạn + +Giờ ta đã hiểu các thành phần cơ bản, hãy áp dụng chúng vào thực tế bằng cách xây dựng đồ thị chức năng đầu tiên. Ta sẽ triển khai hệ thống xử lý email của Alfred, nơi anh ấy cần: + +1. Đọc email đến +2. Phân loại spam hoặc hợp lệ +3. Soạn thảo phản hồi sơ bộ cho email hợp lệ +4. Gửi thông tin cho ông Wayne khi hợp lệ (chỉ in ra) + +Ví dụ này minh họa cách cấu trúc một quy trình làm việc với LangGraph có liên quan đến việc ra quyết định dựa trên LLM. Dù đây chưa được coi là một Agent (tác nhân) vì không có công cụ nào được sử dụng, phần này tập trung vào việc học framework LangGraph hơn là về Agents. + + +Bạn có thể theo dõi code trong notebook này và chạy qua Google Colab. + + +## Quy Trình Làm Việc Của Chúng Ta + +Đây là quy trình ta sẽ xây dựng: +First LangGraph + +## Thiết Lập Môi Trường + +Đầu tiên, cài đặt các gói cần thiết: + +```python +%pip install langgraph langchain_openai +``` + +Nhập các module cần thiết: + +```python +import os +from typing import TypedDict, List, Dict, Any, Optional +from langgraph.graph import StateGraph, END +from langchain_openai import ChatOpenAI +from langchain_core.messages import HumanMessage, AIMessage +``` + +## Bước 1: Định Nghĩa Trạng Thái + +Hãy xác định thông tin Alfred cần theo dõi trong quy trình xử lý email: + +```python +class EmailState(TypedDict): + # Email đang được xử lý + email: Dict[str, Any] # Chứa subject, sender, body, v.v. + + # Phân tích và quyết định + is_spam: Optional[bool] + + # Tạo phản hồi + draft_response: Optional[str] + + # Metadata xử lý + messages: List[Dict[str, Any]] # Theo dõi hội thoại với LLM để phân tích +``` + +> 💡 **Mẹo:** Thiết kế trạng thái đủ chi tiết để theo dõi mọi thông tin quan trọng, nhưng tránh làm phình to với các chi tiết không cần thiết. + +## Bước 2: Định Nghĩa Các Node + +Giờ hãy tạo các hàm xử lý sẽ tạo thành các node: + +```python +# Khởi tạo LLM +model = ChatOpenAI(temperature=0) + +def read_email(state: EmailState): + """Alfred đọc và ghi nhận email đến""" + email = state["email"] + + # Có thể thực hiện tiền xử lý ban đầu ở đây + print(f"Alfred đang xử lý email từ {email['sender']} với chủ đề: {email['subject']}") + + # Không cần thay đổi trạng thái ở đây + return {} + +def classify_email(state: EmailState): + """Alfred sử dụng LLM để xác định email là spam hay hợp lệ""" + email = state["email"] + + # Chuẩn bị prompt cho LLM + prompt = f""" + Với vai trò là quản gia Alfred, hãy phân tích email này và xác định xem nó là spam hay hợp lệ. + + Email: + Từ: {email['sender']} + Chủ đề: {email['subject']} + Nội dung: {email['body']} + + Đầu tiên, xác định xem email này có phải spam không. Nếu là spam, giải thích lý do. + Nếu hợp lệ, phân loại nó (hỏi đáp, khiếu nại, cảm ơn, v.v.). + """ + + # Gọi LLM + messages = [HumanMessage(content=prompt)] + response = model.invoke(messages) + + # Logic đơn giản để phân tích phản hồi (trong ứng dụng thực tế cần phân tích kỹ hơn) + response_text = response.content.lower() + is_spam = "spam" in response_text and "not spam" not in response_text + + # Trích xuất lý do nếu là spam + spam_reason = None + if is_spam and "reason:" in response_text: + spam_reason = response_text.split("reason:")[1].strip() + + # Xác định loại email nếu hợp lệ + email_category = None + if not is_spam: + categories = ["inquiry", "complaint", "thank you", "request", "information"] + for category in categories: + if category in response_text: + email_category = category + break + + # Cập nhật messages để theo dõi + new_messages = state.get("messages", []) + [ + {"role": "user", "content": prompt}, + {"role": "assistant", "content": response.content} + ] + + # Trả về các thay đổi trạng thái + return { + "is_spam": is_spam, + "spam_reason": spam_reason, + "email_category": email_category, + "messages": new_messages + } + +def handle_spam(state: EmailState): + """Alfred loại bỏ email spam với ghi chú""" + print(f"Alfred đã đánh dấu email là spam. Lý do: {state['spam_reason']}") + print("Email đã được chuyển vào thư mục spam.") + + # Hoàn thành xử lý email này + return {} + +def draft_response(state: EmailState): + """Alfred soạn thảo phản hồi sơ bộ cho email hợp lệ""" + email = state["email"] + category = state["email_category"] or "general" + + # Chuẩn bị prompt cho LLM + prompt = f""" + Với vai trò là quản gia Alfred, hãy soạn thảo phản hồi lịch sự sơ bộ cho email này. + + Email: + Từ: {email['sender']} + Chủ đề: {email['subject']} + Nội dung: {email['body']} + + Email này đã được phân loại là: {category} + + Hãy soạn phản hồi ngắn gọn, chuyên nghiệp để ông Hugg có thể xem xét và cá nhân hóa trước khi gửi. + """ + + # Gọi LLM + messages = [HumanMessage(content=prompt)] + response = model.invoke(messages) + + # Cập nhật messages để theo dõi + new_messages = state.get("messages", []) + [ + {"role": "user", "content": prompt}, + {"role": "assistant", "content": response.content} + ] + + # Trả về các thay đổi trạng thái + return { + "draft_response": response.content, + "messages": new_messages + } + +def notify_mr_hugg(state: EmailState): + """Alfred thông báo cho ông Hugg về email và trình bản nháp phản hồi""" + email = state["email"] + + print("\n" + "="*50) + print(f"Thưa ngài, ngài có email từ {email['sender']}.") + print(f"Chủ đề: {email['subject']}") + print(f"Phân loại: {state['email_category']}") + print("\nTôi đã chuẩn bị bản nháp phản hồi để ngài xem xét:") + print("-"*50) + print(state["draft_response"]) + print("="*50 + "\n") + + # Hoàn thành xử lý email này + return {} +``` + +## Bước 3: Định Nghĩa Logic Định Tuyến + +Cần một hàm để xác định đường đi tiếp theo sau khi phân loại: + +```python +def route_email(state: EmailState) -> str: + """Xác định bước tiếp theo dựa trên phân loại spam""" + if state["is_spam"]: + return "spam" + else: + return "legitimate" +``` + +> 💡 **Lưu ý:** Hàm định tuyến này được LangGraph gọi để xác định cạnh nào sẽ đi theo sau node phân loại. Giá trị trả về phải khớp với một trong các khóa trong ánh xạ cạnh điều kiện. + +## Bước 4: Tạo StateGraph và Định Nghĩa Các Cạnh + +Giờ ta kết nối mọi thứ lại: + +```python +# Tạo đồ thị +email_graph = StateGraph(EmailState) + +# Thêm các node +email_graph.add_node("read_email", read_email) +email_graph.add_node("classify_email", classify_email) +email_graph.add_node("handle_spam", handle_spam) +email_graph.add_node("draft_response", draft_response) +email_graph.add_node("notify_mr_hugg", notify_mr_hugg) + +# Bắt đầu các cạnh +email_graph.add_edge(START, "read_email") +# Thêm cạnh - định nghĩa luồng +email_graph.add_edge("read_email", "classify_email") + +# Thêm nhánh điều kiện từ classify_email +email_graph.add_conditional_edges( + "classify_email", + route_email, + { + "spam": "handle_spam", + "legitimate": "draft_response" + } +) + +# Thêm các cạnh cuối +email_graph.add_edge("handle_spam", END) +email_graph.add_edge("draft_response", "notify_mr_hugg") +email_graph.add_edge("notify_mr_hugg", END) + +# Biên dịch đồ thị +compiled_graph = email_graph.compile() +``` + +Lưu ý cách ta sử dụng node `END` đặc biệt của LangGraph. Đây chỉ các trạng thái kết thúc khi quy trình hoàn thành. + +## Bước 5: Chạy Ứng Dụng + +Hãy thử nghiệm đồ thị với email hợp lệ và email spam: + +```python +# Email hợp lệ mẫu +legitimate_email = { + "sender": "john.smith@example.com", + "subject": "Question about your services", + "body": "Dear Mr. Hugg, I was referred to you by a colleague and I'm interested in learning more about your consulting services. Could we schedule a call next week? Best regards, John Smith" +} + +# Email spam mẫu +spam_email = { + "sender": "winner@lottery-intl.com", + "subject": "YOU HAVE WON $5,000,000!!!", + "body": "CONGRATULATIONS! You have been selected as the winner of our international lottery! To claim your $5,000,000 prize, please send us your bank details and a processing fee of $100." +} + +# Xử lý email hợp lệ +print("\nProcessing legitimate email...") +legitimate_result = compiled_graph.invoke({ + "email": legitimate_email, + "is_spam": None, + "spam_reason": None, + "email_category": None, + "draft_response": None, + "messages": [] +}) + +# Xử lý email spam +print("\nProcessing spam email...") +spam_result = compiled_graph.invoke({ + "email": spam_email, + "is_spam": None, + "spam_reason": None, + "email_category": None, + "draft_response": None, + "messages": [] +}) +``` + +
+Bấm để xem bản dịch tiếng Việt + +```python +# Email hợp lệ mẫu +legitimate_email = { + "sender": "john.smith@example.com", + "subject": "Câu hỏi về dịch vụ của bạn", + "body": "Kính gửi ông Hugg, tôi được đồng nghiệp giới thiệu và muốn tìm hiểu thêm về dịch vụ tư vấn của ông. Chúng ta có thể sắp xếp một cuộc gọi vào tuần tới được không? Trân trọng, John Smith" +} + +# Email spam mẫu +spam_email = { + "sender": "winner@lottery-intl.com", + "subject": "BẠN ĐÃ TRÚNG 5.000.000$!!!", + "body": "CHÚC MỪNG! Bạn đã trúng giải xổ số quốc tế của chúng tôi! Để nhận giải 5.000.000$, vui lòng gửi thông tin ngân hàng và phí xử lý 100$." +} + +# Xử lý email hợp lệ +print("\nĐang xử lý email hợp lệ...") +legitimate_result = compiled_graph.invoke({ + "email": legitimate_email, + "is_spam": None, + "spam_reason": None, + "email_category": None, + "draft_response": None, + "messages": [] +}) + +# Xử lý email spam +print("\nĐang xử lý email spam...") +spam_result = compiled_graph.invoke({ + "email": spam_email, + "is_spam": None, + "spam_reason": None, + "email_category": None, + "draft_response": None, + "messages": [] +}) +``` +
+ +```python +# Example legitimate email +legitimate_email = { + "sender": "john.smith@example.com", + "subject": "Question about your services", + "body": "Dear Mr. Hugg, I was referred to you by a colleague and I'm interested in learning more about your consulting services. Could we schedule a call next week? Best regards, John Smith" +} + +# Example spam email +spam_email = { + "sender": "winner@lottery-intl.com", + "subject": "YOU HAVE WON $5,000,000!!!", + "body": "CONGRATULATIONS! You have been selected as the winner of our international lottery! To claim your $5,000,000 prize, please send us your bank details and a processing fee of $100." +} + +# Process the legitimate email +print("\nProcessing legitimate email...") +legitimate_result = compiled_graph.invoke({ + "email": legitimate_email, + "is_spam": None, + "spam_reason": None, + "email_category": None, + "draft_response": None, + "messages": [] +}) + +# Process the spam email +print("\nProcessing spam email...") +spam_result = compiled_graph.invoke({ + "email": spam_email, + "is_spam": None, + "spam_reason": None, + "email_category": None, + "draft_response": None, + "messages": [] +}) +``` + +## Bước 6: Giám Sát Agent Phân Loại Thư Với Langfuse 📡 + +Khi Alfred tinh chỉnh (fine-tuning) Agent Phân Loại Thư, anh ấy đang gặp khó khăn trong việc gỡ lỗi các lần chạy. Bản chất của Agents là khó dự đoán và kiểm tra. Nhưng vì mục tiêu xây dựng Agent Phát Hiện Spam tối ưu và triển khai production, anh ấy cần khả năng theo dõi mạnh mẽ cho giám sát và phân tích sau này. + +Để làm điều này, Alfred có thể sử dụng công cụ quan sát như [Langfuse](https://langfuse.com/) để theo dõi và giám sát agent. + +Đầu tiên, cài đặt Langfuse: +```python +%pip install -q langfuse +``` + +Thêm API keys và địa chỉ host của Langfuse vào biến môi trường. Bạn có thể lấy credentials Langfuse bằng cách đăng ký [Langfuse Cloud](https://cloud.langfuse.com) hoặc [self-host Langfuse](https://langfuse.com/self-hosting). + +```python +import os + +# Lấy keys từ trang cài đặt dự án: https://cloud.langfuse.com +os.environ["LANGFUSE_PUBLIC_KEY"] = "pk-lf-..." +os.environ["LANGFUSE_SECRET_KEY"] = "sk-lf-..." +os.environ["LANGFUSE_HOST"] = "https://cloud.langfuse.com" # 🇪🇺 Khu vực EU +# os.environ["LANGFUSE_HOST"] = "https://us.cloud.langfuse.com" # 🇺🇸 Khu vực US +``` + +Sau đó cấu hình [Langfuse `callback_handler`](https://langfuse.com/docs/integrations/langchain/tracing#add-langfuse-to-your-langchain-application) và tích hợp agent bằng cách thêm `langfuse_callback` vào lệnh gọi đồ thị: `config={"callbacks": [langfuse_handler]}`. + +```python +from langfuse.callback import CallbackHandler + +# Khởi tạo Langfuse CallbackHandler cho LangGraph/Langchain (tracing) +langfuse_handler = CallbackHandler() + +# Xử lý email hợp lệ +legitimate_result = compiled_graph.invoke( + input={"email": legitimate_email, "is_spam": None, "spam_reason": None, "email_category": None, "draft_response": None, "messages": []}, + config={"callbacks": [langfuse_handler]} +) +``` + +Alfred đã kết nối thành công 🔌! Các lần chạy từ LangGraph đang được ghi nhận vào Langfuse, cho phép anh ấy quan sát toàn bộ hành vi của agent. Với thiết lập này, anh ấy có thể xem lại các lần chạy trước và cải thiện Agent Phân Loại Thư. + +![Ví dụ trace trong Langfuse](https://langfuse.com/images/cookbook/huggingface-agent-course/langgraph-trace-legit.png) + +_[Liên kết công khai đến trace với email hợp lệ](https://cloud.langfuse.com/project/cloramnkj0002jz088vzn1ja4/traces/f5d6d72e-20af-4357-b232-af44c3728a7b?timestamp=2025-03-17T10%3A13%3A28.413Z&observation=6997ba69-043f-4f77-9445-700a033afba1)_ + +## Trực Quan Hóa Đồ Thị + +LangGraph cho phép ta trực quan hóa quy trình làm việc để hiểu và gỡ lỗi cấu trúc tốt hơn: + +```python +compiled_graph.get_graph().draw_mermaid_png() +``` +Mail LangGraph + +Điều này tạo ra biểu diễn trực quan cho thấy cách các node được kết nối và các đường đi có điều kiện. + +## Thành Quả Đạt Được + +Ta đã tạo ra một quy trình xử lý email hoàn chỉnh: + +1. Nhận email đến +2. Sử dụng LLM để phân loại spam/hợp lệ +3. Xử lý spam bằng cách loại bỏ +4. Với email hợp lệ, soạn phản hồi và thông báo cho ông Hugg + +Điều này minh họa sức mạnh của LangGraph trong việc điều phối các quy trình phức tạp với LLM trong khi duy trì luồng làm việc rõ ràng. + +## Điểm Quan Trọng + +- **Quản Lý Trạng Thái**: Ta đã định nghĩa trạng thái toàn diện để theo dõi mọi khía cạnh xử lý email +- **Triển Khai Node**: Ta đã tạo các node chức năng tương tác với LLM +- **Định Tuyến Có Điều Kiện**: Ta đã triển khai logic phân nhánh dựa trên phân loại email +- **Trạng Thái Kết Thúc**: Ta đã sử dụng node END để đánh dấu điểm hoàn thành quy trình + +## Bước Tiếp Theo? + +Trong phần tiếp theo, ta sẽ khám phá các tính năng nâng cao của LangGraph, bao gồm xử lý tương tác con người trong quy trình và triển khai logic phân nhánh phức tạp dựa trên nhiều điều kiện. \ No newline at end of file diff --git a/units/vi/unit2/langgraph/introduction.mdx b/units/vi/unit2/langgraph/introduction.mdx new file mode 100644 index 000000000..55414bf26 --- /dev/null +++ b/units/vi/unit2/langgraph/introduction.mdx @@ -0,0 +1,32 @@ +# Giới thiệu về `LangGraph` + +Chương 2.3 Ảnh đại diện + +Chào mừng bạn đến với phần tiếp theo hành trình của chúng ta, nơi bạn sẽ học **cách xây dựng ứng dụng** bằng framework [`LangGraph`](https://github.com/langchain-ai/langgraph) - công cụ giúp tổ chức và điều phối các workflow phức tạp cho LLM (mô hình ngôn ngữ lớn). + +`LangGraph` là framework cho phép bạn xây dựng ứng dụng **sẵn sàng cho production** bằng cách cung cấp các công cụ **kiểm soát** luồng hoạt động của agent. + +## Tổng quan Mô-đun + +Trong chương này, bạn sẽ khám phá: + +### 1️⃣ [LangGraph là gì và khi nào nên sử dụng?](./when_to_use_langgraph) +### 2️⃣ [Các thành phần cơ bản của LangGraph](./building_blocks) +### 3️⃣ [Alfred - quản gia phân loại thư](./first_graph) +### 4️⃣ [Alfred - agent phân tích tài liệu](./document_analysis_agent) +### 5️⃣ [Kiểm tra nhanh](./quizz1) + + +Các ví dụ trong phần này yêu cầu quyền truy cập vào một LLM/VLM mạnh. Chúng mình đã chạy chúng bằng GPT-4o API vì nó tương thích tốt nhất với LangGraph. + + +Đến cuối chương này, bạn sẽ có thể xây dựng các ứng dụng mạnh mẽ, có tổ chức và sẵn sàng cho production! + +Đây là phần giới thiệu cơ bản về LangGraph. Bạn có thể tìm hiểu thêm các chủ đề nâng cao qua khóa học miễn phí học viện LangChain: [Giới thiệu về LangGraph](https://academy.langchain.com/courses/intro-to-langgraph) + +Hãy cùng bắt đầu! + +## Tài nguyên tham khảo + +- [LangGraph Agents](https://langchain-ai.github.io/langgraph/) - Các ví dụ về LangGraph agent +- [LangChain academy](https://academy.langchain.com/courses/intro-to-langgraph) - Khóa học đầy đủ về LangGraph từ LangChain \ No newline at end of file diff --git a/units/vi/unit2/langgraph/quiz1.mdx b/units/vi/unit2/langgraph/quiz1.mdx new file mode 100644 index 000000000..b5331c456 --- /dev/null +++ b/units/vi/unit2/langgraph/quiz1.mdx @@ -0,0 +1,118 @@ +# Kiểm tra hiểu biết của bạn về LangGraph + +Cùng kiểm tra hiểu biết của bạn về `LangGraph` với một bài **Kiểm tra nhanh**! Điều này sẽ giúp củng cố các khái niệm chính mà ta đã đề cập. + +Bài kiểm tra này không bắt buộc và không được chấm điểm. + +### Câu 1: Mục đích chính của LangGraph là gì? +Phát biểu nào mô tả đúng nhất thiết kế của LangGraph? + + + +--- + +### Câu 2: Trong bối cảnh đánh đổi "Kiểm soát vs Tự do", LangGraph đứng ở đâu? +Phát biểu nào đặc trưng nhất cho cách tiếp cận của LangGraph trong thiết kế agent? + + + +--- + +### Câu 3: State (trạng thái) đóng vai trò gì trong LangGraph? +Chọn mô tả chính xác nhất về State trong LangGraph. + + + +### Câu 4: Conditional Edge (cạnh có điều kiện) trong LangGraph là gì? +Chọn mô tả chính xác nhất. + + + +--- + +### Câu 6: LangGraph giúp giải quyết vấn đề ảo giác (hallucination) trong LLM như thế nào? +Chọn câu trả lời đúng nhất. + + + +Chúc mừng bạn đã hoàn thành bài kiểm tra! 🎉 Nếu bạn trả lời sai bất kỳ câu hỏi nào, hãy xem lại các phần trước để củng cố hiểu biết. Tiếp theo, chúng ta sẽ khám phá các tính năng nâng cao hơn của LangGraph và xem cách xây dựng các quy trình agent phức tạp hơn. \ No newline at end of file diff --git a/units/vi/unit2/langgraph/when_to_use_langgraph.mdx b/units/vi/unit2/langgraph/when_to_use_langgraph.mdx new file mode 100644 index 000000000..39c2c2f5a --- /dev/null +++ b/units/vi/unit2/langgraph/when_to_use_langgraph.mdx @@ -0,0 +1,68 @@ +# `LangGraph` là gì? + +`LangGraph` là một framework được phát triển bởi [LangChain](https://www.langchain.com/) **để quản lý luồng điều khiển của các ứng dụng tích hợp LLM**. + +## `LangGraph` có khác với `LangChain` không? + +LangChain cung cấp giao diện chuẩn để tương tác với mô hình và các thành phần khác, hữu ích cho truy xuất, gọi LLM và gọi công cụ (tools). +Các lớp từ LangChain có thể được sử dụng trong LangGraph, nhưng không BẮT BUỘC phải dùng. + +Hai package này độc lập và có thể dùng riêng lẻ, nhưng trên thực tế, các tài nguyên bạn tìm thấy online đều kết hợp cả hai. + +## Khi nào nên dùng `LangGraph`? +### Kiểm soát vs tự do + +Khi thiết kế ứng dụng AI, ta phải cân nhắc giữa **kiểm soát** và **tự do**: + +- **Tự do** cho phép LLM sáng tạo và giải quyết vấn đề bất ngờ. +- **Kiểm soát** giúp đảm bảo hành vi dự đoán được và duy trì giới hạn an toàn. + +Code Agents, như trong *smolagents*, rất tự do. Chúng có thể gọi nhiều công cụ trong một bước, tự tạo công cụ mới... Tuy nhiên, điều này khiến chúng khó dự đoán hơn so với Agent thường dùng JSON. + +`LangGraph` nằm ở đầu đối lập, tỏa sáng khi bạn cần **"Kiểm soát"** quá trình thực thi agent. + +LangGraph đặc biệt hữu ích khi bạn cần **Kiểm soát ứng dụng**. Nó cung cấp công cụ để xây dựng ứng dụng theo quy trình dự đoán được, đồng thời tận dụng sức mạnh LLM. + +Nói đơn giản, nếu ứng dụng của bạn gồm nhiều bước cần được điều phối theo cách cụ thể, với các quyết định tại mỗi điểm rẽ nhánh, **LangGraph cung cấp cấu trúc bạn cần**. + +Ví dụ: giả sử ta muốn xây dựng trợ lý LLM có thể trả lời câu hỏi về tài liệu. + +Vì LLM hiểu văn bản tốt nhất, trước khi trả lời, ta cần chuyển đổi các dạng phức tạp (biểu đồ, bảng) thành văn bản. Tuy nhiên, lựa chọn này phụ thuộc vào loại tài liệu! + +Ta có thể biểu diễn quy trình rẽ nhánh như sau: + +Control flow + +> 💡 **Mẹo:** Phần bên trái không phải agent vì không gọi công cụ. Phần bên phải cần viết code để truy vấn file xls (chuyển sang pandas và xử lý). + +Dù nhánh này là xác định, bạn có thể thiết kế nhánh phụ thuộc vào đầu ra LLM, khiến chúng không xác định. + +Các trường hợp LangGraph phát huy thế mạnh: + +- **Quy trình lập luận đa bước** cần kiểm soát luồng rõ ràng +- **Ứng dụng yêu cầu duy trì trạng thái** giữa các bước +- **Hệ thống kết hợp logic xác định với khả năng AI** +- **Quy trình cần can thiệp của con người** +- **Kiến trúc agent phức tạp** với nhiều thành phần kết hợp + +Tóm lại, khi có thể, **là con người**, hãy thiết kế luồng hành động dựa trên đầu ra từng bước, và quyết định bước tiếp theo. Trường hợp này, LangGraph là framework phù hợp! + +Theo mình, `LangGraph` là framework agent sẵn sàng cho production nhất hiện nay. + +## LangGraph hoạt động thế nào? + +Cốt lõi, `LangGraph` dùng đồ thị có hướng để định nghĩa luồng ứng dụng: + +- **Node** đại diện cho từng bước xử lý (gọi LLM, dùng công cụ, ra quyết định). +- **Edge** xác định chuyển tiếp giữa các node. +- **State** do người dùng định nghĩa, được duy trì và truyền giữa các node. Khi quyết định node tiếp theo, ta xem xét state hiện tại. + +Chúng ta sẽ khám phá các khối cơ bản này ở Chương tiếp theo! + +## Khác gì với Python thường? Tại sao cần LangGraph? + +Bạn có thể thắc mắc: "Mình có thể dùng Python với câu lệnh if-else để xử lý các luồng này mà?" + +Về mặt kỹ thuật là được, nhưng LangGraph mang **lợi thế** so với Python thuần khi xây hệ thống phức tạp. Bạn có thể tự xây ứng dụng tương tự, nhưng LangGraph cung cấp sẵn công cụ và abstraction. + +Nó bao gồm state, visualization, logging (traces), tích hợp sẵn human-in-the-loop, và hơn thế. \ No newline at end of file diff --git a/units/vi/unit2/llama-index/agents.mdx b/units/vi/unit2/llama-index/agents.mdx new file mode 100644 index 000000000..2567504ca --- /dev/null +++ b/units/vi/unit2/llama-index/agents.mdx @@ -0,0 +1,160 @@ +# Sử dụng Agent trong LlamaIndex + +Hãy nhớ Alfred, agent quản gia đáng tin cậy của chúng ta từ những bài trước chứ? Giờ đây anh ấy sắp được nâng cấp! +Sau khi đã hiểu về các Tools có sẵn trong LlamaIndex, ta có thể trang bị thêm khả năng mới cho Alfred để phục vụ tốt hơn. + +Nhưng trước khi tiếp tục, hãy cùng ôn lại cách hoạt động của một agent như Alfred. +Từ Chương 1, ta đã học được: + +> Agent là hệ thống sử dụng model AI để tương tác với môi trường nhằm đạt được mục tiêu do người dùng định nghĩa. Nó kết hợp khả năng lý luận, lập kế hoạch và thực thi hành động (thông qua các Tools bên ngoài) để hoàn thành nhiệm vụ. + +LlamaIndex hỗ trợ **ba loại agent chính**: + +![Agents](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/agents.png) + +1. `Function Calling Agents` - Loại này làm việc với các model AI có thể gọi các function cụ thể +2. `ReAct Agents` - Có thể hoạt động với bất kỳ AI nào có endpoint chat hoặc text để xử lý các tác vụ lý luận phức tạp +3. `Advanced Custom Agents` - Sử dụng các phương pháp phức tạp hơn để xử lý các workflow phức tạp + +Tìm hiểu thêm về các agent nâng cao tại BaseWorkflowAgent + +## Khởi tạo Agent + + +Bạn có thể theo dõi code trong notebook này và chạy thử qua Google Colab. + + +Để tạo agent, ta bắt đầu bằng cách cung cấp cho nó **một tập hợp các function/Tools xác định khả năng hoạt động**. +Hãy xem cách tạo agent với một số Tools cơ bản. Tại thời điểm viết bài, agent sẽ tự động sử dụng API function calling (nếu có sẵn) hoặc vòng lặp ReAct agent tiêu chuẩn. + +Các LLM hỗ trợ API tools/functions còn khá mới, nhưng chúng cung cấp cách mạnh mẽ để gọi Tools bằng cách tránh prompt cụ thể và cho phép LLM tạo lệnh gọi Tools dựa trên schema được cung cấp. + +ReAct agents cũng giỏi xử lý các tác vụ lý luận phức tạp và có thể làm việc với bất kỳ LLM nào có khả năng chat hoặc hoàn thiện văn bản. Chúng chi tiết hơn và hiển thị lý luận đằng sau các hành động được thực hiện. + +```python +from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI +from llama_index.core.agent.workflow import AgentWorkflow +from llama_index.core.tools import FunctionTool + +# định nghĩa một Tool mẫu - chú thích kiểu, tên function và docstring đều được đưa vào schema +def multiply(a: int, b: int) -> int: + """Nhân hai số nguyên và trả về kết quả dạng số nguyên""" + return a * b + +# khởi tạo llm +llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct") + +# khởi tạo agent +agent = AgentWorkflow.from_tools_or_functions( + [FunctionTool.from_defaults(multiply)], + llm=llm +) +``` + +**Agent mặc định không lưu trữ trạng thái (stateless)**, việc ghi nhớ các tương tác trước được thực hiện thông qua object `Context` +Điều này hữu ích nếu bạn muốn tạo agent cần ghi nhớ ngữ cảnh như chatbot duy trì ngữ cảnh qua nhiều tin nhắn hoặc trình quản lý tác vụ cần theo dõi tiến trình. + +```python +# không lưu trạng thái +response = await agent.run("2 nhân 2 bằng mấy?") + +# lưu trạng thái +from llama_index.core.workflow import Context + +ctx = Context(agent) + +response = await agent.run("Tên tôi là Bob.", ctx=ctx) +response = await agent.run("Tên tôi là gì nhỉ?", ctx=ctx) +``` + +Bạn sẽ thấy agent trong `LlamaIndex` là async (bất đồng bộ) vì chúng sử dụng toán tử `await` của Python. Nếu bạn mới làm quen với async code hoặc cần ôn lại, hãy xem [hướng dẫn async xuất sắc này](https://docs.llamaindex.ai/en/stable/getting_started/async_python/). + +Giờ ta đã nắm được kiến thức cơ bản, hãy cùng xem cách sử dụng các Tools phức tạp hơn trong agent. + +## Tạo RAG Agent với QueryEngineTools + +**Agentic RAG (Tìm kiếm và tạo ra câu trả lời mang tính tác nhân) là cách mạnh mẽ để sử dụng agent trả lời câu hỏi về dữ liệu.** Ta có thể cung cấp nhiều Tools cho Alfred để hỗ trợ trả lời câu hỏi. +Thay vì tự động trả lời dựa trên tài liệu, Alfred có thể quyết định sử dụng bất kỳ Tool nào khác để đưa ra câu trả lời. + +![Agentic RAG](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/agentic-rag.png) + +Việc **biến `QueryEngine` thành một Tool** cho agent rất dễ dàng. +Khi làm vậy, ta cần **định nghĩa tên và mô tả**. LLM sẽ sử dụng thông tin này để sử dụng Tool chính xác. +Hãy xem cách tải `QueryEngineTool` từ `QueryEngine` đã tạo trong [phần components](components.mdx). + +```python +from llama_index.core.tools import QueryEngineTool + +query_engine = index.as_query_engine(llm=llm, similarity_top_k=3) # như đã trình bày trong phần Components in LlamaIndex + +query_engine_tool = QueryEngineTool.from_defaults( + query_engine=query_engine, + name="name", + description="a specific description", + return_direct=False, +) +query_engine_agent = AgentWorkflow.from_tools_or_functions( + [query_engine_tool], + llm=llm, + system_prompt="Bạn là trợ lý hữu ích có quyền truy cập vào cơ sở dữ liệu mô tả nhân vật. " +) +``` + +## Tạo hệ thống đa agent + +Lớp `AgentWorkflow` cũng hỗ trợ trực tiếp hệ thống đa agent. Bằng cách đặt tên và mô tả cho từng agent, hệ thống duy trì một speaker chính, mỗi agent có khả năng chuyển quyền điều khiển cho agent khác. + +Bằng cách thu hẹp phạm vi của từng agent, ta có thể giúp tăng độ chính xác tổng thể khi phản hồi tin nhắn người dùng. + +**Agent trong LlamaIndex cũng có thể được sử dụng trực tiếp như Tools** cho các agent khác, phục vụ các kịch bản tùy chỉnh phức tạp hơn. + +```python +from llama_index.core.agent.workflow import ( + AgentWorkflow, + FunctionAgent, + ReActAgent, +) + +# Định nghĩa một số Tools +def add(a: int, b: int) -> int: + """Cộng hai số.""" + return a + b + + +def subtract(a: int, b: int) -> int: + """Trừ hai số.""" + return a - b + + +# Tạo cấu hình agent +# LƯU Ý: ta có thể dùng FunctionAgent hoặc ReActAgent ở đây. +# FunctionAgent hoạt động với các LLM có API gọi function. +# ReActAgent hoạt động với mọi LLM. +calculator_agent = ReActAgent( + name="calculator", + description="Thực hiện các phép toán cơ bản", + system_prompt="Bạn là trợ lý máy tính. Hãy dùng Tools cho mọi phép toán.", + tools=[add, subtract], + llm=llm, +) + +query_agent = ReActAgent( + name="info_lookup", + description="Tra cứu thông tin về XYZ", + system_prompt="Sử dụng Tool để truy vấn hệ thống RAG trả lời thông tin về XYZ", + tools=[query_engine_tool], + llm=llm +) + +# Tạo và chạy workflow +agent = AgentWorkflow( + agents=[calculator_agent, query_agent], root_agent="calculator" +) + +# Chạy hệ thống +response = await agent.run(user_msg="5 cộng 3 bằng mấy?") +``` + +Chưa đủ kiến thức? Bạn có thể khám phá thêm về agent và Tools trong LlamaIndex qua Hướng dẫn cơ bản về AgentWorkflow hoặc Tài liệu học Agent, nơi bạn có thể đọc thêm về streaming, tuần tự hóa context và human-in-the-loop! + +Giờ đây khi đã hiểu cơ bản về agent và Tools trong LlamaIndex, hãy cùng xem cách sử dụng LlamaIndex để **tạo các workflow có thể cấu hình và quản lý được!** \ No newline at end of file diff --git a/units/vi/unit2/llama-index/components.mdx b/units/vi/unit2/llama-index/components.mdx new file mode 100644 index 000000000..16a0516af --- /dev/null +++ b/units/vi/unit2/llama-index/components.mdx @@ -0,0 +1,235 @@ +# Các thành phần trong LlamaIndex là gì? + +Bạn còn nhớ Alfred, Agent hỗ trợ đắc lực từ Chương 1 chứ? +Để hỗ trợ ta hiệu quả, Alfred cần hiểu yêu cầu và **chuẩn bị, tìm kiếm và sử dụng thông tin liên quan để hoàn thành nhiệm vụ.** +Đây chính là lúc các thành phần của LlamaIndex phát huy tác dụng. + +Dù LlamaIndex có nhiều thành phần, **ta sẽ tập trung vào thành phần `QueryEngine`.** +Tại sao? Vì nó có thể được dùng như công cụ Tìm kiếm và tạo ra câu trả lời (RAG) cho Agent. + +Vậy RAG là gì? LLM được huấn luyện trên lượng dữ liệu khổng lồ để học kiến thức tổng quát. +Tuy nhiên, chúng có thể không được huấn luyện trên dữ liệu mới nhất và liên quan. +RAG giải quyết vấn đề này bằng cách tìm và truy xuất thông tin liên quan từ dữ liệu của bạn để cung cấp cho LLM. + +![RAG](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/rag.png) + +Hãy xem cách Alfred hoạt động: + +1. Bạn yêu cầu Alfred lên kế hoạch tiệc tối +2. Alfred cần kiểm tra lịch trình, sở thích ăn uống và thực đơn thành công trước đó +3. `QueryEngine` giúp Alfred tìm thông tin này và sử dụng để lên kế hoạch + +Điều này khiến `QueryEngine` **trở thành thành phần chính để xây dựng workflow RAG** trong LlamaIndex. +Giống như Alfred cần tìm kiếm thông tin trong gia đình bạn, mọi Agent đều cần cách tìm và hiểu dữ liệu liên quan. +`QueryEngine` chính là giải pháp cho nhu cầu này. + +Giờ hãy cùng khám phá sâu hơn về cách **kết hợp các thành phần để tạo pipeline RAG.** + +## Tạo pipeline RAG bằng các thành phần + + +Bạn có thể theo dõi code trong notebook này và chạy qua Google Colab. + + +Có năm giai đoạn chính trong RAG, thường xuất hiện trong các ứng dụng lớn: + +1. **Loading (Tải dữ liệu)**: đưa dữ liệu từ nguồn (file text, PDF, website, database, API) vào workflow. LlamaHub cung cấp hàng trăm công cụ tích hợp. +2. **Indexing (Đánh chỉ mục)**: tạo cấu trúc dữ liệu cho phép truy vấn. Với LLM, điều này thường liên quan đến tạo embedding vector - biểu diễn số hóa ý nghĩa dữ liệu. Indexing cũng có thể bao gồm các chiến lược metadata khác. +3. **Storing (Lưu trữ)**: sau khi index, bạn cần lưu index và metadata để tránh phải index lại. +4. **Querying (Truy vấn)**: với mỗi chiến lược indexing, có nhiều cách sử dụng LLM và cấu trúc dữ liệu LlamaIndex để truy vấn, bao gồm sub-query, multi-step query và hybrid strategies. +5. **Evaluation (Đánh giá)**: bước quan trọng để kiểm tra hiệu quả workflow so với các phương pháp khác hoặc khi có thay đổi. Đánh giá cung cấp các chỉ số khách quan về độ chính xác, độ trung thực và tốc độ phản hồi. + +Tiếp theo, hãy xem cách triển khai các giai đoạn này bằng thành phần. + +### Tải và embedding tài liệu + +Như đã đề cập, LlamaIndex có thể làm việc với dữ liệu riêng, nhưng **trước khi truy cập dữ liệu, ta cần tải chúng.** +Có ba cách chính để tải dữ liệu vào LlamaIndex: + +1. `SimpleDirectoryReader`: Bộ tải tích hợp cho nhiều loại file từ thư mục local. +2. `LlamaParse`: Công cụ chính thức của LlamaIndex để phân tích PDF, có sẵn qua API. +3. `LlamaHub`: Kho lưu trữ hàng trăm thư viện tải dữ liệu từ mọi nguồn. + +Tham khảo LlamaHub loaders và LlamaParse cho các nguồn dữ liệu phức tạp. + +**Cách đơn giản nhất là dùng `SimpleDirectoryReader`.** +Thành phần linh hoạt này có thể tải nhiều loại file từ thư mục và chuyển thành đối tượng `Document` mà LlamaIndex có thể xử lý. + +```python +from llama_index.core import SimpleDirectoryReader + +reader = SimpleDirectoryReader(input_dir="path/to/directory") +documents = reader.load_data() +``` + +Sau khi tải, ta cần chia tài liệu thành các phần nhỏ gọi là `Node`. +`Node` là đoạn văn bản từ tài liệu gốc, dễ xử lý hơn cho AI, vẫn giữ tham chiếu đến `Document` gốc. + +`IngestionPipeline` giúp tạo các node này qua hai biến đổi chính: +1. `SentenceSplitter` chia tài liệu thành các đoạn nhỏ tại các điểm ngắt câu tự nhiên. +2. `HuggingFaceEmbedding` chuyển mỗi đoạn thành embedding số - biểu diễn vector phản ánh ý nghĩa ngữ nghĩa để AI xử lý hiệu quả. + +Quy trình này giúp tổ chức tài liệu theo cách hữu ích cho tìm kiếm và phân tích. + +```python +from llama_index.core import Document +from llama_index.embeddings.huggingface import HuggingFaceEmbedding +from llama_index.core.node_parser import SentenceSplitter +from llama_index.core.ingestion import IngestionPipeline + +# tạo pipeline với các biến đổi +pipeline = IngestionPipeline( + transformations=[ + SentenceSplitter(chunk_overlap=0), + HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"), + ] +) + +nodes = await pipeline.arun(documents=[Document.example()]) +``` + +### Lưu trữ và đánh chỉ mục tài liệu + +Sau khi tạo `Node`, ta cần đánh chỉ mục để tìm kiếm, nhưng trước đó cần nơi lưu trữ. + +Vì đang dùng pipeline `ingestion`, ta có thể gắn trực tiếp kho vector (vector store) vào pipeline. +Trong trường hợp này, ta dùng `Chroma` để lưu trữ. + +
+Cài đặt ChromaDB +Như đã giới thiệu trong [phần về LlamaHub](llama-hub), ta có thể cài ChromaDB vector store bằng lệnh: + +```bash +pip install llama-index-vector-stores-chroma +``` +
+ +```python +import chromadb +from llama_index.vector_stores.chroma import ChromaVectorStore + +db = chromadb.PersistentClient(path="./alfred_chroma_db") +chroma_collection = db.get_or_create_collection("alfred") +vector_store = ChromaVectorStore(chroma_collection=chroma_collection) + +pipeline = IngestionPipeline( + transformations=[ + SentenceSplitter(chunk_size=25, chunk_overlap=0), + HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"), + ], + vector_store=vector_store, +) +``` + +Tổng quan về các vector store khác có trong tài liệu LlamaIndex. + +Embedding vector giúp tìm kiếm phù hợp bằng cách embedding cả truy vấn và node trong cùng không gian vector. +`VectorStoreIndex` xử lý việc này, dùng cùng embedding model như lúc ingestion để đảm bảo tính nhất quán. + +Cách tạo index từ vector store và embedding: + +```python +from llama_index.core import VectorStoreIndex +from llama_index.embeddings.huggingface import HuggingFaceEmbedding + +embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5") +index = VectorStoreIndex.from_vector_store(vector_store, embed_model=embed_model) +``` + +Mọi thông tin tự động lưu trong `ChromaVectorStore` và đường dẫn đã chỉ định. + +Giờ ta đã có thể lưu và tải index dễ dàng, hãy khám phá cách truy vấn nó. + +### Truy vấn VectorStoreIndex với prompt và LLM + +Trước khi truy vấn, ta cần chuyển index thành giao diện truy vấn. Các tùy chọn phổ biến: + +- `as_retriever`: Cho truy xuất tài liệu cơ bản, trả về danh sách `NodeWithScore` với điểm tương đồng +- `as_query_engine`: Cho tương tác hỏi-đáp đơn, trả về phản hồi dạng văn bản +- `as_chat_engine`: Cho hội thoại có ghi nhớ lịch sử, trả về phản hồi sử dụng cả ngữ cảnh và lịch sử chat + +Ta tập trung vào query engine vì phổ biến hơn cho tương tác kiểu Agent. +Ta cũng truyền LLM vào query engine để tạo phản hồi. + +```python +from llama_index.LLM.huggingface_api import HuggingFaceInferenceAPI + +llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct") +query_engine = index.as_query_engine( + llm=llm, + response_mode="tree_summarize", +) +query_engine.query("What is the meaning of life?") +# The meaning of life is 42 +``` + +### Xử lý phản hồi + +Bên dưới, query engine không chỉ dùng LLM để trả lời mà còn sử dụng `ResponseSynthesizer` làm chiến lược xử lý phản hồi. +Có ba chiến lược chính hoạt động tốt: + +- `refine`: Tạo và tinh chỉnh câu trả lời bằng cách xử lý tuần tự từng text chunk. Mỗi Node/chunk sẽ gọi LLM riêng. +- `compact` (mặc định): Tương tự refine nhưng nối các chunk trước, giảm số lần gọi LLM. +- `tree_summarize`: Tạo câu trả lời chi tiết bằng cách xây dựng cấu trúc cây từ các chunk. + +Kiểm soát chi tiết workflow truy vấn với low-level composition API. API này cho phép tùy chỉnh từng bước truy vấn, kết hợp tốt với Workflows. + +LLM không phải lúc nào cũng cho kết quả chính xác, nên ta cần **đánh giá chất lượng câu trả lời**. + +### Đánh giá và quan sát + +LlamaIndex cung cấp **công cụ đánh giá tích hợp** để kiểm tra chất lượng phản hồi. +Các công cụ đánh giá này sử dụng LLM để phân tích phản hồi trên nhiều khía cạnh. Ba công cụ đánh giá chính: + +- `FaithfulnessEvaluator`: Kiểm tra tính trung thực của câu trả lời so với ngữ cảnh. +- `AnswerRelevancyEvaluator`: Đánh giá mức độ liên quan của câu trả lời với câu hỏi. +- `CorrectnessEvaluator`: Kiểm tra tính chính xác của câu trả lời. + +```python +from llama_index.core.evaluation import FaithfulnessEvaluator + +query_engine = # từ phần trước +llm = # từ phần trước + +# truy vấn index +evaluator = FaithfulnessEvaluator(llm=llm) +response = query_engine.query( + "What battles took place in New York City in the American Revolution?" +) +eval_result = evaluator.evaluate_response(response=response) +eval_result.passing +``` + +Ngay cả khi không đánh giá trực tiếp, ta có thể **hiểu rõ hiệu suất hệ thống qua quan sát.** +Điều này đặc biệt hữu ích khi xây dựng workflow phức tạp và muốn hiểu cách từng thành phần hoạt động. + +
+Cài đặt LlamaTrace +Như đã giới thiệu trong [phần về LlamaHub](llama-hub), ta cài LlamaTrace callback từ Arize Phoenix bằng lệnh: + +```bash +pip install -U llama-index-callbacks-arize-phoenix +``` + +Cần thiết lập biến môi trường `PHOENIX_API_KEY` bằng API key từ LlamaTrace. Cách lấy key: +- Tạo tài khoản tại [LlamaTrace](https://llamatrace.com/login) +- Tạo API key trong phần cài đặt tài khoản +- Dùng API key trong code để kích hoạt tracing + +
+ +```python +import llama_index +import os + +PHOENIX_API_KEY = "" +os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"api_key={PHOENIX_API_KEY}" +llama_index.core.set_global_handler( + "arize_phoenix", + endpoint="https://llamatrace.com/v1/traces" +) +``` + +Muốn tìm hiểu thêm về thành phần và cách sử dụng? Khám phá Hướng dẫn thành phần hoặc Hướng dẫn RAG. + +Ta đã thấy cách dùng thành phần để tạo `QueryEngine`. Giờ hãy xem cách **dùng `QueryEngine` làm công cụ cho Agent!** \ No newline at end of file diff --git a/units/vi/unit2/llama-index/conclusion.mdx b/units/vi/unit2/llama-index/conclusion.mdx new file mode 100644 index 000000000..92782b81c --- /dev/null +++ b/units/vi/unit2/llama-index/conclusion.mdx @@ -0,0 +1,13 @@ +# Kết luận + +Chúc mừng các bạn đã hoàn thành Mô-đun `llama-index` của Chương thứ hai 🥳 + +Bạn đã nắm vững kiến thức cơ bản về `llama-index` và biết cách xây dựng các agentic workflows của riêng mình! +Giờ đây với kỹ năng sử dụng `llama-index`, bạn có thể bắt đầu tạo các công cụ tìm kiếm giải quyết những bài toán mình quan tâm. + +Trong Mô-đun tiếp theo của Chương này, chúng ta sẽ học **cách xây dựng Agents với LangGraph**. + +Cuối cùng, chúng mình rất mong nhận được **ý kiến đóng góp của bạn về khóa học và cách cải thiện nội dung**. +Nếu có phản hồi, hãy 👉 [điền vào form này](https://docs.google.com/forms/d/e/1FAIpQLSe9VaONn0eglax0uTwi29rIn4tM7H2sYmmybmG5jJNlE5v0xA/viewform?usp=dialog) + +### Hãy tiếp tục học tập và luôn tuyệt vời nhé 🤗 \ No newline at end of file diff --git a/units/vi/unit2/llama-index/introduction.mdx b/units/vi/unit2/llama-index/introduction.mdx new file mode 100644 index 000000000..6756a098c --- /dev/null +++ b/units/vi/unit2/llama-index/introduction.mdx @@ -0,0 +1,27 @@ +# Giới thiệu về LlamaIndex + +Chào mừng bạn đến với mô-đun này, nơi bạn sẽ học cách xây dựng Agent sử dụng LLM với bộ công cụ [LlamaIndex](https://www.llamaindex.ai/). + +LlamaIndex là **bộ công cụ hoàn chỉnh để tạo Agent sử dụng LLM trên dữ liệu của bạn thông qua các chỉ mục và quy trình làm việc**. Trong khóa học này, chúng ta sẽ tập trung vào ba phần chính giúp xây dựng Agent trong LlamaIndex: **Components** (Thành phần), **Agents and Tools** (Tác nhân và Công cụ) và **Workflows** (Quy trình làm việc). + +![LlamaIndex](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/thumbnail.png) + +Hãy cùng xem các phần quan trọng này của LlamaIndex và cách chúng hỗ trợ Agent: + +- **Component** hay thành phần là các khối xây dựng cơ bản trong LlamaIndex. Chúng bao gồm các yếu tố như prompt, model và cơ sở dữ liệu. Các thành phần thường giúp kết nối LlamaIndex với các công cụ và thư viện khác. +- **Tool** hay công cụ là các thành phần cung cấp khả năng chuyên biệt như tìm kiếm, tính toán hoặc truy cập dịch vụ bên ngoài. Chúng là nền tảng giúp Agent thực hiện các tác vụ. +- **Agent** hay tác nhân là các thành phần tự trị có thể sử dụng công cụ và đưa ra quyết định. Chúng phối hợp sử dụng công cụ để đạt được mục tiêu phức tạp. +- **Workflow** hay quy trình làm việc là các quy trình từng bước xử lý logic cùng nhau. Workflow (hoặc agentic workflow) là cách cấu trúc hành vi của Agent mà không cần sử dụng Agent một cách tường minh. + +## Điều gì làm nên sự khác biệt của LlamaIndex? + +Dù LlamaIndex có một số điểm tương đồng với các framework khác như smolagents (một framework nhỏ gọn để xây dựng Agent), nó có những ưu điểm chính: + +- **Hệ thống Workflow rõ ràng**. Workflow giúp phân tách cách Agent đưa ra quyết định từng bước bằng cú pháp ưu tiên sự kiện và bất đồng bộ. Điều này giúp bạn tổ chức và sắp xếp logic một cách rõ ràng. +- **Phân tích tài liệu nâng cao với LlamaParse** LlamaParse được tạo riêng cho LlamaIndex nên tích hợp liền mạch, dù đây là tính năng trả phí. +- **Nhiều thành phần sẵn có** LlamaIndex đã tồn tại một thời gian nên tương thích với nhiều framework khác. Điều này có nghĩa nó sở hữu nhiều thành phần đã được kiểm nghiệm như LLMs, retrievers, indexes... +- **LlamaHub** là kho lưu trữ hàng trăm thành phần, Agent và công cụ mà bạn có thể sử dụng trong LlamaIndex. + +Tất cả các khái niệm này đều cần thiết trong các kịch bản khác nhau để tạo ra Agent hữu ích. Trong các phần tiếp theo, chúng ta sẽ đi sâu vào từng khái niệm. Sau khi nắm vững lý thuyết, chúng mình sẽ áp dụng kiến thức để **tạo các use case thực tế với Agent Alfred**! + +Được trực tiếp làm việc với LlamaIndex thật thú vị phải không nào? Vậy còn chờ gì nữa? Hãy cùng bắt đầu với **tìm và cài đặt các tích hợp cần thiết qua LlamaHub thôi! 🚀** \ No newline at end of file diff --git a/units/vi/unit2/llama-index/llama-hub.mdx b/units/vi/unit2/llama-index/llama-hub.mdx new file mode 100644 index 000000000..b856e4588 --- /dev/null +++ b/units/vi/unit2/llama-index/llama-hub.mdx @@ -0,0 +1,46 @@ +# Giới thiệu về LlamaHub + +**LlamaHub là một kho lưu trữ hàng trăm tích hợp, agent và các tool mà bạn có thể sử dụng trong LlamaIndex.** + +![LlamaHub](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/llama-hub.png) + +Chúng ta sẽ sử dụng nhiều tích hợp trong khóa học này, vì vậy hãy cùng xem qua LlamaHub và cách nó có thể hỗ trợ chúng ta. + +Hãy cùng tìm hiểu cách tìm và cài đặt các dependencies cho các thành phần cần thiết. + +## Cài đặt + +Hướng dẫn cài đặt LlamaIndex được cung cấp dưới dạng tổng quan chi tiết trên **[LlamaHub](https://llamahub.ai/)**. +Ban đầu có thể hơi choáng ngợp, nhưng hầu hết **câu lệnh cài đặt đều tuân theo định dạng dễ nhớ**: + +```bash +pip install llama-index-{component-type}-{framework-name} +``` + +Hãy thử cài đặt dependencies cho LLM và thành phần nhúng sử dụng [Tích hợp API luận suy của Hugging Face](https://llamahub.ai/l/llms/llama-index-llms-huggingface-api?from=llms). + +```bash +pip install llama-index-llms-huggingface-api llama-index-embeddings-huggingface +``` + +## Cách sử dụng + +Sau khi cài đặt, ta có thể xem cách sử dụng. Bạn sẽ nhận thấy đường dẫn import tuân theo cú pháp lệnh cài đặt! +Dưới đây là ví dụ về cách sử dụng **Tích hợp API luận suy của Hugging Face cho các thành phần LLM**. + +```python +from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI + +llm = HuggingFaceInferenceAPI( + model_name="Qwen/Qwen2.5-Coder-32B-Instruct", + temperature=0.7, + max_tokens=100, + token="hf_xxx", +) + +llm.complete("Hello, how are you?") +# Tôi khỏe, tôi có thể giúp gì cho bạn hôm nay? +``` + +Tuyệt vời, giờ chúng ta đã biết cách tìm kiếm, cài đặt và sử dụng các tích hợp cho các thành phần cần thiết. +**Hãy cùng đi sâu vào các thành phần** và xem cách sử dụng chúng để xây dựng agent của riêng mình. \ No newline at end of file diff --git a/units/vi/unit2/llama-index/quiz1.mdx b/units/vi/unit2/llama-index/quiz1.mdx new file mode 100644 index 000000000..41786ebaa --- /dev/null +++ b/units/vi/unit2/llama-index/quiz1.mdx @@ -0,0 +1,115 @@ +# Câu đố nhỏ (không tính điểm) [[quiz1]] + +Đến thời điểm hiện tại, ta đã thảo luận về các thành phần chính và công cụ được sử dụng trong LlamaIndex. Đã đến lúc làm một bài kiểm tra ngắn vì **tự kiểm tra** là cách học hiệu quả nhất và [tránh ảo tưởng về năng lực](https://www.coursera.org/lecture/learning-how-to-learn/illusions-of-competence-BuFzf). Bài tập này sẽ giúp bạn xác định **phần kiến thức cần củng cố**. + +Đây là bài kiểm tra không bắt buộc và không tính điểm. + +### Q1: QueryEngine là gì? +Đâu là mô tả chính xác nhất về thành phần QueryEngine? + + + +--- + +### Q2: Mục đích của FunctionTools là gì? +Tại sao FunctionTools quan trọng với Agent? + + + +--- + +### Q3: Toolspecs trong LlamaIndex là gì? +Mục đích chính của Toolspecs là gì? + + + +--- + +### Q4: Yêu cầu tạo một tool +Thông tin nào BẮT BUỘC khi tạo một tool? + + + +--- + +Chúc mừng bạn đã hoàn thành bài kiểm tra 🥳! Nếu có phần chưa đúng, hãy dành thời gian đọc lại chương để củng cố kiến thức. Nếu đã vượt qua, bạn đã sẵn sàng khám phá sâu hơn về cách xây dựng với các thành phần này! \ No newline at end of file diff --git a/units/vi/unit2/llama-index/quiz2.mdx b/units/vi/unit2/llama-index/quiz2.mdx new file mode 100644 index 000000000..298c64565 --- /dev/null +++ b/units/vi/unit2/llama-index/quiz2.mdx @@ -0,0 +1,111 @@ +# Kiểm tra nhanh (không chấm điểm) [[quiz2]] + +Gì nữa? Lại một bài kiểm tra ư? Chúng mình biết, chúng mình biết... 😅 Nhưng bài kiểm tra ngắn không chấm điểm này sẽ **giúp bạn củng cố các khái niệm quan trọng** vừa học. + +Bài kiểm tra này tập trung vào workflow và tương tác của Agent - những thành phần thiết yếu để xây dựng các AI Agent hiệu quả. + +### Câu 1: Mục đích của AgentWorkflow trong LlamaIndex là gì? + + + +--- + +### Câu 2: Đối tượng nào được dùng để theo dõi trạng thái của workflow? + + + +--- + +### Câu 3: Phương thức nào nên dùng nếu muốn agent ghi nhớ các tương tác trước đó? + + + +--- + +### Câu 4: Tính năng chính của Agentic RAG là gì? + + + +--- + +Hiểu rồi chứ? Tuyệt! Giờ thì hãy cùng **tóm tắt nhanh Chương này** nhé! \ No newline at end of file diff --git a/units/vi/unit2/llama-index/tools.mdx b/units/vi/unit2/llama-index/tools.mdx new file mode 100644 index 000000000..7b3f74067 --- /dev/null +++ b/units/vi/unit2/llama-index/tools.mdx @@ -0,0 +1,111 @@ +# Sử dụng Tools trong LlamaIndex + +**Việc định nghĩa một bộ Tools rõ ràng là yếu tố quan trọng cho hiệu suất.** Như đã thảo luận trong [chương 1](../../unit1/tools), các giao diện tool rõ ràng giúp LLM dễ sử dụng hơn. +Giống như giao diện API phần mềm cho kỹ sư, chúng có thể tận dụng tool tốt hơn nếu hiểu cách hoạt động của nó. + +LlamaIndex có **bốn loại tool chính**: + +![Tools](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/tools.png) + +1. `FunctionTool`: Biến mọi hàm Python thành tool cho Agent. Nó tự động hiểu cách hàm hoạt động. +2. `QueryEngineTool`: Cho phép Agent sử dụng query engine. Vì Agent được xây dựng trên query engine, chúng có thể dùng các Agent khác như tool. +3. `Toolspecs`: Bộ tool do cộng đồng tạo ra, thường bao gồm tool cho dịch vụ cụ thể như Gmail. +4. `Utility Tools`: Tool đặc biệt giúp xử lý lượng dữ liệu lớn từ tool khác. + +Chúng ta sẽ đi vào chi tiết từng loại bên dưới. + +## Tạo FunctionTool + + +Bạn có thể theo dõi code trong notebook này và chạy qua Google Colab. + + +FunctionTool cung cấp cách đơn giản để bao bọc hàm Python thành tool cho Agent. +Bạn có thể truyền hàm đồng bộ hoặc bất đồng bộ vào tool, cùng các tham số tùy chọn `name` và `description`. +Tên và mô tả đặc biệt quan trọng vì giúp Agent hiểu khi nào và cách sử dụng tool hiệu quả. +Hãy xem cách tạo FunctionTool và gọi nó: + +```python +from llama_index.core.tools import FunctionTool + +def get_weather(location: str) -> str: + """Hữu ích để lấy thông tin thời tiết cho một địa điểm cụ thể.""" + print(f"Getting weather for {location}") + return f"The weather in {location} is sunny" + +tool = FunctionTool.from_defaults( + get_weather, + name="my_weather_tool", + description="Hữu ích để lấy thông tin thời tiết cho một địa điểm cụ thể.", +) +tool.call("New York") +``` + +Khi dùng Agent hoặc LLM với function calling, tool được chọn (và các đối số) phụ thuộc nhiều vào tên tool và mô tả mục đích/đối số. Tìm hiểu thêm trong [Hướng Dẫn Function Calling](https://docs.llamaindex.ai/en/stable/module_guides/deploying/agents/modules/function_calling.html) và [Hướng Dẫn Học Function Calling](https://docs.llamaindex.ai/en/stable/understanding/agent/function_calling.html). + +## Tạo QueryEngineTool + +`QueryEngine` đã định nghĩa ở chương trước có thể dễ dàng biến thành tool bằng lớp `QueryEngineTool`. +Xem cách tạo `QueryEngineTool` từ `QueryEngine` trong ví dụ: + +```python +from llama_index.core import VectorStoreIndex +from llama_index.core.tools import QueryEngineTool +from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI +from llama_index.embeddings.huggingface import HuggingFaceEmbedding +from llama_index.vector_stores.chroma import ChromaVectorStore + +embed_model = HuggingFaceEmbedding("BAAI/bge-small-en-v1.5") + +db = chromadb.PersistentClient(path="./alfred_chroma_db") +chroma_collection = db.get_or_create_collection("alfred") +vector_store = ChromaVectorStore(chroma_collection=chroma_collection) + +index = VectorStoreIndex.from_vector_store(vector_store, embed_model=embed_model) + +llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct") +query_engine = index.as_query_engine(llm=llm) +tool = QueryEngineTool.from_defaults(query_engine, name="some useful name", description="some useful description") +``` + +## Tạo Toolspecs + +Hãy coi `ToolSpecs` như bộ sưu tập tool hoạt động hài hòa - giống bộ toolkit chuyên nghiệp được tổ chức tốt. +Như bộ tool sửa chữa xe chứa các công cụ bổ trợ, `ToolSpec` kết hợp các tool liên quan cho mục đích cụ thể. +Ví dụ: `ToolSpec` cho Agent kế toán có thể tích hợp khả năng bảng tính, email và công cụ tính toán để xử lý tài chính chính xác. + +
+Cài đặt Google Toolspec +Như đã giới thiệu trong [phần LlamaHub](llama-hub), ta cài Google toolspec bằng lệnh: + +```python +pip install llama-index-tools-google +``` +
+ +Giờ ta có thể load toolspec và chuyển thành danh sách tool: + +```python +from llama_index.tools.google import GmailToolSpec + +tool_spec = GmailToolSpec() +tool_spec_list = tool_spec.to_tool_list() +``` + +Để xem chi tiết hơn về các tool, ta có thể kiểm tra `metadata` của từng tool: + +```python +[(tool.metadata.name, tool.metadata.description) for tool in tool_spec_list] +``` + +## Utility Tools + +Thường thì việc truy vấn trực tiếp API **có thể trả về quá nhiều dữ liệu**, một phần có thể không liên quan, vượt quá context window của LLM hoặc làm tăng token không cần thiết. +Hãy xem qua hai utility tool chính: + +1. `OnDemandToolLoader`: Biến mọi LlamaIndex data loader (lớp BaseReader) thành tool cho Agent. Tool được gọi với mọi tham số cần thiết để kích hoạt `load_data` từ data loader, cùng chuỗi truy vấn ngôn ngữ tự nhiên. Trong quá trình chạy, đầu tiên ta load dữ liệu từ data loader, index nó (ví dụ với vector store), rồi truy vấn 'theo yêu cầu'. Cả ba bước này diễn ra trong một lần gọi tool. +2. `LoadAndSearchToolSpec`: Nhận bất kỳ Tool nào làm input. Khi gọi `to_tool_list`, nó trả về hai tool: tool load và tool search. Tool load sẽ gọi Tool cơ bản và index kết quả (mặc định bằng vector index). Tool search nhận chuỗi truy vấn và gọi index cơ bản. + +Bạn có thể tìm toolspecs và utility tools trên LlamaHub + +Bây giờ chúng ta đã hiểu cơ bản về agents và tools trong LlamaIndex, hãy xem cách **dùng LlamaIndex để tạo workflow có thể cấu hình và quản lý được!** \ No newline at end of file diff --git a/units/vi/unit2/llama-index/workflows.mdx b/units/vi/unit2/llama-index/workflows.mdx new file mode 100644 index 000000000..5e8ea8031 --- /dev/null +++ b/units/vi/unit2/llama-index/workflows.mdx @@ -0,0 +1,269 @@ +# Tạo Agentic Workflow trong LlamaIndex + +Một workflow trong LlamaIndex cung cấp cách có cấu trúc để tổ chức mã nguồn của bạn thành các bước tuần tự và quản lý được. + +Workflow được tạo bằng cách định nghĩa các `Steps` (bước) được kích hoạt bởi `Events` (sự kiện), và chính chúng phát ra `Events` để kích hoạt các bước tiếp theo. Hãy xem Alfred minh họa một workflow LlamaIndex cho tác vụ RAG (Tìm kiếm và tạo ra câu trả lời). + +![Sơ đồ workflow](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/workflows.png) + +**Workflow mang lại những lợi ích chính:** + +- Tổ chức mã nguồn rõ ràng thành các bước riêng biệt +- Kiến trúc hướng sự kiện để kiểm soát luồng linh hoạt +- Giao tiếp an toàn kiểu dữ liệu giữa các bước +- Quản lý trạng thái tích hợp sẵn +- Hỗ trợ cả tương tác tác nhân đơn giản và phức tạp + +Như bạn có thể đoán, **workflow tạo ra sự cân bằng tuyệt vời giữa tính tự chủ của các Agent (tác nhân) trong khi vẫn duy trì kiểm soát toàn bộ quy trình.** + +Vậy hãy cùng học cách tạo workflow nào! + +## Tạo Workflow + + +Bạn có thể theo dõi mã nguồn trong notebook này và chạy bằng Google Colab. + + +### Tạo Workflow cơ bản + +
+Cài đặt gói Workflow +Như đã giới thiệu trong [phần về LlamaHub](llama-hub), ta có thể cài đặt gói Workflow bằng lệnh: + +```python +pip install llama-index-utils-workflow +``` +
+ +Ta có thể tạo workflow một bước bằng cách định nghĩa lớp kế thừa từ `Workflow` và trang trí hàm bằng `@step`. Chúng mình cũng cần thêm `StartEvent` và `StopEvent` - các sự kiện đặc biệt để chỉ định điểm bắt đầu và kết thúc workflow. + +```python +from llama_index.core.workflow import StartEvent, StopEvent, Workflow, step + +class MyWorkflow(Workflow): + @step + async def my_step(self, ev: StartEvent) -> StopEvent: + # thực hiện một số thao tác ở đây + return StopEvent(result="Xin chào thế giới!") + + +w = MyWorkflow(timeout=10, verbose=False) +result = await w.run() +``` + +Như bạn thấy, giờ ta có thể chạy workflow bằng cách gọi `w.run()`. + +### Kết nối nhiều bước + +Để kết nối nhiều bước, ta **tạo các sự kiện tùy chỉnh mang dữ liệu giữa các bước.** Cần thêm `Event` truyền giữa các bước và chuyển kết quả từ bước đầu sang bước sau. + +```python +from llama_index.core.workflow import Event + +class ProcessingEvent(Event): + intermediate_result: str + +class MultiStepWorkflow(Workflow): + @step + async def step_one(self, ev: StartEvent) -> ProcessingEvent: + # Xử lý dữ liệu ban đầu + return ProcessingEvent(intermediate_result="Bước 1 hoàn thành") + + @step + async def step_two(self, ev: ProcessingEvent) -> StopEvent: + # Sử dụng kết quả trung gian + final_result = f"Xử lý xong: {ev.intermediate_result}" + return StopEvent(result=final_result) + +w = MultiStepWorkflow(timeout=10, verbose=False) +result = await w.run() +result +``` + +Việc gợi ý kiểu dữ liệu ở đây rất quan trọng để đảm bảo workflow chạy đúng. Hãy thử làm phức tạp hơn một chút! + +### Vòng lặp và nhánh + +Gợi ý kiểu dữ liệu là phần mạnh mẽ nhất của workflow vì cho phép tạo nhánh, vòng lặp và điểm giao để xây dựng workflow phức tạp. + +Hãy xem ví dụ **tạo vòng lặp** bằng toán tử union `|`. Trong ví dụ dưới, `LoopEvent` được dùng làm đầu vào cho bước và cũng có thể trả về làm đầu ra. + +```python +from llama_index.core.workflow import Event +import random + + +class ProcessingEvent(Event): + intermediate_result: str + + +class LoopEvent(Event): + loop_output: str + + +class MultiStepWorkflow(Workflow): + @step + async def step_one(self, ev: StartEvent | LoopEvent) -> ProcessingEvent | LoopEvent: + if random.randint(0, 1) == 0: + print("Điều xấu xảy ra") + return LoopEvent(loop_output="Quay lại bước một.") + else: + print("Điều tốt xảy ra") + return ProcessingEvent(intermediate_result="Bước đầu hoàn thành.") + + @step + async def step_two(self, ev: ProcessingEvent) -> StopEvent: + # Sử dụng kết quả trung gian + final_result = f"Xử lý xong: {ev.intermediate_result}" + return StopEvent(result=final_result) + + +w = MultiStepWorkflow(verbose=False) +result = await w.run() +result +``` + +### Vẽ workflow + +Ta cũng có thể vẽ workflow. Hãy dùng hàm `draw_all_possible_flows` để vẽ workflow và lưu vào file HTML. + +```python +from llama_index.utils.workflow import draw_all_possible_flows + +w = ... # như định nghĩa ở phần trước +draw_all_possible_flows(w, "flow.html") +``` + +![Vẽ workflow](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/workflow-draw.png) + +Còn một mẹo thú vị cuối cùng mà chúng ta sẽ học trong khóa học này - khả năng thêm trạng thái vào workflow. + +### Quản lý trạng thái + +Quản lý trạng thái hữu ích khi bạn muốn theo dõi trạng thái workflow để mọi bước đều truy cập được cùng trạng thái. Ta có thể làm điều này bằng cách dùng gợi ý kiểu `Context` cho tham số trong hàm bước. + +```python +from llama_index.core.workflow import Context, StartEvent, StopEvent + + +@step +async def query(self, ctx: Context, ev: StartEvent) -> StopEvent: + # lưu truy vấn vào context + await ctx.set("query", "Thủ đô của Pháp là gì?") + + # thực hiện gì đó với context và sự kiện + val = ... + + # lấy truy vấn từ context + query = await ctx.get("query") + + return StopEvent(result=val) +``` + +Tuyệt vời! Giờ bạn đã biết cách tạo workflow cơ bản trong LlamaIndex! + +Bạn có thể tìm hiểu thêm về các chi tiết phức tạp của workflow trong tài liệu LlamaIndex. + +Tuy nhiên có một cách khác để tạo workflow bằng lớp `AgentWorkflow`. Hãy cùng xem cách dùng lớp này để tạo workflow đa tác nhân. + +## Tự động hóa workflow với Multi-Agent Workflow + +Thay vì tạo workflow thủ công, ta có thể dùng **lớp `AgentWorkflow` để tạo workflow đa tác nhân**. `AgentWorkflow` sử dụng Workflow Agents cho phép tạo hệ thống gồm một hoặc nhiều Agent (tác nhân) có thể hợp tác và chuyển giao tác vụ dựa trên khả năng chuyên biệt. Điều này giúp xây dựng hệ thống Agent phức tạp với các Agent xử lý các khía cạnh khác nhau của tác vụ. Thay vì import các lớp từ `llama_index.core.agent`, ta sẽ import các lớp Agent từ `llama_index.core.agent.workflow`. Một Agent phải được chỉ định là root agent trong hàm khởi tạo `AgentWorkflow`. Khi người dùng gửi tin nhắn, nó sẽ được chuyển đến root agent đầu tiên. + +Mỗi Agent có thể: + +- Xử lý trực tiếp yêu cầu bằng Tools của họ +- Chuyển giao cho Agent khác phù hợp hơn +- Trả lời người dùng + +Hãy xem cách tạo workflow đa tác nhân. + +```python +from llama_index.core.agent.workflow import AgentWorkflow, ReActAgent +from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI + +# Định nghĩa một số công cụ +def add(a: int, b: int) -> int: + """Cộng hai số.""" + return a + b + +def multiply(a: int, b: int) -> int: + """Nhân hai số.""" + return a * b + +llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct") + +# có thể truyền hàm trực tiếp mà không cần FunctionTool - tên/mô tả sẽ được phân tích từ hàm/docstring +multiply_agent = ReActAgent( + name="multiply_agent", + description="Có thể nhân hai số nguyên", + system_prompt="Trợ lý hữu ích có thể dùng công cụ để nhân số.", + tools=[multiply], + llm=llm, +) + +addition_agent = ReActAgent( + name="add_agent", + description="Có thể cộng hai số nguyên", + system_prompt="Trợ lý hữu ích có thể dùng công cụ để cộng số.", + tools=[add], + llm=llm, +) + +# Tạo workflow +workflow = AgentWorkflow( + agents=[multiply_agent, addition_agent], + root_agent="multiply_agent", +) + +# Chạy hệ thống +response = await workflow.run(user_msg="Bạn có thể cộng 5 và 3 không?") +``` + +Các Tools của Agent cũng có thể chỉnh sửa trạng thái workflow đã đề cập. Trước khi bắt đầu workflow, ta có thể cung cấp state dict ban đầu để tất cả Agent truy cập. Trạng thái được lưu trong key state của workflow context và sẽ được đưa vào state_prompt để bổ sung cho mỗi tin nhắn người dùng mới. + +Hãy thêm bộ đếm số lần gọi hàm bằng cách sửa ví dụ trước: + +```python +from llama_index.core.workflow import Context + +# Định nghĩa một số công cụ +async def add(ctx: Context, a: int, b: int) -> int: + """Cộng hai số.""" + # cập nhật bộ đếm + cur_state = await ctx.get("state") + cur_state["num_fn_calls"] += 1 + await ctx.set("state", cur_state) + + return a + b + +async def multiply(ctx: Context, a: int, b: int) -> int: + """Nhân hai số.""" + # cập nhật bộ đếm + cur_state = await ctx.get("state") + cur_state["num_fn_calls"] += 1 + await ctx.set("state", cur_state) + + return a * b + +... + +workflow = AgentWorkflow( + agents=[multiply_agent, addition_agent], + root_agent="multiply_agent" + initial_state={"num_fn_calls": 0}, + state_prompt="Trạng thái hiện tại: {state}. Tin nhắn người dùng: {msg}", +) + +# chạy workflow với context +ctx = Context(workflow) +response = await workflow.run(user_msg="Bạn có thể cộng 5 và 3 không?", ctx=ctx) + +# lấy và kiểm tra trạng thái +state = await ctx.get("state") +print(state["num_fn_calls"]) +``` + +Chúc mừng bạn đã nắm vững kiến thức cơ bản về Agent trong LlamaIndex! 🎉 + +Hãy cùng làm bài Kiểm tra nhanh cuối cùng để củng cố kiến thức! 🚀 \ No newline at end of file diff --git a/units/vi/unit2/smolagents/code_agents.mdx b/units/vi/unit2/smolagents/code_agents.mdx new file mode 100644 index 000000000..cd6d19d70 --- /dev/null +++ b/units/vi/unit2/smolagents/code_agents.mdx @@ -0,0 +1,386 @@ + + +# Xây dựng Agent sử dụng code + +Code Agent là loại Agent mặc định trong `smolagents`. Chúng tạo ra các lệnh gọi công cụ Python để thực hiện hành động, đạt được biểu diễn hành động hiệu quả, biểu cảm và chính xác. + +Cách tiếp cận tối giản này giúp giảm số lượng hành động cần thiết, đơn giản hóa các thao tác phức tạp và cho phép tái sử dụng các hàm code có sẵn. `smolagents` cung cấp một framework nhẹ để xây dựng code agent, được triển khai trong khoảng 1,000 dòng code. + +![Hành động dạng code so với JSON](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/code_vs_json_actions.png) +Đồ họa từ bài báo [Executable Code Actions Elicit Better LLM Agents](https://huggingface.co/papers/2402.01030) + + +Nếu muốn tìm hiểu thêm về lý do code agent hiệu quả, hãy xem hướng dẫn này từ tài liệu smolagents. + + +## Tại sao nên dùng Code Agent? + +Trong quy trình đa bước của Agent, LLM viết và thực thi các hành động, thường liên quan đến lệnh gọi công cụ bên ngoài. Cách tiếp cận truyền thống sử dụng định dạng JSON để chỉ định tên công cụ và đối số dưới dạng chuỗi, **mà hệ thống phải phân tích để xác định công cụ cần thực thi**. + +Tuy nhiên, nghiên cứu cho thấy **LLM thực thi công cụ hoạt động hiệu quả hơn khi làm việc trực tiếp với code**. Đây là nguyên lý cốt lõi của `smolagents`, như minh họa trong biểu đồ trên từ [Executable Code Actions Elicit Better LLM Agents](https://huggingface.co/papers/2402.01030). + +Viết hành động bằng code thay vì JSON mang lại nhiều lợi thế chính: + +* **Khả năng kết hợp**: Dễ dàng kết hợp và tái sử dụng hành động +* **Quản lý đối tượng**: Làm việc trực tiếp với các cấu trúc phức tạp như hình ảnh +* **Tính tổng quát**: Biểu diễn mọi tác vụ có thể tính toán được +* **Tự nhiên với LLM**: Dữ liệu training của LLM đã chứa code chất lượng cao + +## Code Agent hoạt động thế nào? + +![Từ https://huggingface.co/docs/smolagents/conceptual_guides/react](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smolagents/codeagent_docs.png) + +Biểu đồ trên minh họa cách `CodeAgent.run()` hoạt động, theo framework ReAct mà ta đã đề cập ở Chương 1. Khái niệm chính cho Agent trong `smolagents` là `MultiStepAgent`, đóng vai trò là khối xây dựng cốt lõi. `CodeAgent` là một dạng đặc biệt của `MultiStepAgent`, như ta sẽ thấy trong ví dụ dưới đây. + +Một `CodeAgent` thực hiện hành động thông qua chu trình các bước, với các biến và kiến thức hiện có được tích hợp vào ngữ cảnh của Agent, được lưu trong nhật ký thực thi: + +1. Prompt hệ thống được lưu trong `SystemPromptStep`, và truy vấn người dùng được ghi lại trong `TaskStep`. + +2. Sau đó, vòng lặp while sau được thực thi: + + 2.1 Phương thức `agent.write_memory_to_messages()` ghi nhật ký của Agent vào danh sách [tin nhắn chat](https://huggingface.co/docs/transformers/main/en/chat_templating) mà LLM có thể đọc được. + + 2.2 Các tin nhắn này được gửi tới `Model`, nơi tạo ra phần hoàn thành. + + 2.3 Phần hoàn thành được phân tích để trích xuất hành động, trong trường hợp của chúng ta nên là một đoạn code vì ta đang làm việc với `CodeAgent`. + + 2.4 Hành động được thực thi. + + 2.5 Kết quả được ghi vào bộ nhớ trong `ActionStep`. + +Cuối mỗi bước, nếu Agent chứa bất kỳ lệnh gọi hàm nào (trong `agent.step_callback`), chúng sẽ được thực thi. + +## Cùng xem ví dụ + + +Bạn có thể theo dõi code trong notebook này và chạy bằng Google Colab. + + +Alfred đang lên kế hoạch tổ chức tiệc tại biệt thự gia đình Wayne và cần bạn giúp đảm bảo mọi thứ diễn ra suôn sẻ. Để hỗ trợ anh ấy, chúng ta sẽ áp dụng những gì đã học về cách hoạt động của `CodeAgent` đa bước. + +Alfred tổ chức tiệc + +Nếu chưa cài đặt `smolagents`, bạn có thể chạy lệnh sau: + +```bash +pip install smolagents -U +``` + +Đồng thời đăng nhập vào Hugging Face Hub để truy cập Serverless Inference API. + +```python +from huggingface_hub import login + +login() +``` + +### Lựa chọn playlist cho bữa tiệc bằng `smolagents` + +Âm nhạc là phần thiết yếu của một bữa tiệc thành công! Alfred cần giúp đỡ để chọn playlist. May mắn thay, `smolagents` đã có sẵn giải pháp! Chúng ta có thể xây dựng một Agent có khả năng tìm kiếm web bằng DuckDuckGo. Để cấp quyền truy cập công cụ này cho Agent, chúng ta thêm nó vào danh sách công cụ khi tạo Agent. + +Alfred chọn playlist + +Về mô hình, chúng ta sẽ dùng `HfApiModel` để truy cập [Serverless Inference API](https://huggingface.co/docs/api-inference/index) của Hugging Face. Mô hình mặc định là `"Qwen/Qwen2.5-Coder-32B-Instruct"` - mô hình hiệu năng cao và có sẵn cho inference nhanh, nhưng bạn có thể chọn bất kỳ mô hình tương thích nào từ Hub. + +Chạy Agent khá đơn giản: + +```python +from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel + +agent = CodeAgent(tools=[DuckDuckGoSearchTool()], model=HfApiModel()) + +agent.run("Search for the best music recommendations for a party at the Wayne's mansion.") +``` + +Khi chạy ví dụ này, đầu ra sẽ **hiển thị lộ trình các bước workflow được thực thi**. Nó cũng in code Python tương ứng với thông báo: + +```python + ─ Executing parsed code: ──────────────────────────────────────────────────────────────────────────────────────── + results = web_search(query="best music for a Batman party") + print(results) + ───────────────────────────────────────────────────────────────────────────────────────────────────────────────── +``` + +Sau vài bước, bạn sẽ thấy playlist được tạo ra mà Alfred có thể dùng cho bữa tiệc! 🎵 + +### Sử dụng công cụ tùy chỉnh để chuẩn bị thực đơn + +Alfred chuẩn bị thực đơn + +Giờ đã có playlist, chúng ta cần sắp xếp thực đơn cho khách. Một lần nữa, Alfred có thể tận dụng `smolagents` để làm điều này. Ở đây, chúng ta dùng decorator `@tool` để định nghĩa hàm tùy chỉnh đóng vai trò công cụ. Chúng ta sẽ tìm hiểu chi tiết về tạo công cụ sau, hiện tại cứ chạy code trước. + +Như bạn thấy trong ví dụ dưới, chúng ta sẽ tạo công cụ bằng decorator `@tool` và thêm vào danh sách `tools`. + +```python +from smolagents import CodeAgent, tool, HfApiModel + +# Công cụ đề xuất thực đơn theo dịp +@tool +def suggest_menu(occasion: str) -> str: + """ + Đề xuất thực đơn dựa trên dịp. + Args: + occasion (str): Loại dịp cho bữa tiệc. Giá trị cho phép: + - "casual": Thực đơn tiệc thông thường. + - "formal": Thực đơn tiệc trang trọng. + - "superhero": Thực đơn tiệc siêu anh hùng. + - "custom": Thực đơn tùy chỉnh. + """ + if occasion == "casual": + return "Pizza, đồ ăn nhẹ và đồ uống." + elif occasion == "formal": + return "Bữa tối 3 món với rượu và tráng miệng." + elif occasion == "superhero": + return "Tiệc tự chọn với đồ ăn giàu năng lượng và lành mạnh." + else: + return "Thực đơn tùy chỉnh cho quản gia." + +# Alfred, quản gia, chuẩn bị thực đơn cho bữa tiệc +agent = CodeAgent(tools=[suggest_menu], model=HfApiModel()) + +# Chuẩn bị thực đơn tiệc trang trọng +agent.run("Prepare a formal menu for the party.") +``` + +Agent sẽ chạy qua vài bước cho đến khi tìm ra câu trả lời. Việc chỉ rõ giá trị cho phép trong docstring giúp định hướng Agent đến các giá trị `occasion` hợp lệ và hạn chế ảo giác. + +Thực đơn đã sẵn sàng! 🥗 + +### Sử dụng import Python trong Agent + +Đã có playlist và thực đơn, nhưng cần kiểm tra một chi tiết quan trọng: thời gian chuẩn bị! + +Alfred cần tính toán mọi thứ sẽ sẵn sàng vào lúc nào nếu bắt đầu ngay bây giờ, phòng trường hợp cần sự trợ giúp từ các siêu anh hùng khác. + +`smolagents` chuyên về các Agent viết và thực thi đoạn code Python, cung cấp môi trường thực thi an toàn. +**Việc thực thi code có các biện pháp bảo mật nghiêm ngặt** - các import ngoài danh sách an toàn định trước bị chặn mặc định. Tuy nhiên, bạn có thể ủy quyền thêm import bằng cách truyền chúng dưới dạng chuỗi trong `additional_authorized_imports`. +Để biết thêm chi tiết về thực thi code an toàn, xem [hướng dẫn chính thức](https://huggingface.co/docs/smolagents/tutorials/secure_code_execution). + +Khi tạo Agent, chúng ta sẽ dùng `additional_authorized_imports` để cho phép import module `datetime`. + +```python +from smolagents import CodeAgent, HfApiModel +import numpy as np +import time +import datetime + +agent = CodeAgent(tools=[], model=HfApiModel(), additional_authorized_imports=['datetime']) + +agent.run( + """ + Alfred cần chuẩn bị cho bữa tiệc. Các công việc bao gồm: + 1. Chuẩn bị đồ uống - 30 phút + 2. Trang trí biệt thự - 60 phút + 3. Chuẩn bị thực đơn - 45 phút + 4. Chuẩn bị âm nhạc và playlist - 45 phút + + Nếu bắt đầu ngay bây giờ, mấy giờ mọi thứ sẽ sẵn sàng? + """ +) +``` + +Những ví dụ này mới chỉ là khởi đầu cho những gì bạn có thể làm với code agent, và chúng ta đã thấy được tiện ích của chúng trong việc chuẩn bị tiệc. +Bạn có thể tìm hiểu thêm về cách xây dựng code agent trong [tài liệu smolagents](https://huggingface.co/docs/smolagents). + +Tóm lại, `smolagents` chuyên về các Agent viết và thực thi đoạn code Python, cung cấp môi trường thực thi an toàn. Nó hỗ trợ cả mô hình ngôn ngữ local và dựa trên API, giúp thích ứng với nhiều môi trường phát triển khác nhau. + +### Chia sẻ Agent chuẩn bị tiệc tới Hub + +Sẽ **tuyệt vời thế nào nếu chia sẻ Agent Alfred của chúng ta với cộng đồng**? Bằng cách này, mọi người có thể dễ dàng tải và dùng Agent trực tiếp từ Hub, mang đến công cụ lên kế hoạch tiệc tối ưu của Gotham! Hãy biến điều này thành hiện thực! 🎉 + +Thư viện `smolagents` cho phép thực hiện điều này bằng cách chia sẻ toàn bộ Agent với cộng đồng và tải về để dùng ngay. Đơn giản như sau: + +```python +# Đổi thành username và repo name của bạn +agent.push_to_hub('sergiopaniego/AlfredAgent') +``` + +Để tải lại Agent, dùng code sau: + +```python +# Đổi thành username và repo name của bạn +alfred_agent = agent.from_hub('sergiopaniego/AlfredAgent', trust_remote_code=True) + +alfred_agent.run("Give me the best playlist for a party at Wayne's mansion. The party idea is a 'villain masquerade' theme") +``` + +Điều thú vị là các Agent được chia sẻ có sẵn dưới dạng Hugging Face Spaces, cho phép bạn tương tác thời gian thực. Bạn có thể khám phá các Agent khác [tại đây](https://huggingface.co/spaces/davidberenstein1957/smolagents-and-tools). + +Ví dụ, _AlfredAgent_ có sẵn [tại đây](https://huggingface.co/spaces/sergiopaniego/AlfredAgent). Bạn có thể dùng thử trực tiếp bên dưới: + + + +Bạn có thể thắc mắc - làm thế nào Alfred xây dựng được Agent như vậy bằng `smolagents`? Bằng cách tích hợp nhiều công cụ, anh ấy có thể tạo ra Agent như sau. Đừng lo về các công cụ hiện tại, vì chúng ta sẽ có phần riêng trong chương này để tìm hiểu chi tiết: + +```python +from smolagents import CodeAgent, DuckDuckGoSearchTool, FinalAnswerTool, HfApiModel, Tool, tool, VisitWebpageTool + +@tool +def suggest_menu(occasion: str) -> str: + """ + Đề xuất thực đơn dựa trên dịp. + Args: + occasion: Loại dịp cho bữa tiệc. + """ + if occasion == "casual": + return "Pizza, đồ ăn nhẹ và đồ uống." + elif occasion == "formal": + return "Bữa tối 3 món với rượu và tráng miệng." + elif occasion == "superhero": + return "Tiệc tự chọn với đồ ăn giàu năng lượng và lành mạnh." + else: + return "Thực đơn tùy chỉnh cho quản gia." + +@tool +def catering_service_tool(query: str) -> str: + """ + Công cụ trả về dịch vụ catering được đánh giá cao nhất tại Gotham City. + + Args: + query: Từ khóa tìm kiếm dịch vụ catering. + """ + # Danh sách dịch vụ catering và đánh giá + services = { + "Gotham Catering Co.": 4.9, + "Wayne Manor Catering": 4.8, + "Gotham City Events": 4.7, + } + + # Tìm dịch vụ có đánh giá cao nhất (mô phỏng tìm kiếm) + best_service = max(services, key=services.get) + + return best_service + +class SuperheroPartyThemeTool(Tool): + name = "superhero_party_theme_generator" + description = """ + Công cụ đề xuất ý tưởng tiệc theo chủ đề siêu anh hùng sáng tạo dựa trên thể loại. + Trả về ý tưởng chủ đề tiệc độc đáo.""" + + inputs = { + "category": { + "type": "string", + "description": "Thể loại tiệc siêu anh hùng (vd: 'classic heroes', 'villain masquerade', 'futuristic Gotham').", + } + } + + output_type = "string" + + def forward(self, category: str): + themes = { + "classic heroes": "Tiệc Justice League: Khách mặc trang phục siêu anh hùng DC yêu thích với cocktail chủ đề như 'The Kryptonite Punch'.", + "villain masquerade": "Dạ hội Gotham Rogues: Lễ hội hóa trang bí ẩn nơi khách mặc trang như phản diện Batman.", + "futuristic Gotham": "Đêm Neo-Gotham: Tiệc phong cách cyberpunk lấy cảm hứng từ Batman Beyond, với trang trí neon và gadget tương lai." + } + + return themes.get(category.lower(), "Không tìm thấy ý tưởng chủ đề. Thử 'classic heroes', 'villain masquerade' hoặc 'futuristic Gotham'.") + + +# Alfred, quản gia, chuẩn bị thực đơn cho bữa tiệc +agent = CodeAgent( + tools=[ + DuckDuckGoSearchTool(), + VisitWebpageTool(), + suggest_menu, + catering_service_tool, + SuperheroPartyThemeTool() + ], + model=HfApiModel(), + max_steps=10, + verbosity_level=2 +) + +agent.run("Give me the best playlist for a party at the Wayne's mansion. The party idea is a 'villain masquerade' theme") +``` + +Như bạn thấy, chúng ta đã tạo `CodeAgent` với nhiều công cụ mở rộng chức năng, biến nó thành công cụ lên kế hoạch tiệc hoàn hảo sẵn sàng chia sẻ với cộng đồng! 🎉 + +Giờ đến lượt bạn: hãy xây dựng Agent của riêng mình và chia sẻ với cộng đồng bằng kiến thức vừa học! 🕵️‍♂️💡 + + +Nếu muốn chia sẻ dự án Agent, hãy tạo một Space và tag agents-course trên Hugging Face Hub. Chúng mình rất muốn xem những gì bạn tạo ra! + + +### Kiểm tra Agent chuẩn bị tiệc với OpenTelemetry và Langfuse 📡 + +Khi Alfred tinh chỉnh Agent chuẩn bị tiệc, anh ấy cảm thấy mệt mỏi với việc gỡ lỗi các lần chạy. Vốn dĩ Agent khó đoán và khó kiểm tra. Nhưng vì muốn xây dựng Agent chuẩn bị tiệc tối ưu và triển khai production, anh ấy cần khả năng theo dõi quá trình chạy để giám sát và phân tích sau này. + +Một lần nữa, `smolagents` giải cứu! Nó áp dụng chuẩn [OpenTelemetry](https://opentelemetry.io/) để theo dõi các lần chạy Agent, cho phép ghi log và kiểm tra liền mạch. Với sự trợ giúp của [Langfuse](https://langfuse.com/) và `SmolagentsInstrumentor`, Alfred có thể dễ dàng theo dõi và phân tích hành vi Agent. + +Cài đặt rất đơn giản! + +Đầu tiên, cần cài các dependency cần thiết: + +```bash +pip install opentelemetry-sdk opentelemetry-exporter-otlp openinference-instrumentation-smolagents +``` + +Tiếp theo, Alfred đã tạo tài khoản Langfuse và có sẵn API key. Nếu chưa có, bạn có thể đăng ký Langfuse Cloud [tại đây](https://cloud.langfuse.com/) hoặc xem [lựa chọn khác](https://huggingface.co/docs/smolagents/tutorials/inspect_runs). + +Sau khi có API key, cấu hình chúng như sau: + +```python +import os +import base64 + +LANGFUSE_PUBLIC_KEY="pk-lf-..." +LANGFUSE_SECRET_KEY="sk-lf-..." +LANGFUSE_AUTH=base64.b64encode(f"{LANGFUSE_PUBLIC_KEY}:{LANGFUSE_SECRET_KEY}".encode()).decode() + +os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://cloud.langfuse.com/api/public/otel" # Khu vực dữ liệu EU +# os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://us.cloud.langfuse.com/api/public/otel" # Khu vực dữ liệu US +os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {LANGFUSE_AUTH}" +``` + +Cuối cùng, Alfred sẵn sàng khởi tạo `SmolagentsInstrumentor` và bắt đầu theo dõi hiệu suất Agent. + +```python +from opentelemetry.sdk.trace import TracerProvider + +from openinference.instrumentation.smolagents import SmolagentsInstrumentor +from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter +from opentelemetry.sdk.trace.export import SimpleSpanProcessor + +trace_provider = TracerProvider() +trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter())) + +SmolagentsInstrumentor().instrument(tracer_provider=trace_provider) +``` + +Alfred đã kết nối thành công 🔌! Các lần chạy từ `smolagents` được ghi log vào Langfuse, cho anh ấy cái nhìn toàn diện về hành vi Agent. Với setup này, anh ấy có thể xem lại các lần chạy trước và cải thiện Agent chuẩn bị tiệc. + +```python +from smolagents import CodeAgent, HfApiModel + +agent = CodeAgent(tools=[], model=HfApiModel()) +alfred_agent = agent.from_hub('sergiopaniego/AlfredAgent', trust_remote_code=True) +alfred_agent.run("Give me the best playlist for a party at Wayne's mansion. The party idea is a 'villain masquerade' theme") +``` + +Alfred có thể truy cập các log này [tại đây](https://cloud.langfuse.com/project/cm7bq0abj025rad078ak3luwi/traces/995fc019255528e4f48cf6770b0ce27b?timestamp=2025-02-19T10%3A28%3A36.929Z) để xem xét và phân tích. + + +Thực tế đã xảy ra lỗi nhỏ trong quá trình thực thi. Bạn có thể phát hiện ra nó trong log không? Thử theo dõi cách Agent xử lý và vẫn trả về kết quả hợp lệ. Đây là link trực tiếp đến lỗi nếu bạn muốn kiểm tra. Dĩ nhiên lỗi đã được sửa, chi tiết xem trong issue này. + + +Trong khi đó, [playlist được đề xuất](https://open.spotify.com/playlist/0gZMMHjuxMrrybQ7wTMTpw) tạo không khí hoàn hảo cho việc chuẩn bị tiệc. Thật tuyệt phải không? 🎶 + +--- + +Giờ đã tạo xong Code Agent đầu tiên, hãy **học cách tạo Tool Calling Agent** - loại Agent thứ hai có sẵn trong `smolagents`. + +## Tài nguyên + +- [Blog smolagents](https://huggingface.co/blog/smolagents) - Giới thiệu về smolagents và tương tác code +- [smolagents: Xây dựng Agent tốt](https://huggingface.co/docs/smolagents/tutorials/building_good_agents) - Best practices cho Agent đáng tin cậy +- [Xây dựng Agent hiệu quả - Anthropic](https://www.anthropic.com/research/building-effective-agents) - Nguyên tắc thiết kế Agent +- [Chia sẻ lần chạy với OpenTelemetry](https://huggingface.co/docs/smolagents/tutorials/inspect_runs) - Chi tiết cách cài OpenTelemetry để theo dõi Agent. \ No newline at end of file diff --git a/units/vi/unit2/smolagents/conclusion.mdx b/units/vi/unit2/smolagents/conclusion.mdx new file mode 100644 index 000000000..8ac56ddda --- /dev/null +++ b/units/vi/unit2/smolagents/conclusion.mdx @@ -0,0 +1,11 @@ +# Kết luận + +Chúc mừng bạn đã hoàn thành module `smolagents` của Chương thứ hai 🥳 + +Bạn vừa nắm vững những nguyên tắc cơ bản của `smolagents` và đã xây dựng Agent đầu tiên của riêng mình! Giờ khi đã có kỹ năng làm việc với `smolagents`, bạn có thể bắt đầu tạo các Agent giải quyết những nhiệm vụ mà bạn quan tâm. + +Trong mô đun tiếp theo, chúng ta sẽ học **cách xây dựng Agent với LlamaIndex**. + +Cuối cùng, chúng mình rất muốn **nghe ý kiến của bạn về khóa học và cách cải thiện nó**. Nếu có phản hồi, hãy 👉 [điền vào form này](https://docs.google.com/forms/d/e/1FAIpQLSe9VaONn0eglax0uTwi29rIn4tM7H2sYmmybmG5jJNlE5v0xA/viewform?usp=dialog) + +### Tiếp tục học hỏi và luôn tỏa sáng nhé 🤗 \ No newline at end of file diff --git a/units/vi/unit2/smolagents/final_quiz.mdx b/units/vi/unit2/smolagents/final_quiz.mdx new file mode 100644 index 000000000..e60937541 --- /dev/null +++ b/units/vi/unit2/smolagents/final_quiz.mdx @@ -0,0 +1,25 @@ +# Đến giờ thi rồi! + +Chúc mừng các bạn đã hoàn thành phần học về `smolagents`! Giờ là lúc kiểm tra kiến thức của chúng mình bằng một bài quiz. 🧠 + +## Hướng dẫn + +- Quiz bao gồm các câu hỏi code +- Bạn sẽ nhận được hướng dẫn để hoàn thành các đoạn code +- Đọc kỹ hướng dẫn và điền code vào chỗ trống +- Mỗi câu hỏi sẽ có kết quả và feedback đi kèm + +🧘 **Bài quiz này không tính điểm và không cấp chứng chỉ**. Mục đích chính là giúp bạn hiểu rõ thư viện `smolagents` và tự đánh giá xem có cần ôn lại lý thuyết không. Ở các Chương tiếp theo, chúng ta sẽ áp dụng kiến thức này vào dự án thực tế. + +Bắt đầu thôi! + +## Quiz 🚀 + + + +Truy cập quiz tại 👉 [đây](https://huggingface.co/spaces/agents-course/unit2_smolagents_quiz) \ No newline at end of file diff --git a/units/vi/unit2/smolagents/introduction.mdx b/units/vi/unit2/smolagents/introduction.mdx new file mode 100644 index 000000000..8b841587a --- /dev/null +++ b/units/vi/unit2/smolagents/introduction.mdx @@ -0,0 +1,69 @@ +# Giới thiệu về `smolagents` + +Chương 2.1 Hình thu nhỏ + +Chào mừng bạn đến với mô-đun này, nơi ta sẽ học **cách xây dựng AI Agent hiệu quả** bằng thư viện [`smolagents`](https://github.com/huggingface/smolagents) - một framework nhẹ để tạo các AI Agent mạnh mẽ. + +`smolagents` là thư viện của Hugging Face, vì vậy chúng mình rất mong nhận được sự ủng hộ của bạn bằng cách **star** (đánh dấu sao) cho [kho lưu trữ](https://github.com/huggingface/smolagents) smolagents: +star smolagents + +## Tổng quan mô-đun + +Mô-đun này cung cấp cái nhìn toàn diện về các khái niệm chính và chiến lược thực tế để xây dựng AI Agent thông minh bằng `smolagents`. + +Với nhiều framework mã nguồn mở hiện có, việc hiểu các thành phần và khả năng của `smolagents` là rất quan trọng để quyết định khi nào nên dùng nó hoặc chọn giải pháp khác phù hợp hơn. + +Ta sẽ khám phá các loại Agent quan trọng bao gồm CodeAgent cho tác vụ phát triển phần mềm, Tool Calling Agent để tạo workflow mô đun hóa theo chức năng, và agent truy xuất thông tin để tổng hợp thông tin. + +Ngoài ra, ta sẽ tìm hiểu cách phối hợp nhiều Agent cùng lúc cũng như tích hợp khả năng xử lý hình ảnh và duyệt web - những tính năng mở ra khả năng ứng dụng đa dạng hơn. + +Trong chương này, Alfred - Agent từ Chương 1 - sẽ quay trở lại. Lần này, cậu ấy sử dụng framework `smolagents` cho các hoạt động nội bộ. Cùng theo dõi hành trình Alfred chuẩn bị tiệc tại dinh thự Wayne 🦇 khi gia đình Wayne vắng nhà, và khám phá cách cậu ấy xử lý mọi việc với `smolagents`! + + + +Trong chương này, bạn sẽ học cách xây dựng AI Agent bằng thư viện `smolagents`. Các Agent của bạn sẽ có thể tìm kiếm dữ liệu, thực thi code và tương tác với trang web. Bạn cũng sẽ học cách kết hợp nhiều Agent để tạo hệ thống mạnh mẽ hơn. + + + +![Agent Alfred](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit1/this-is-alfred.jpg) + +## Nội dung chính + +Trong chương về `smolagents`, ta sẽ tìm hiểu: + +### 1️⃣ [Tại sao nên dùng smolagents](./why_use_smolagents) + +`smolagents` là một trong nhiều framework Agent mã nguồn mở hiện có. Các lựa chọn khác như `LlamaIndex` và `LangGraph` cũng được đề cập trong các mô-đun khác của khóa học. `smolagents` cung cấp nhiều tính năng nổi bật phù hợp cho các trường hợp cụ thể, nhưng ta luôn cần cân nhắc kỹ khi chọn framework. Phần này sẽ phân tích ưu/nhược điểm của `smolagents` để giúp bạn lựa chọn phù hợp với yêu cầu dự án. + +### 2️⃣ [CodeAgents](./code_agents) + +`CodeAgents` là loại Agent chính trong `smolagents`. Thay vì tạo JSON hay văn bản, các Agent này sinh code Python để thực hiện hành động. Mô-đun này giải thích mục đích, cách hoạt động của chúng kèm ví dụ thực tế. + +### 3️⃣ [ToolCallingAgents](./tool_calling_agents) + +`ToolCallingAgents` là loại Agent thứ hai được hỗ trợ bởi `smolagents`. Khác với `CodeAgents` sinh code Python, các Agent này dựa vào JSON/text mà hệ thống cần phân tích để thực thi. Phần này sẽ so sánh sự khác biệt với `CodeAgents` và cung cấp ví dụ minh họa. + +### 4️⃣ [Tools](./tools) + +Như đã thấy ở Chương 1, Tools là các hàm mà LLM có thể sử dụng trong hệ thống Agent, đóng vai trò như khối xây dựng cơ bản cho hành vi của Agent. Mô-đun này hướng dẫn tạo Tools cấu trúc, cách triển khai bằng lớp `Tool` hoặc decorator `@tool`. Bạn cũng sẽ học về bộ Tools mặc định, cách chia sẻ Tools với cộng đồng và tải Tools từ cộng đồng để sử dụng. + +### 5️⃣ [Retrieval Agents](./retrieval_agents) + +Retrieval agent (Agent truy xuất thông tin) cho phép model truy cập kho kiến thức, tìm kiếm và tổng hợp thông tin từ nhiều nguồn. Chúng sử dụng vector store để truy xuất hiệu quả và triển khai mô hình Tìm kiếm và tạo ra câu trả lời (**RAG**). Đặc biệt hữu ích khi tích hợp tìm kiếm web với kho kiến thức tùy chỉnh, đồng thời duy trì ngữ cảnh hội thoại qua hệ thống bộ nhớ. Phần này cũng đề cập cơ chế fallback để đảm bảo truy xuất thông tin ổn định. + +### 6️⃣ [Multi-Agent Systems](./multi_agent_systems) + +Việc phối hợp nhiều Agent hiệu quả là chìa khóa để xây dựng hệ thống đa Agent mạnh mẽ. Bằng cách kết hợp các Agent với khả năng khác nhau (ví dụ Agent tìm kiếm web + Agent thực thi code), bạn có thể tạo giải pháp phức tạp hơn. Mô-đun này tập trung vào thiết kế, triển khai và quản lý hệ thống đa Agent. + +### 7️⃣ [Vision and Browser agents](./vision_agents) + +Vision agent mở rộng khả năng truyền thống bằng cách tích hợp Mô hình ngôn ngữ-thị giác **(VLMs)**, cho phép xử lý và phân tích thông tin hình ảnh. Ta sẽ học cách thiết kế và tích hợp Agent sử dụng VLM để thực hiện các chức năng nâng cao như phân tích dữ liệu hình ảnh, tương tác đa phương thức. Chúng ta cũng sẽ xây dựng browser agent (Agent duyệt web) có thể trích xuất thông tin từ web. + +## Tài nguyên tham khảo + +- [Tài liệu smolagents](https://huggingface.co/docs/smolagents) - Tài liệu chính thức +- [Xây dựng Agent hiệu quả](https://www.anthropic.com/research/building-effective-agents) - Nghiên cứu về kiến trúc Agent +- [Hướng dẫn xây Agent](https://huggingface.co/docs/smolagents/tutorials/building_good_agents) - Best practices +- [LangGraph Agents](https://langchain-ai.github.io/langgraph/) - Ví dụ triển khai Agent +- [Hướng dẫn Function Calling](https://platform.openai.com/docs/guides/function-calling) - Hiểu về function calling trong LLM +- [Best practices RAG](https://www.pinecone.io/learn/retrieval-augmented-generation/) - Hướng dẫn triển khai RAG hiệu quả \ No newline at end of file diff --git a/units/vi/unit2/smolagents/multi_agent_systems.mdx b/units/vi/unit2/smolagents/multi_agent_systems.mdx new file mode 100644 index 000000000..5cc32bab6 --- /dev/null +++ b/units/vi/unit2/smolagents/multi_agent_systems.mdx @@ -0,0 +1,470 @@ + + +# Hệ thống Đa Agent + +Hệ thống đa Agent cho phép **các Agent chuyên biệt hợp tác xử lý tác vụ phức tạp**, nâng cao tính mô-đun, khả năng mở rộng và độ ổn định. Thay vì phụ thuộc vào một Agent duy nhất, các tác vụ được phân phối cho nhiều Agent với khả năng khác nhau. + +Trong **smolagents**, các Agent khác nhau có thể kết hợp để tạo mã Python, gọi công cụ bên ngoài, thực hiện tìm kiếm web và hơn thế. Bằng cách điều phối các Agent này, ta có thể tạo ra các quy trình làm việc mạnh mẽ. + +Một thiết lập điển hình có thể bao gồm: +- **Manager Agent** (Agent quản lý) để phân công tác vụ +- **Code Interpreter Agent** (Agent thông dịch mã) để thực thi code +- **Web Search Agent** (Agent tìm kiếm web) để thu thập thông tin + +Biểu đồ dưới minh họa kiến trúc đa Agent đơn giản, nơi **Manager Agent** phối hợp với **Code Interpreter Tool** và **Web Search Agent** - Agent này lại sử dụng các công cụ như `DuckDuckGoSearchTool` và `VisitWebpageTool` để thu thập thông tin liên quan. + + + +## Hệ thống Đa Agent trong thực tế + +Một hệ thống đa Agent bao gồm nhiều Agent chuyên biệt làm việc cùng nhau dưới sự điều phối của **Orchestrator Agent** (Agent điều phối). Cách tiếp cận này cho phép xử lý các quy trình phức tạp bằng cách phân phối tác vụ cho các Agent với vai trò khác nhau. + +Ví dụ, **Hệ thống RAG (Tìm kiếm và tạo ra câu trả lời) Đa Agent** có thể tích hợp: +- **Web Agent** để duyệt internet +- **Retriever Agent** để truy xuất thông tin từ cơ sở tri thức +- **Image Generation Agent** để tạo hình ảnh + +Tất cả Agent này hoạt động dưới sự điều phối của một Orchestrator quản lý việc phân công và tương tác. + +## Giải quyết tác vụ phức tạp với hệ thống phân cấp đa Agent + + +Bạn có thể theo dõi code trong notebook này và chạy bằng Google Colab. + + +Buổi tiếp tân sắp đến! Với sự giúp đỡ của bạn, Alfred gần như đã hoàn thành mọi chuẩn bị. + +Nhưng giờ phát sinh vấn đề: Batmobile đã biến mất. Alfred cần tìm phương tiện thay thế và phải tìm thật nhanh. + +May mắn thay, một số phim tiểu sử về cuộc đời Bruce Wayne đã được thực hiện, có lẽ Alfred có thể tìm thấy xe bỏ lại ở trường quay nào đó và nâng cấp lên tiêu chuẩn hiện đại, chắc chắn bao gồm cả tính năng tự lái hoàn toàn. + +Nhưng điều này có thể ở bất kỳ đâu trong các địa điểm quay phim trên thế giới - và số lượng có thể rất nhiều. + +Vì vậy Alfred cần bạn giúp đỡ. Bạn có thể xây dựng một Agent giải quyết tác vụ này không? + +> 👉 Tìm tất cả địa điểm quay phim Batman trên thế giới, tính toán thời gian vận chuyển bằng tàu đến đó và thể hiện chúng trên bản đồ với màu sắc biến đổi theo thời gian vận chuyển. Đồng thời thể hiện các nhà máy siêu xe có cùng thời gian vận chuyển. + +Hãy cùng xây dựng nào! + +Ví dụ này cần một số package bổ sung, hãy cài đặt chúng trước: + +```bash +pip install 'smolagents[litellm]' plotly geopandas shapely kaleido -q +``` + +### Đầu tiên tạo công cụ tính thời gian vận chuyển bằng máy bay chở hàng + +```python +import math +from typing import Optional, Tuple + +from smolagents import tool + + +@tool +def calculate_cargo_travel_time( + origin_coords: Tuple[float, float], + destination_coords: Tuple[float, float], + cruising_speed_kmh: Optional[float] = 750.0, # Tốc độ trung bình của máy bay chở hàng +) -> float: + """ + Tính thời gian di chuyển bằng máy bay chở hàng giữa hai điểm trên Trái Đất sử dụng khoảng cách vòng cung lớn. + + Args: + origin_coords: Tuple (vĩ độ, kinh độ) của điểm xuất phát + destination_coords: Tuple (vĩ độ, kinh độ) của điểm đến + cruising_speed_kmh: Tốc độ bay tùy chọn theo km/h (mặc định 750 km/h cho máy bay chở hàng thông thường) + + Returns: + float: Thời gian di chuyển ước tính tính bằng giờ + + Ví dụ: + >>> # Từ Chicago (41.8781° N, 87.6298° W) đến Sydney (33.8688° S, 151.2093° E) + >>> result = calculate_cargo_travel_time((41.8781, -87.6298), (-33.8688, 151.2093)) + """ + + def to_radians(degrees: float) -> float: + return degrees * (math.pi / 180) + + # Trích xuất tọa độ + lat1, lon1 = map(to_radians, origin_coords) + lat2, lon2 = map(to_radians, destination_coords) + + # Bán kính Trái Đất tính bằng km + EARTH_RADIUS_KM = 6371.0 + + # Tính khoảng cách vòng cung lớn bằng công thức haversine + dlon = lon2 - lon1 + dlat = lat2 - lat1 + + a = ( + math.sin(dlat / 2) ** 2 + + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2 + ) + c = 2 * math.asin(math.sqrt(a)) + distance = EARTH_RADIUS_KM * c + + # Thêm 10% để tính các tuyến đường không trực tiếp và kiểm soát không lưu + actual_distance = distance * 1.1 + + # Tính thời gian bay + # Thêm 1 giờ cho quy trình cất/hạ cánh + flight_time = (actual_distance / cruising_speed_kmh) + 1.0 + + # Định dạng kết quả + return round(flight_time, 2) + + +print(calculate_cargo_travel_time((41.8781, -87.6298), (-33.8688, 151.2093))) +``` + +### Thiết lập Agent + +Đối với nhà cung cấp model, ta sử dụng Together AI - một trong những [nhà cung cấp inference mới trên Hub](https://huggingface.co/blog/inference-providers)! + +GoogleSearchTool sử dụng [Serper API](https://serper.dev) để tìm kiếm web, vì vậy cần thiết lập biến môi trường `SERPAPI_API_KEY` và truyền `provider="serpapi"` hoặc có `SERPER_API_KEY` và truyền `provider=serper`. + +Nếu không có Serper API, bạn có thể dùng `DuckDuckGoSearchTool` nhưng lưu ý nó có giới hạn tốc độ. + +```python +import os +from PIL import Image +from smolagents import CodeAgent, GoogleSearchTool, HfApiModel, VisitWebpageTool + +model = HfApiModel(model_id="Qwen/Qwen2.5-Coder-32B-Instruct", provider="together") +``` + +Ta có thể bắt đầu bằng cách tạo một Agent đơn giản làm baseline để tạo báo cáo cơ bản. + +```python +task = """Tìm tất cả địa điểm quay phim Batman trên thế giới, tính thời gian vận chuyển bằng máy bay chở hàng đến đây (ta đang ở Gotham, 40.7128° N, 74.0060° W) và trả về dưới dạng dataframe pandas. +Đồng thời cung cấp một số nhà máy siêu xe có cùng thời gian vận chuyển.""" +``` + +```python +agent = CodeAgent( + model=model, + tools=[GoogleSearchTool("serper"), VisitWebpageTool(), calculate_cargo_travel_time], + additional_authorized_imports=["pandas"], + max_steps=20, +) +``` + +```python +result = agent.run(task) +``` + +```python +result +``` + +Trong trường hợp của chúng ta, nó tạo ra kết quả: + +
+Bấm để xem bản dịch tiếng Việt +```python +| | Địa điểm | Thời gian đến Gotham (giờ) | +|--|------------------------------------------------------|------------------------------| +| 0 | Nghĩa trang Necropolis, Glasgow, Scotland, UK | 8.60 | +| 1 | St. George's Hall, Liverpool, Anh, UK | 8.81 | +| 2 | Two Temple Place, London, Anh, UK | 9.17 | +| 3 | Wollaton Hall, Nottingham, Anh, UK | 9.00 | +| 4 | Knebworth House, Knebworth, Hertfordshire, UK | 9.15 | +| 5 | Nhà máy điện Acton Lane, Acton Lane, Acton, UK | 9.16 | +| 6 | Cầu Queensboro, New York, Mỹ | 1.01 | +| 7 | Phố Wall, New York, Mỹ | 1.00 | +| 8 | Pháo đài Mehrangarh, Jodhpur, Ấn Độ | 18.34 | +| 9 | Hẻm núi Turda, Romania | 11.89 | +| 10 | Chicago, Mỹ | 2.68 | +| 11 | Hong Kong, Trung Quốc | 19.99 | +| 12 | Xưởng phim Cardington, Northamptonshire, UK | 9.10 | +| 13 | Warner Bros. Leavesden Studios, Hertfordshire, UK | 9.13 | +| 14 | Westwood, Los Angeles, Mỹ | 6.79 | +| 15 | Woking, UK (McLaren) | 9.13 | +``` +
+```python +| | Location | Travel Time to Gotham (hours) | +|--|------------------------------------------------------|------------------------------| +| 0 | Necropolis Cemetery, Glasgow, Scotland, UK | 8.60 | +| 1 | St. George's Hall, Liverpool, England, UK | 8.81 | +| 2 | Two Temple Place, London, England, UK | 9.17 | +| 3 | Wollaton Hall, Nottingham, England, UK | 9.00 | +| 4 | Knebworth House, Knebworth, Hertfordshire, UK | 9.15 | +| 5 | Acton Lane Power Station, Acton Lane, Acton, UK | 9.16 | +| 6 | Queensboro Bridge, New York City, USA | 1.01 | +| 7 | Wall Street, New York City, USA | 1.00 | +| 8 | Mehrangarh Fort, Jodhpur, Rajasthan, India | 18.34 | +| 9 | Turda Gorge, Turda, Romania | 11.89 | +| 10 | Chicago, USA | 2.68 | +| 11 | Hong Kong, China | 19.99 | +| 12 | Cardington Studios, Northamptonshire, UK | 9.10 | +| 13 | Warner Bros. Leavesden Studios, Hertfordshire, UK | 9.13 | +| 14 | Westwood, Los Angeles, CA, USA | 6.79 | +| 15 | Woking, UK (McLaren) | 9.13 | +``` + +Ta có thể cải thiện bằng cách thêm các bước lập kế hoạch và prompt chi tiết hơn. + +Các bước lập kế hoạch cho phép Agent suy nghĩ trước và lên kế hoạch, hữu ích cho các tác vụ phức tạp. + +```python +agent.planning_interval = 4 + +detailed_report = agent.run(f""" +Bạn là chuyên gia phân tích. Hãy tạo báo cáo toàn diện sau khi truy cập nhiều website. +Đừng ngần ngại tìm kiếm nhiều truy vấn cùng lúc trong vòng lặp. +Với mỗi dữ liệu tìm thấy, hãy truy cập URL nguồn để xác nhận số liệu. + +{task} +""") + +print(detailed_report) +``` + +```python +detailed_report +``` + +Trong trường hợp của chúng ta, nó tạo ra: + +
+Bấm để xem bản dịch tiếng Việt +```python +| | Địa điểm | Thời gian di chuyển (giờ) | +|--|--------------------------------------------------|---------------------| +| 0 | Cầu Than thở, Nghĩa trang Glasgow, UK | 8.6 | +| 1 | Phố Wishart, Glasgow, Scotland, UK | 8.6 | +``` +
+```python +| | Location | Travel Time (hours) | +|--|--------------------------------------------------|---------------------| +| 0 | Bridge of Sighs, Glasgow Necropolis, Glasgow, UK | 8.6 | +| 1 | Wishart Street, Glasgow, Scotland, UK | 8.6 | + + +Nhờ những thay đổi nhanh chóng này, ta đã có báo cáo cô đọng hơn chỉ bằng cách cung cấp prompt chi tiết và thêm khả năng lập kế hoạch cho Agent! + +Cửa sổ ngữ cảnh của model đang nhanh chóng bị lấp đầy. **Nếu yêu cầu Agent kết hợp kết quả từ nhiều tìm kiếm, nó sẽ chậm dần và làm tăng token cùng chi phí**. + +➡️ Chúng ta cần cải thiện cấu trúc hệ thống. + +### ✌️ Chia tác vụ giữa hai Agent + +Cấu trúc đa Agent cho phép tách biệt bộ nhớ giữa các tác vụ con, mang lại hai lợi ích lớn: +- Mỗi Agent tập trung hơn vào tác vụ chính, từ đó hiệu suất cao hơn +- Tách biệt bộ nhớ làm giảm số lượng token đầu vào ở mỗi bước, giảm độ trễ và chi phí. + +Hãy tạo một nhóm với Agent tìm kiếm web chuyên dụng, được quản lý bởi một Agent khác. + +Agent quản lý cần khả năng vẽ biểu đồ để tạo báo cáo cuối: hãy cấp quyền truy cập các thư viện như `plotly`, `geopandas` + `shapely` cho việc vẽ bản đồ. + +```python +model = HfApiModel( + "Qwen/Qwen2.5-Coder-32B-Instruct", provider="together", max_tokens=8096 +) + +web_agent = CodeAgent( + model=model, + tools=[ + GoogleSearchTool(provider="serper"), + VisitWebpageTool(), + calculate_cargo_travel_time, + ], + name="web_agent", + description="Duyệt web để tìm thông tin", + verbosity_level=0, + max_steps=10, +) +``` + +Agent quản lý cần xử lý các tác vụ nặng về tư duy. + +Vì vậy ta sử dụng model mạnh hơn [DeepSeek-R1](https://huggingface.co/deepseek-ai/DeepSeek-R1), và thêm `planning_interval`. + +```python +from smolagents.utils import encode_image_base64, make_image_url +from smolagents import OpenAIServerModel + + +def check_reasoning_and_plot(final_answer, agent_memory): + multimodal_model = OpenAIServerModel("gpt-4o", max_tokens=8096) + filepath = "saved_map.png" + assert os.path.exists(filepath), "Hãy đảm bảo lưu biểu đồ dưới tên saved_map.png!" + image = Image.open(filepath) + prompt = ( + f"Đây là tác vụ người dùng và các bước Agent đã thực hiện: {agent_memory.get_succinct_steps()}. Đây là biểu đồ được tạo." + "Hãy kiểm tra xem quá trình lập luận và biểu đồ có chính xác không: chúng có trả lời đúng tác vụ được giao không?" + "Đầu tiên liệt kê lý do tại sao đúng/sai, sau đó đưa ra quyết định cuối: VIẾT HOA PASS nếu đạt yêu cầu, FAIL nếu không." + "Đừng quá khắt khe: nếu biểu đồ giải quyết được phần lớn tác vụ, nên pass." + "Để pass, biểu đồ phải được tạo bằng px.scatter_map chứ không phải phương pháp khác (scatter_map trông đẹp hơn)." + ) + messages = [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": prompt, + }, + { + "type": "image_url", + "image_url": {"url": make_image_url(encode_image_base64(image))}, + }, + ], + } + ] + output = multimodal_model(messages).content + print("Phản hồi: ", output) + if "FAIL" in output: + raise Exception(output) + return True + + +manager_agent = CodeAgent( + model=HfApiModel("deepseek-ai/DeepSeek-R1", provider="together", max_tokens=8096), + tools=[calculate_cargo_travel_time], + managed_agents=[web_agent], + additional_authorized_imports=[ + "geopandas", + "plotly", + "shapely", + "json", + "pandas", + "numpy", + ], + planning_interval=5, + verbosity_level=2, + final_answer_checks=[check_reasoning_and_plot], + max_steps=15, +) +``` + +Hãy xem cấu trúc nhóm Agent: + +```python +manager_agent.visualize() +``` + +Kết quả sẽ tương tự thế này, giúp ta hiểu mối quan hệ giữa các Agent và công cụ sử dụng: + +
+Bấm để xem bản dịch tiếng Việt +```python +CodeAgent | deepseek-ai/DeepSeek-R1 +├── ✅ Các import được phép: ['geopandas', 'plotly', 'shapely', 'json', 'pandas', 'numpy'] +├── 🛠️ Công cụ: +│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +│ ┃ Tên ┃ Mô tả ┃ Tham số ┃ +│ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ │ calculate_cargo_travel_time │ Tính thời gian di chuyển máy bay chở hàng giữa hai điểm trên Trái Đất │ origin_coords (`array`): Tuple (vĩ độ, kinh độ) điểm xuất phát │ +│ │ │ │ destination_coords (`array`): Tuple (vĩ độ, kinh độ) điểm đến │ +│ │ │ │ cruising_speed_kmh (`number`): Tốc độ bay tùy chọn (mặc định 750 km/h) │ +│ │ final_answer │ Cung cấp câu trả lời cuối cùng │ answer (`any`): Câu trả lời cuối cùng │ +│ └─────────────────────────────┴───────────────────────────────────────┴───────────────────────────────────────┘ +└── 🤖 Các Agent quản lý: + └── web_agent | CodeAgent | Qwen/Qwen2.5-Coder-32B-Instruct + ├── ✅ Các import được phép: [] + ├── 📝 Mô tả: Duyệt web để tìm thông tin + └── 🛠️ Công cụ: + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ Tên ┃ Mô tả ┃ Tham số ┃ + ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ + │ web_search │ Thực hiện tìm kiếm Google │ query (`string`): Truy vấn tìm kiếm │ + │ visit_webpage │ Truy cập webpage │ url (`string`): URL cần truy cập │ + │ calculate_cargo_travel_time │ Tính thời gian di chuyển máy bay chở hàng │ origin_coords (`array`): Tuple (vĩ độ, kinh độ) điểm xuất phát │ + │ final_answer │ Cung cấp câu trả lời cuối cùng │ answer (`any`): Câu trả lời cuối cùng │ + └─────────────────────────────┴───────────────────────────────────┴───────────────────────────────────┘ +``` +
+```python +CodeAgent | deepseek-ai/DeepSeek-R1 +├── ✅ Authorized imports: ['geopandas', 'plotly', 'shapely', 'json', 'pandas', 'numpy'] +├── 🛠️ Tools: +│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +│ ┃ Name ┃ Description ┃ Arguments ┃ +│ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ +│ │ calculate_cargo_travel_time │ Calculate the travel time for a cargo │ origin_coords (`array`): Tuple of │ +│ │ │ plane between two points on Earth │ (latitude, longitude) for the │ +│ │ │ using great-circle distance. │ starting point │ +│ │ │ │ destination_coords (`array`): Tuple │ +│ │ │ │ of (latitude, longitude) for the │ +│ │ │ │ destination │ +│ │ │ │ cruising_speed_kmh (`number`): │ +│ │ │ │ Optional cruising speed in km/h │ +│ │ │ │ (defaults to 750 km/h for typical │ +│ │ │ │ cargo planes) │ +│ │ final_answer │ Provides a final answer to the given │ answer (`any`): The final answer to │ +│ │ │ problem. │ the problem │ +│ └─────────────────────────────┴───────────────────────────────────────┴───────────────────────────────────────┘ +└── 🤖 Managed agents: + └── web_agent | CodeAgent | Qwen/Qwen2.5-Coder-32B-Instruct + ├── ✅ Authorized imports: [] + ├── 📝 Description: Browses the web to find information + └── 🛠️ Tools: + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ Name ┃ Description ┃ Arguments ┃ + ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ + │ web_search │ Performs a google web search for │ query (`string`): The search │ + │ │ your query then returns a string │ query to perform. │ + │ │ of the top search results. │ filter_year (`integer`): │ + │ │ │ Optionally restrict results to a │ + │ │ │ certain year │ + │ visit_webpage │ Visits a webpage at the given url │ url (`string`): The url of the │ + │ │ and reads its content as a │ webpage to visit. │ + │ │ markdown string. Use this to │ │ + │ │ browse webpages. │ │ + │ calculate_cargo_travel_time │ Calculate the travel time for a │ origin_coords (`array`): Tuple of │ + │ │ cargo plane between two points on │ (latitude, longitude) for the │ + │ │ Earth using great-circle │ starting point │ + │ │ distance. │ destination_coords (`array`): │ + │ │ │ Tuple of (latitude, longitude) │ + │ │ │ for the destination │ + │ │ │ cruising_speed_kmh (`number`): │ + │ │ │ Optional cruising speed in km/h │ + │ │ │ (defaults to 750 km/h for typical │ + │ │ │ cargo planes) │ + │ final_answer │ Provides a final answer to the │ answer (`any`): The final answer │ + │ │ given problem. │ to the problem │ + └─────────────────────────────┴───────────────────────────────────┴───────────────────────────────────┘ +``` + +```python +manager_agent.run(""" +Tìm tất cả địa điểm quay phim Batman trên thế giới, tính thời gian vận chuyển bằng máy bay chở hàng đến đây (ta đang ở Gotham, 40.7128° N, 74.0060° W). +Đồng thời cung cấp một số nhà máy siêu xe có cùng thời gian vận chuyển. Cần ít nhất 6 điểm tổng cộng. +Biểu diễn dữ liệu dưới dạng bản đồ thế giới, các địa điểm hiển thị bằng điểm phân tán với màu phụ thuộc vào thời gian vận chuyển, và lưu vào saved_map.png! + +Đây là ví dụ cách vẽ và trả về bản đồ: +import plotly.express as px +df = px.data.carshare() +fig = px.scatter_map(df, lat="centroid_lat", lon="centroid_lon", text="name", color="peak_hour", size=100, + color_continuous_scale=px.colors.sequential.Magma, size_max=15, zoom=1) +fig.show() +fig.write_image("saved_image.png") +final_answer(fig) + +Không bao giờ xử lý chuỗi bằng code: khi có chuỗi cần đọc, chỉ cần in ra và bạn sẽ thấy nó. +""") +``` + +Tôi không biết kết quả chạy của bạn thế nào, nhưng trong trường hợp của tôi, Agent quản lý đã khéo léo phân chia tác vụ cho web_agent trong `1. Tìm địa điểm quay Batman`, sau đó `2. Tìm nhà máy siêu xe`, trước khi tổng hợp danh sách và vẽ bản đồ. + +Hãy xem bản đồ trông thế nào bằng cách kiểm tra trực tiếp từ trạng thái Agent: + +```python +manager_agent.python_executor.state["fig"] +``` + +Kết quả sẽ hiển thị bản đồ: + +![Bản đồ ví dụ hệ thống đa Agent](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/smolagents/output_map.png) + +## Tài nguyên + +- [Hệ thống Đa Agent](https://huggingface.co/docs/smolagents/main/en/examples/multiagents) – \ No newline at end of file diff --git a/units/vi/unit2/smolagents/quiz1.mdx b/units/vi/unit2/smolagents/quiz1.mdx new file mode 100644 index 000000000..fac0c0a5b --- /dev/null +++ b/units/vi/unit2/smolagents/quiz1.mdx @@ -0,0 +1,142 @@ +# Câu đố nhỏ (không tính điểm) [[quiz1]] + +Hãy cùng kiểm tra hiểu biết của bạn về `smolagents` với một bài Kiểm tra nhanh! Hãy nhớ rằng, tự kiểm tra giúp củng cố kiến thức và xác định các phần cần xem lại. + +Đây là bài kiểm tra không bắt buộc và không tính điểm. + +### Q1: Một trong những ưu điểm chính của việc chọn `smolagents` so với các framework khác là gì? +Phát biểu nào nêu bật được thế mạnh cốt lõi trong cách tiếp cận của `smolagents`? + + + +--- + +### Q2: Trường hợp nào sau đây bạn sẽ được hưởng lợi nhiều nhất từ việc sử dụng smolagents? +Tình huống nào phù hợp nhất với thế mạnh của smolagents? + + + +--- + +### Q3: smolagents cung cấp tính linh hoạt trong việc tích hợp mô hình. Phát biểu nào phản ánh đúng nhất cách tiếp cận này? +Hãy chọn mô tả chính xác nhất về cách smolagents làm việc với LLMs. + + + +--- + +### Q4: smolagents xử lý cuộc tranh luận giữa hành động dựa trên code và JSON như thế nào? +Phát biểu nào mô tả đúng triết lý của smolagents về định dạng hành động? + + + +--- + +### Q5: smolagents tích hợp với Hugging Face Hub để mang lại lợi ích như thế nào? +Phát biểu nào mô tả chính xác một lợi thế cốt lõi của việc tích hợp Hub? + + + +--- + +Chúc mừng bạn đã hoàn thành bài kiểm tra này! 🎉 Nếu bạn trả lời sai bất kỳ câu nào, hãy xem lại phần *Tại sao nên dùng smolagents* để hiểu sâu hơn. Nếu bạn làm tốt, bạn đã sẵn sàng khám phá các chủ đề nâng cao hơn trong smolagents! \ No newline at end of file diff --git a/units/vi/unit2/smolagents/quiz2.mdx b/units/vi/unit2/smolagents/quiz2.mdx new file mode 100644 index 000000000..724c24446 --- /dev/null +++ b/units/vi/unit2/smolagents/quiz2.mdx @@ -0,0 +1,147 @@ +# Kiểm tra nhỏ (không tính điểm) [[quiz2]] + +Đã đến lúc kiểm tra hiểu biết của bạn về các phần *Code Agents*, *Tool Calling Agents* và *Tools*. Bài kiểm tra này không bắt buộc và không tính điểm. + +--- + +### Q1: Điểm khác biệt chính giữa việc tạo tool bằng decorator `@tool` so với tạo subclass của `Tool` trong smolagents là gì? + +Phát biểu nào mô tả chính xác nhất sự khác biệt giữa hai cách định nghĩa tool này? + +@tool bắt buộc dùng cho các tool truy vấn, trong khi subclass Tool chỉ dành cho các tác vụ sinh văn bản", + explain: "Cả hai cách đều có thể dùng cho mọi loại tool, bao gồm các tool truy vấn và sinh văn bản.", + }, + { + text: "Decorator @tool được khuyên dùng cho các tool sử dụng hàm đơn giản, trong khi subclass Tool linh hoạt hơn cho chức năng phức tạp hoặc metadata tùy chỉnh", + explain: "Đúng. Cách dùng decorator đơn giản hơn, nhưng subclass cho phép tùy chỉnh hành vi.", + correct: true + }, + { + text: "@tool chỉ dùng được trong hệ thống đa agent, còn subclass Tool dành cho đơn agent", + explain: "Mọi agent (đơn hay đa) đều có thể dùng cả hai cách - không có hạn chế này.", + }, + { + text: "Decorator @tool thay thế docstring, còn subclass không được chứa docstring", + explain: "Cả hai phương pháp đều cần docstring rõ ràng. Decorator không thay thế docstring, subclass vẫn có thể có docstring.", + } +]} +/> + +--- + +### Q2: CodeAgent xử lý các nhiệm vụ nhiều bước bằng cách tiếp cận ReAct (Reason + Act) như thế nào? + +Phát biểu nào mô tả đúng cách CodeAgent thực thi nhiều bước để giải quyết tác vụ? + + + +--- + +### Q3: Lợi ích chính của việc chia sẻ tool trên Hugging Face Hub là gì? + +Lý do chính nào khiến nhà phát triển tải lên và chia sẻ tool tùy chỉnh của họ? + + + +--- + +### Q4: ToolCallingAgent khác CodeAgent ở cách thực thi hành động. Phát biểu nào đúng? + +Chọn mô tả chính xác về cách ToolCallingAgent hoạt động. + + + +--- + +### Q5: Những gì có trong default toolbox của smolagents và tại sao nên dùng nó? + +Phát biểu nào mô tả đúng mục đích và nội dung của default toolbox trong smolagents? + + + +--- + +Chúc mừng bạn đã hoàn thành bài kiểm tra! 🎉 Nếu có câu hỏi nào khó, hãy xem lại các phần *Code Agents*, *Tool Calling Agents* hoặc *Tools* để củng cố kiến thức. Nếu bạn đạt điểm tuyệt đối, bạn đang trên đường trở thành bậc thầy xây dựng ứng dụng smolagents! \ No newline at end of file diff --git a/units/vi/unit2/smolagents/retrieval_agents.mdx b/units/vi/unit2/smolagents/retrieval_agents.mdx new file mode 100644 index 000000000..f0ed171cd --- /dev/null +++ b/units/vi/unit2/smolagents/retrieval_agents.mdx @@ -0,0 +1,163 @@ + + +# Xây dựng hệ thống RAG mang tính tác nhân + + +Bạn có thể theo dõi mã trong notebook này để chạy trên Google Colab. + + +Hệ thống Tạo câu trả lời kết hợp truy xuất dữ liệu (RAG) kết hợp khả năng truy xuất dữ liệu và tạo câu trả lời để đưa ra phản hồi theo ngữ cảnh. Ví dụ: truy vấn của người dùng được chuyển đến công cụ tìm kiếm, kết quả truy xuất được cung cấp cho mô hình cùng với truy vấn. Mô hình sau đó tạo phản hồi dựa trên truy vấn và thông tin đã truy xuất. + +RAG mang tính tác nhân (Agentic RAG) mở rộng hệ thống RAG truyền thống bằng cách **kết hợp các tác nhân tự trị với truy xuất tri thức động**. + +Trong khi hệ thống RAG truyền thống sử dụng LLM để trả lời truy vấn dựa trên dữ liệu đã truy xuất, RAG mang tính tác nhân **cho phép kiểm soát thông minh cả quá trình truy xuất và tạo câu trả lời**, cải thiện hiệu quả và độ chính xác. + +Hệ thống RAG truyền thống gặp phải những hạn chế chính như **chỉ dựa vào một bước truy xuất duy nhất** và tập trung vào độ tương đồng ngữ nghĩa trực tiếp với truy vấn của người dùng, điều này có thể bỏ sót thông tin liên quan. + +RAG mang tính tác nhân giải quyết những vấn đề này bằng cách cho phép tác nhân tự động xây dựng truy vấn tìm kiếm, đánh giá kết quả truy xuất và thực hiện nhiều bước truy xuất để tạo ra kết quả toàn diện và phù hợp hơn. + +## Truy xuất cơ bản với DuckDuckGo + +Hãy xây dựng một tác nhân đơn giản có thể tìm kiếm web bằng DuckDuckGo. Tác nhân này sẽ truy xuất thông tin và tổng hợp phản hồi để trả lời các truy vấn. Với RAG mang tính tác nhân, tác nhân của Alfred có thể: + +* Tìm kiếm xu hướng tiệc siêu anh hùng mới nhất +* Tinh chỉnh kết quả để bao gồm các yếu tố sang trọng +* Tổng hợp thông tin thành một kế hoạch hoàn chỉnh + +Đây là cách tác nhân của Alfred có thể đạt được điều này: + +```python +from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel + +# Khởi tạo công cụ tìm kiếm +search_tool = DuckDuckGoSearchTool() + +# Khởi tạo model +model = InferenceClientModel() + +agent = CodeAgent( + model=model, + tools=[search_tool], +) + +# Ví dụ sử dụng +response = agent.run( + "Search for luxury superhero-themed party ideas, including decorations, entertainment, and catering." +) +print(response) +``` + +Tác nhân tuân theo quy trình sau: + +1. **Phân tích yêu cầu:** Tác nhân của Alfred xác định các yếu tố chính của truy vấn - lập kế hoạch tiệc siêu anh hùng sang trọng, tập trung vào trang trí, giải trí và ăn uống. +2. **Thực hiện truy xuất:** Tác nhân tận dụng DuckDuckGo để tìm kiếm thông tin mới nhất và phù hợp nhất, đảm bảo phù hợp với sở thích tinh tế của Alfred cho một sự kiện sang trọng. +3. **Tổng hợp thông tin:** Sau khi thu thập kết quả, tác nhân xử lý chúng thành một kế hoạch hành động mạch lạc cho Alfred, bao gồm mọi khía cạnh của bữa tiệc. +4. **Lưu trữ để tham khảo sau:** Tác nhân lưu trữ thông tin đã truy xuất để dễ dàng truy cập khi lập kế hoạch cho các sự kiện trong tương lai, tối ưu hóa hiệu quả trong các tác vụ tiếp theo. + +## Công cụ cơ sở tri thức tùy chỉnh + +Đối với các tác vụ chuyên biệt, một cơ sở tri thức tùy chỉnh có thể rất hữu ích. Hãy tạo một công cụ truy vấn cơ sở dữ liệu vector về tài liệu kỹ thuật hoặc tri thức chuyên ngành. Sử dụng tìm kiếm ngữ nghĩa, tác nhân có thể tìm thấy thông tin phù hợp nhất cho nhu cầu của Alfred. + +Cơ sở dữ liệu vector lưu trữ biểu diễn số (embeddings) của văn bản hoặc dữ liệu khác, được tạo bởi các model học máy. Nó cho phép tìm kiếm ngữ nghĩa bằng cách xác định các ý nghĩa tương tự trong không gian nhiều chiều. + +Cách tiếp cận này kết hợp tri thức được xác định trước với tìm kiếm ngữ nghĩa để cung cấp giải pháp theo ngữ cảnh cho việc lập kế hoạch sự kiện. Với quyền truy cập tri thức chuyên biệt, Alfred có thể hoàn thiện từng chi tiết của bữa tiệc. + +Trong ví dụ này, chúng ta sẽ tạo một công cụ truy xuất ý tưởng lập kế hoạch tiệc từ cơ sở tri thức tùy chỉnh. Chúng ta sẽ sử dụng bộ truy xuất BM25 để tìm kiếm cơ sở tri thức và trả về kết quả hàng đầu, đồng thời sử dụng `RecursiveCharacterTextSplitter` để chia tài liệu thành các đoạn nhỏ hơn để tìm kiếm hiệu quả hơn. + +
+Bấm để xem bản dịch tiếng Việt + +```python +from langchain.docstore.document import Document +from langchain.text_splitter import RecursiveCharacterTextSplitter +from smolagents import Tool +from langchain_community.retrievers import BM25Retriever +from smolagents import CodeAgent, InferenceClientModel + +class PartyPlanningRetrieverTool(Tool): + name = "party_planning_retriever" + description = "Uses semantic search to retrieve relevant party planning ideas for Alfred’s superhero-themed party at Wayne Manor." + inputs = { + "query": { + "type": "string", + "description": "The query to perform. This should be a query related to party planning or superhero themes.", + } + } + output_type = "string" + + def __init__(self, docs, **kwargs): + super().__init__(**kwargs) + self.retriever = BM25Retriever.from_documents( + docs, k=5 # Retrieve the top 5 documents + ) + + def forward(self, query: str) -> str: + assert isinstance(query, str), "Your search query must be a string" + + docs = self.retriever.invoke( + query, + ) + return "\nRetrieved ideas:\n" + "".join( + [ + f"\n\n===== Idea {str(i)} =====\n" + doc.page_content + for i, doc in enumerate(docs) + ] + ) + +# Simulate a knowledge base about party planning +party_ideas = [ + {"text": "A superhero-themed masquerade ball with luxury decor, including gold accents and velvet curtains.", "source": "Party Ideas 1"}, + {"text": "Hire a professional DJ who can play themed music for superheroes like Batman and Wonder Woman.", "source": "Entertainment Ideas"}, + {"text": "For catering, serve dishes named after superheroes, like 'The Hulk's Green Smoothie' and 'Iron Man's Power Steak.'", "source": "Catering Ideas"}, + {"text": "Decorate with iconic superhero logos and projections of Gotham and other superhero cities around the venue.", "source": "Decoration Ideas"}, + {"text": "Interactive experiences with VR where guests can engage in superhero simulations or compete in themed games.", "source": "Entertainment Ideas"} +] + +source_docs = [ + Document(page_content=doc["text"], metadata={"source": doc["source"]}) + for doc in party_ideas +] + +# Split the documents into smaller chunks for more efficient search +text_splitter = RecursiveCharacterTextSplitter( + chunk_size=500, + chunk_overlap=50, + add_start_index=True, + strip_whitespace=True, + separators=["\n\n", "\n", ".", " ", ""], +) +docs_processed = text_splitter.split_documents(source_docs) + +# Create the retriever tool +party_planning_retriever = PartyPlanningRetrieverTool(docs_processed) + +# Initialize the agent +agent = CodeAgent(tools=[party_planning_retriever], model=InferenceClientModel()) + +# Example usage +response = agent.run( + "Find ideas for a luxury superhero-themed party, including entertainment, catering, and decoration options." +) + +print(response) +``` + +Agent (tác nhân) nâng cao này có thể: +1. Đầu tiên kiểm tra tài liệu để tìm thông tin liên quan +2. Kết hợp thông tin chi tiết từ cơ sở kiến thức +3. Duy trì ngữ cảnh hội thoại trong bộ nhớ + +## Khả năng Truy xuất Nâng cao + +Khi xây dựng hệ thống RAG (tìm kiếm và tạo ra câu trả lời) agentic, agent (tác nhân) có thể sử dụng các chiến lược phức tạp như: + +1. **Cải tiến Truy vấn (Query Reformulation):** Thay vì sử dụng truy vấn thô từ người dùng, agent có thể tạo ra các điều kiện tìm kiếm tối ưu hơn để khớp với tài liệu mục tiêu +2. **Truy xuất Nhiều Bước (Multi-Step Retrieval):** Agent có thể thực hiện nhiều lần tìm kiếm, sử dụng kết quả ban đầu để thông báo cho các truy vấn tiếp theo +3. **Tích hợp Nguồn (Source Integration):** Thông tin có thể được kết hợp từ nhiều nguồn như tìm kiếm web và tài liệu cục bộ +4. **Xác thực Kết quả (Result Validation):** Nội dung truy xuất có thể được phân tích về mức độ liên quan và độ chính xác trước khi đưa vào câu trả lời + +Các hệ thống RAG agentic hiệu quả đòi hỏi sự cân nhắc cẩn thận về một số khía cạnh chính. Agent **nên chọn giữa các Tools (công cụ) có sẵn dựa trên loại truy vấn và ngữ cảnh**. Hệ thống bộ nhớ giúp duy trì lịch sử hội thoại và tránh truy xuất lặp đi lặp lại. Có các chiến lược dự phòng đảm bảo hệ thống vẫn có thể cung cấp giá trị ngay cả khi các phương pháp truy xuất chính không thành công. Ngoài ra, việc triển khai các bước xác thực giúp đảm bảo tính chính xác và mức độ liên quan của thông tin được truy xuất. \ No newline at end of file diff --git a/units/vi/unit2/smolagents/tool_calling_agents.mdx b/units/vi/unit2/smolagents/tool_calling_agents.mdx new file mode 100644 index 000000000..7456226cf --- /dev/null +++ b/units/vi/unit2/smolagents/tool_calling_agents.mdx @@ -0,0 +1,73 @@ + + +# Viết các hành động dưới dạng đoạn code hoặc JSON + + +Bạn có thể theo dõi code trong notebook này mà bạn có thể chạy trên Google Colab. + + +Tool Calling Agents là loại Agent thứ hai có trong `smolagents`. Khác với Code Agent sử dụng đoạn code Python, các Agent này **sử dụng khả năng gọi công cụ tích hợp sẵn của các nhà cung cấp LLM** để tạo ra các lệnh gọi công cụ dưới dạng **cấu trúc JSON**. Đây là cách tiếp cận tiêu chuẩn được sử dụng bởi OpenAI, Anthropic và nhiều nhà cung cấp khác. + +Hãy xem một ví dụ. Khi Alfred muốn tìm kiếm dịch vụ catering và ý tưởng tiệc tùng, một `CodeAgent` sẽ tạo và chạy code Python như thế này: + +```python +for query in [ + "Best catering services in Gotham City", + "Party theme ideas for superheroes" +]: + print(web_search(f"Search for: {query}")) +``` + +Trong khi đó, `ToolCallingAgent` sẽ tạo ra cấu trúc JSON: + +```python +[ + {"name": "web_search", "arguments": "Best catering services in Gotham City"}, + {"name": "web_search", "arguments": "Party theme ideas for superheroes"} +] +``` + +JSON này sau đó được dùng để thực thi các lệnh gọi công cụ. + +Dù `smolagents` tập trung chủ yếu vào `CodeAgents` vì [chúng hoạt động tốt hơn tổng thể](https://arxiv.org/abs/2402.01030), `ToolCallingAgents` có thể hiệu quả cho các hệ thống đơn giản không cần xử lý biến hay các lệnh gọi công cụ phức tạp. + +![Hành động dạng Code vs JSON](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/code_vs_json_actions.png) + +## Tool Calling Agents hoạt động thế nào? + +Tool Calling Agents tuân theo quy trình làm việc đa bước giống như Code Agents (xem chi tiết ở [phần trước](./code_agents)). + +Điểm khác biệt chính nằm ở **cách chúng cấu trúc hành động**: thay vì code có thể thực thi, chúng **tạo ra các đối tượng JSON xác định tên công cụ và tham số**. Hệ thống sau đó **phân tích các hướng dẫn này** để thực thi công cụ phù hợp. + +## Ví dụ: Chạy Tool Calling Agent + +Hãy xem lại ví dụ trước khi Alfred bắt đầu chuẩn bị tiệc, nhưng lần này ta sẽ dùng `ToolCallingAgent` để làm nổi bật sự khác biệt. Ta sẽ xây dựng một Agent có thể tìm kiếm web bằng DuckDuckGo, giống như trong ví dụ Code Agent. Điểm khác biệt duy nhất là loại Agent - framework sẽ xử lý mọi thứ còn lại: + +```python +from smolagents import ToolCallingAgent, DuckDuckGoSearchTool, HfApiModel + +agent = ToolCallingAgent(tools=[DuckDuckGoSearchTool()], model=HfApiModel()) + +agent.run("Search for the best music recommendations for a party at the Wayne's mansion.") +``` + +Khi kiểm tra trace của Agent, thay vì thấy `Executing parsed code:`, bạn sẽ thấy: + +```text +╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Calling tool: 'web_search' with arguments: {'query': "best music recommendations for a party at Wayne's │ +│ mansion"} │ +╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +Agent tạo ra một lệnh gọi công cụ có cấu trúc mà hệ thống xử lý để tạo đầu ra, thay vì trực tiếp thực thi code như `CodeAgent`. + +Giờ khi đã hiểu cả hai loại Agent, ta có thể chọn loại phù hợp cho nhu cầu của mình. Hãy tiếp tục khám phá `smolagents` để biến bữa tiệc của Alfred thành công! 🎉 + +## Tài nguyên + +- [Tài liệu ToolCallingAgent](https://huggingface.co/docs/smolagents/v1.8.1/en/reference/agents#smolagents.ToolCallingAgent) - Tài liệu chính thức về ToolCallingAgent \ No newline at end of file diff --git a/units/vi/unit2/smolagents/tools.mdx b/units/vi/unit2/smolagents/tools.mdx new file mode 100644 index 000000000..cb554f3a4 --- /dev/null +++ b/units/vi/unit2/smolagents/tools.mdx @@ -0,0 +1,269 @@ + + +# Công cụ + +Như ta đã tìm hiểu ở [Chương 1](https://huggingface.co/learn/agents-course/unit1/tools), các Agent (tác nhân) sử dụng Tools (công cụ) để thực hiện nhiều hành động khác nhau. Trong `smolagents`, công cụ được xem như **các hàm mà LLM (mô hình ngôn ngữ lớn) có thể gọi trong hệ thống agent**. + +Để tương tác với một công cụ, LLM cần **mô tả giao diện** với các thành phần chính: + +- **Tên**: Tên gọi của công cụ +- **Mô tả công cụ**: Chức năng của công cụ +- **Kiểu và mô tả đầu vào**: Các tham số mà công cụ chấp nhận +- **Kiểu đầu ra**: Kết quả trả về của công cụ + +Ví dụ, khi chuẩn bị cho một bữa tiệc tại Wayne Manor, Alfred cần nhiều công cụ khác nhau để thu thập thông tin - từ tìm kiếm dịch vụ catering đến ý tưởng chủ đề tiệc. Đây là cách một công cụ tìm kiếm đơn giản có thể trông như thế nào: + +- **Tên:** `web_search` +- **Mô tả công cụ:** Tìm kiếm trên web theo truy vấn cụ thể +- **Đầu vào:** `query` (chuỗi) - Từ khóa tìm kiếm +- **Đầu ra:** Chuỗi chứa kết quả tìm kiếm + +Nhờ các công cụ này, Alfred có thể đưa ra quyết định sáng suốt và thu thập mọi thông tin cần thiết để lên kế hoạch cho bữa tiệc hoàn hảo. + +Dưới đây là minh họa cách một lệnh gọi công cụ được xử lý: + +![Agentic pipeline from https://huggingface.co/docs/smolagents/conceptual_guides/react](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/Agent_ManimCE.gif) + +## Cách tạo công cụ + +Trong `smolagents`, ta có thể định nghĩa công cụ theo 2 cách: +1. **Sử dụng decorator `@tool`** cho các công cụ đơn giản dựa trên hàm +2. **Tạo lớp con kế thừa `Tool`** cho các chức năng phức tạp hơn + +### Decorator `@tool` + +Decorator `@tool` là **cách được khuyến nghị để định nghĩa các công cụ đơn giản**. Bên trong, smolagents sẽ tự động phân tích thông tin cơ bản về hàm từ Python. Vì vậy, nếu bạn đặt tên hàm rõ ràng và viết docstring tốt, LLM sẽ dễ sử dụng hơn. + +Với cách tiếp cận này, ta định nghĩa một hàm với: + +- **Tên hàm rõ ràng, mô tả đúng** để LLM hiểu được mục đích +- **Chú thích kiểu dữ liệu** cho cả đầu vào và đầu ra để đảm bảo sử dụng đúng +- **Mô tả chi tiết**, bao gồm phần `Args:` mô tả rõ từng tham số. Những mô tả này cung cấp ngữ cảnh quan trọng cho LLM, nên cần viết cẩn thận. + +#### Tạo công cụ tìm dịch vụ catering được đánh giá cao nhất + +Alfred Catering + + +Bạn có thể theo dõi code trong notebook này và chạy trên Google Colab. + + +Giả sử Alfred đã quyết định thực đơn cho bữa tiệc nhưng cần giúp chuẩn bị đồ ăn cho số lượng khách lớn. Để làm điều này, anh ấy muốn thuê dịch vụ catering và cần tìm những lựa chọn được đánh giá cao nhất. Alfred có thể sử dụng một công cụ để tìm kiếm các dịch vụ catering tốt nhất trong khu vực. + +Dưới đây là ví dụ cách Alfred dùng decorator `@tool` để thực hiện việc này: + +```python +from smolagents import CodeAgent, HfApiModel, tool + +# Giả sử ta có hàm tìm dịch vụ catering được đánh giá cao nhất +@tool +def catering_service_tool(query: str) -> str: + """ + Công cụ này trả về dịch vụ catering được đánh giá cao nhất tại Gotham City. + + Args: + query: Từ khóa tìm kiếm dịch vụ catering. + """ + # Danh sách dịch vụ và điểm đánh giá + services = { + "Gotham Catering Co.": 4.9, + "Wayne Manor Catering": 4.8, + "Gotham City Events": 4.7, + } + + # Tìm dịch vụ có điểm cao nhất (mô phỏng lọc truy vấn tìm kiếm) + best_service = max(services, key=services.get) + + return best_service + + +agent = CodeAgent(tools=[catering_service_tool], model=HfApiModel()) + +# Chạy agent để tìm dịch vụ catering tốt nhất +result = agent.run( + "Bạn có thể cho tôi tên dịch vụ catering được đánh giá cao nhất ở Gotham City không?" +) + +print(result) # Kết quả: Gotham Catering Co. +``` + +### Định nghĩa công cụ bằng lớp Python + +Cách này liên quan đến việc tạo lớp con kế thừa từ [`Tool`](https://huggingface.co/docs/smolagents/v1.8.1/en/reference/tools#smolagents.Tool). Với các công cụ phức tạp, ta có thể triển khai một lớp thay vì hàm. Lớp này bao bọc hàm cùng metadata giúp LLM hiểu cách sử dụng. Trong lớp này, ta định nghĩa: + +- `name`: Tên công cụ +- `description`: Mô tả dùng để đưa vào system prompt của agent +- `inputs`: Từ điển với các key `type` và `description`, cung cấp thông tin giúp trình thông dịch Python xử lý đầu vào +- `output_type`: Chỉ định kiểu đầu ra mong đợi +- `forward`: Phương thức chứa logic inference để thực thi + +Dưới đây là ví dụ về công cụ được xây dựng bằng `Tool` và cách tích hợp vào `CodeAgent`. + +#### Tạo công cụ sinh ý tưởng tiệc siêu anh hùng + +Bữa tiệc tại dinh thự của Alfred có **chủ đề siêu anh hùng**, nhưng anh ấy cần ý tưởng sáng tạo để làm nó thực sự đặc biệt. Là một người tổ chức xuất sắc, Alfred muốn gây bất ngờ cho khách mời với chủ đề độc đáo. + +Để làm điều này, anh ấy có thể dùng agent sinh ý tưởng chủ đề tiệc siêu anh hùng dựa trên thể loại cho trước. Nhờ vậy, Alfred có thể tìm được chủ đề hoàn hảo cho bữa tiệc. + +```python +from smolagents import Tool, CodeAgent, HfApiModel + +class SuperheroPartyThemeTool(Tool): + name = "superhero_party_theme_generator" + description = """ + Công cụ đề xuất ý tưởng tiệc chủ đề siêu anh hùng sáng tạo dựa trên thể loại. + Trả về ý tưởng chủ đề tiệc độc đáo.""" + + inputs = { + "category": { + "type": "string", + "description": "Thể loại tiệc siêu anh hùng (vd: 'anh hùng cổ điển', 'vũ hội mặt nạ phản diện', 'Gotham tương lai').", + } + } + + output_type = "string" + + def forward(self, category: str): + themes = { + "anh hùng cổ điển": "Dạ tiệc Justice League: Khách mời hóa thân thành các siêu anh hùng DC yêu thích với cocktail chủ đề như 'The Kryptonite Punch'.", + "vũ hội mặt nạ phản diện": "Dạ vũ Gotham Rogues: Vũ hội bí ẩn nơi khách mời hóa trang thành các phản diện Batman kinh điển.", + "Gotham tương lai": "Đêm Neo-Gotham: Tiệc phong cách cyberpunk lấy cảm hứng từ Batman Beyond, với trang trí neon và gadget tương lai." + } + + return themes.get(category.lower(), "Không tìm thấy ý tưởng. Hãy thử 'anh hùng cổ điển', 'vũ hội mặt nạ phản diện', hoặc 'Gotham tương lai'.") + +# Khởi tạo công cụ +party_theme_tool = SuperheroPartyThemeTool() +agent = CodeAgent(tools=[party_theme_tool], model=HfApiModel()) + +# Chạy agent để sinh ý tưởng chủ đề tiệc +result = agent.run( + "Ý tưởng tiệc siêu anh hùng hay cho chủ đề 'vũ hội mặt nạ phản diện' là gì?" +) + +print(result) # Kết quả: "Dạ vũ Gotham Rogues: Vũ hội bí ẩn nơi khách mời hóa trang thành các phản diện Batman kinh điển." +``` + +Với công cụ này, Alfred sẽ trở thành người tổ chức siêu đẳng, mang đến bữa tiệc siêu anh hùng đáng nhớ cho khách mời! 🦸‍♂️🦸‍♀️ + +## Bộ công cụ mặc định + +`smolagents` đi kèm với các công cụ được xây dựng sẵn có thể tích hợp trực tiếp vào agent của bạn. [Bộ công cụ mặc định](https://huggingface.co/docs/smolagents/guided_tour?build-a-tool=Decorate+a+function+with+%40tool#default-toolbox) bao gồm: + +- **PythonInterpreterTool** +- **FinalAnswerTool** +- **UserInputTool** +- **DuckDuckGoSearchTool** +- **GoogleSearchTool** +- **VisitWebpageTool** + +Alfred có thể sử dụng nhiều công cụ để đảm bảo bữa tiệc tại Wayne Manor hoàn hảo: + +- Đầu tiên, dùng `DuckDuckGoSearchTool` để tìm ý tưởng tiệc siêu anh hùng sáng tạo + +- Về catering, dùng `GoogleSearchTool` để tìm dịch vụ được đánh giá cao nhất ở Gotham + +- Để sắp xếp chỗ ngồi, Alfred có thể chạy tính toán bằng `PythonInterpreterTool` + +- Sau khi thu thập đủ thông tin, tổng hợp kế hoạch bằng `FinalAnswerTool` + +Với những công cụ này, Alfred đảm bảo bữa tiệc vừa đặc biệt vừa trơn tru. 🦇💡 + +## Chia sẻ và nhập công cụ + +Một trong những tính năng mạnh mẽ nhất của **smolagents** là khả năng chia sẻ công cụ tùy chỉnh lên Hub và tích hợp liền mạch các công cụ từ cộng đồng. Điều này bao gồm kết nối với **HF Spaces** và **LangChain tools**, giúp Alfred nâng cao khả năng tổ chức những bữa tiệc đáng nhớ tại Wayne Manor. 🎭 + +Với các tích hợp này, Alfred có thể tận dụng các công cụ lập kế hoạch sự kiện tiên tiến - từ điều chỉnh ánh sáng tạo không khí hoàn hảo, lên playlist lý tưởng cho tiệc, đến phối hợp với các dịch vụ catering tốt nhất Gotham. + +Dưới đây là các ví dụ minh họa cách những chức năng này nâng tầm trải nghiệm tiệc: + +### Chia sẻ công cụ lên Hub + +Chia sẻ công cụ tùy chỉnh với cộng đồng rất dễ dàng! Chỉ cần tải lên tài khoản Hugging Face của bạn bằng phương thức `push_to_hub()`. + +Ví dụ, Alfred có thể chia sẻ `party_theme_tool` để giúp người khác tìm dịch vụ catering tốt nhất ở Gotham: + +```python +party_theme_tool.push_to_hub("{your_username}/party_theme_tool", token="") +``` + +### Nhập công cụ từ Hub + +Bạn có thể dễ dàng nhập công cụ từ người dùng khác bằng hàm `load_tool()`. Ví dụ, Alfred muốn tạo hình ảnh quảng bá cho bữa tiệc bằng AI. Thay vì xây từ đầu, anh ấy có thể sử dụng công cụ định nghĩa sẵn từ cộng đồng: + +```python +from smolagents import load_tool, CodeAgent, HfApiModel + +image_generation_tool = load_tool( + "m-ric/text-to-image", + trust_remote_code=True +) + +agent = CodeAgent( + tools=[image_generation_tool], + model=HfApiModel() +) + +agent.run("Tạo hình ảnh bữa tiệc siêu anh hùng sang trọng tại Wayne Manor với các siêu anh hùng hư cấu.") +``` + +### Nhập HF Space làm công cụ + +Bạn cũng có thể nhập HF Space làm công cụ bằng `Tool.from_space()`. Điều này mở ra khả năng tích hợp với hàng ngàn spaces từ cộng đồng cho các tác vụ từ tạo ảnh đến phân tích dữ liệu. + +Công cụ sẽ kết nối với backend Gradio của space thông qua `gradio_client`, nên hãy đảm bảo cài đặt nó qua `pip` nếu chưa có. + +Để chuẩn bị cho tiệc, Alfred có thể dùng một HF Space có sẵn để tạo ảnh AI cho thông báo (thay vì dùng công cụ xây sẵn như trước). Hãy xây dựng nó! + +```python +from smolagents import CodeAgent, HfApiModel, Tool + +image_generation_tool = Tool.from_space( + "black-forest-labs/FLUX.1-schnell", + name="image_generator", + description="Tạo ảnh từ prompt" +) + +model = HfApiModel("Qwen/Qwen2.5-Coder-32B-Instruct") + +agent = CodeAgent(tools=[image_generation_tool], model=model) + +agent.run( + "Cải thiện prompt này rồi tạo ảnh từ nó.", + additional_args={'user_prompt': 'Bữa tiệc siêu anh hùng hoành tráng tại Wayne Manor, với Alfred điều hành một dạ tiệc sang trọng'} +) +``` + +### Nhập công cụ LangChain + +Chúng ta sẽ thảo luận về framework `LangChain` trong các phần tiếp theo. Hiện tại, ta chỉ cần biết có thể tái sử dụng LangChain tools trong workflow smolagents! + +Bạn có thể dễ dàng tải LangChain tools bằng phương thức `Tool.from_langchain()`. Alfred, với tính cách cầu toàn, đang chuẩn bị cho một đêm siêu anh hùng ngoạn mục tại Wayne Manor khi gia đình Wayne đi vắng. Để đảm bảo mọi chi tiết vượt mong đợi, anh ấy sử dụng LangChain tools để tìm ý tưởng giải trí đỉnh cao. + +Bằng cách dùng `Tool.from_langchain()`, Alfred dễ dàng thêm chức năng tìm kiếm nâng cao vào smolagent của mình, cho phép anh ấy khám phá ý tưởng tiệc và dịch vụ độc quyền chỉ với vài lệnh. + +Cách thực hiện: + +```python +from langchain.agents import load_tools +from smolagents import CodeAgent, HfApiModel, Tool + +search_tool = Tool.from_langchain(load_tools(["serpapi"])[0]) + +agent = CodeAgent(tools=[search_tool], model=model) + +agent.run("Tìm kiếm ý tưởng giải trí sang trọng cho sự kiện chủ đề siêu anh hùng, như biểu diễn trực tiếp và trải nghiệm tương tác.") +``` + +Với thiết lập này, Alfred có thể nhanh chóng tìm thấy các lựa chọn giải trí sang trọng, đảm bảo khách mời thượng lưu của Gotham có trải nghiệm khó quên. Công cụ này giúp anh ấy tạo nên sự kiện chủ đề siêu anh hùng hoàn hảo tại Wayne Manor! 🎉 + +## Tài nguyên + +- [Hướng dẫn về công cụ](https://huggingface.co/docs/smolagents/tutorials/tools) - Khám phá hướng dẫn này để học cách làm việc hiệu quả với công cụ +- [Tài liệu công cụ](https://huggingface.co/docs/smolagents/v1.8.1/en/reference/tools) - Tài liệu tham khảo toàn diện về công cụ +- [Hướng dẫn từng bước về công cụ](https://huggingface.co/docs/smolagents/v1.8.1/en/guided_tour#tools) - Hướng dẫn từng bước giúp xây dựng và sử dụng công cụ hiệu quả +- [Xây dựng Agent hiệu quả](https://huggingface.co/docs/smolagents/tutorials/building_good_agents) - Hướng dẫn chi tiết về best practices để phát triển agent tùy chỉnh đáng tin cậy và hiệu suất cao \ No newline at end of file diff --git a/units/vi/unit2/smolagents/vision_agents.mdx b/units/vi/unit2/smolagents/vision_agents.mdx new file mode 100644 index 000000000..21fa7a723 --- /dev/null +++ b/units/vi/unit2/smolagents/vision_agents.mdx @@ -0,0 +1,222 @@ + + +# Các Agent thị giác với smolagents + + +Các ví dụ trong phần này yêu cầu truy cập vào một VLM model mạnh. Chúng mình đã thử nghiệm chúng bằng GPT-4o API. +Tuy nhiên, bài viết Tại sao nên dùng smolagents thảo luận về các giải pháp thay thế được hỗ trợ bởi smolagents và Hugging Face. Nếu bạn muốn khám phá các lựa chọn khác, hãy xem qua phần đó. + + +Trao quyền xử lý thị giác cho các Agent là yếu tố quan trọng để giải quyết các tác vụ vượt ra ngoài xử lý văn bản. Nhiều thách thức thực tế như duyệt web hay hiểu tài liệu đòi hỏi phân tích nội dung hình ảnh phong phú. May mắn thay, `smolagents` cung cấp hỗ trợ sẵn cho các vision-language models (VLMs), giúp agent có thể xử lý và phân tích hình ảnh hiệu quả. + +Trong ví dụ này, hãy tưởng tượng Alfred - quản gia tại Dinh Wayne - được giao nhiệm vụ xác minh danh tính các vị khách tham dự bữa tiệc. Như bạn có thể đoán, Alfred có thể không quen biết tất cả mọi người. Để giúp ông ấy, ta có thể dùng một agent xác minh danh tính bằng cách tìm kiếm thông tin hình ảnh về ngoại hình thông qua VLM. Điều này sẽ giúp Alfred đưa ra quyết định sáng suốt về việc ai được phép vào. Hãy cùng xây dựng ví dụ này! + + +## Cung cấp hình ảnh khi khởi chạy Agent + + +Bạn có thể theo dõi code trong notebook này và chạy trên Google Colab. + + +Với cách tiếp cận này, hình ảnh được truyền cho agent ngay từ đầu và lưu dưới dạng `task_images` cùng với prompt nhiệm vụ. Agent sẽ xử lý các hình ảnh này trong suốt quá trình chạy. + +Xét trường hợp Alfred muốn xác minh danh tính các siêu anh hùng tham dự tiệc. Ông ấy đã có sẵn dataset hình ảnh từ các bữa tiệc trước với tên khách mời. Khi có hình ảnh khách mới, agent có thể so sánh với dataset hiện có và đưa ra quyết định. + +Trong trường hợp này, một vị khách đang cố vào cửa và Alfred nghi ngờ đây là Joker đang đóng giả Wonder Woman. Alfred cần xác minh danh tính để ngăn kẻ không mong muốn vào. + +Hãy bắt đầu xây dựng ví dụ. Đầu tiên, ta load các hình ảnh. Ở đây chúng ta dùng hình từ Wikipedia để minh họa: + +```python +from PIL import Image +import requests +from io import BytesIO + +image_urls = [ + "https://upload.wikimedia.org/wikipedia/commons/e/e8/The_Joker_at_Wax_Museum_Plus.jpg", # Ảnh Joker + "https://upload.wikimedia.org/wikipedia/en/9/98/Joker_%28DC_Comics_character%29.jpg" # Ảnh Joker +] + +images = [] +for url in image_urls: + response = requests.get(url) + image = Image.open(BytesIO(response.content)).convert("RGB") + images.append(image) +``` + +Giờ đây agent sẽ cho chúng ta biết liệu một vị khách có thực sự là siêu anh hùng (Wonder Woman) hay là phản diện (The Joker). + +```python +from smolagents import CodeAgent, OpenAIServerModel + +model = OpenAIServerModel(model_id="gpt-4o") + +# Khởi tạo agent +agent = CodeAgent( + tools=[], + model=model, + max_steps=20, + verbosity_level=2 +) + +response = agent.run( + """ + Mô tả trang phục và trang điểm của nhân vật truyện tranh trong các ảnh này và trả về mô tả. + Cho biết vị khách này là The Joker hay Wonder Woman. + """, + images=images +) +``` + +Kết quả chạy thử của mình như sau (kết quả của bạn có thể khác): + +```python + { + 'Costume and Makeup - First Image': ( + 'Áo khoác tím và cà vạt lụa tím trên áo sơ mi màu vàng mù tạt.', + 'Sơn mặt trắng với các đường nét phóng đại, lông mày đen, trang điểm mắt xanh, môi đỏ tạo nụ cười rộng.' + ), + 'Costume and Makeup - Second Image': ( + 'Vest đen với hoa cài ve áo, cầm lá bài.', + 'Da xanh xao, tóc xanh lá, môi đỏ với nụ cười khoác lác.' + ), + 'Character Identity': 'Nhân vật này giống với mô tả về The Joker từ truyện tranh.' + } +``` + +Trường hợp này, kết quả cho thấy đây là kẻ mạo danh nên ta có thể ngăn Joker vào tiệc! + +## Thu thập hình ảnh động trong quá trình chạy + + +Bạn có thể theo dõi code trong file Python này + + +Cách tiếp cận trước rất hữu ích nhưng trong trường hợp khách không có trong database, ta cần phương án khác. Một giải pháp là thu thập hình ảnh/thông tin động từ nguồn bên ngoài như duyệt web. + +Ở cách này, hình ảnh được thêm động vào bộ nhớ agent khi chạy. Các agent trong `smolagents` dựa trên lớp `MultiStepAgent` - một abstraction của framework ReAct. Lớp này hoạt động theo chu kỳ có cấu trúc: + +1. **SystemPromptStep:** Lưu prompt hệ thống +2. **TaskStep:** Ghi nhận truy vấn người dùng và input +3. **ActionStep:** Ghi lại logs từ hành động và kết quả + +Cách tiếp cận này cho phép agent tích hợp thông tin hình ảnh động và phản ứng linh hoạt. Dưới đây là sơ đồ minh họa quy trình làm việc động: + +![Thu thập hình ảnh động](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/smolagents-can-see/diagram_adding_vlms_smolagents.png) + +Giờ hãy xây dựng ví dụ hoàn chỉnh. Lần này Alfred muốn toàn quyền kiểm soát quy trình xác minh qua duyệt web. Ta cần một bộ tools mới cho agent, sử dụng Selenium và Helium để tự động hóa trình duyệt. Hãy cài đặt các thư viện cần thiết: + +```bash +pip install "smolagents[all]" helium selenium python-dotenv +``` + +Chúng ta cần các tools duyệt web như `search_item_ctrl_f`, `go_back`, và `close_popups` để agent hành xử như người dùng thực: + +```python +@tool +def search_item_ctrl_f(text: str, nth_result: int = 1) -> str: + """ + Tìm kiếm text trên trang hiện tại bằng Ctrl + F và nhảy đến kết quả thứ n. + Args: + text: Chuỗi cần tìm + nth_result: Vị trí kết quả cần nhảy đến (mặc định: 1) + """ + elements = driver.find_elements(By.XPATH, f"//*[contains(text(), '{text}')]") + if nth_result > len(elements): + raise Exception(f"Match n°{nth_result} not found (only {len(elements)} matches found)") + result = f"Found {len(elements)} matches for '{text}'." + elem = elements[nth_result - 1] + driver.execute_script("arguments[0].scrollIntoView(true);", elem) + result += f"Focused on element {nth_result} of {len(elements)}" + return result + + +@tool +def go_back() -> None: + """Quay lại trang trước.""" + driver.back() + + +@tool +def close_popups() -> str: + """ + Đóng các pop-up/modal hiển thị trên trang. Dùng để tắt các cửa sổ pop-up! Không áp dụng cho banner cookie. + """ + webdriver.ActionChains(driver).send_keys(Keys.ESCAPE).perform() +``` + +Chúng ta cần chức năng chụp màn hình để VLM agent xử lý. Chức năng này chụp ảnh và lưu vào `step_log.observations_images = [image.copy()]`: + +```python +def save_screenshot(step_log: ActionStep, agent: CodeAgent) -> None: + sleep(1.0) # Chờ animation JavaScript trước khi chụp + driver = helium.get_driver() + current_step = step_log.step_number + if driver is not None: + for step_logs in agent.logs: # Xóa ảnh cũ để xử lý tối ưu + if isinstance(step_log, ActionStep) and step_log.step_number <= current_step - 2: + step_logs.observations_images = None + png_bytes = driver.get_screenshot_as_png() + image = Image.open(BytesIO(png_bytes)) + print(f"Đã chụp ảnh màn hình trình duyệt: {image.size} pixels") + step_log.observations_images = [image.copy()] # Tạo bản sao để đảm bảo lưu trữ + + # Cập nhật thông tin URL hiện tại + url_info = f"Current url: {driver.current_url}" + step_log.observations = url_info if step_logs.observations is None else step_log.observations + "\n" + url_info + return +``` + +Hàm này được truyền vào agent qua `step_callback` để kích hoạt sau mỗi bước chạy. + +Giờ ta có thể tạo vision agent duyệt web, cung cấp các tools đã tạo cùng `DuckDuckGoSearchTool` để thu thập thông tin xác minh danh tính: + +```python +from smolagents import CodeAgent, OpenAIServerModel, DuckDuckGoSearchTool +model = OpenAIServerModel(model_id="gpt-4o") + +agent = CodeAgent( + tools=[DuckDuckGoSearchTool(), go_back, close_popups, search_item_ctrl_f], + model=model, + additional_authorized_imports=["helium"], + step_callbacks=[save_screenshot], + max_steps=20, + verbosity_level=2, +) +``` + +Với setup này, Alfred đã sẵn sàng kiểm tra danh tính khách mời: + +```python +agent.run(""" +Tôi là Alfred, quản gia Dinh Wayne, chịu trách nhiệm xác minh danh tính khách tới dự tiệc. Một siêu anh hùng tự nhận là Wonder Woman vừa đến cổng. + +Hãy tìm kiếm hình ảnh Wonder Woman và tạo mô tả chi tiết. Đồng thời truy cập Wikipedia để thu thập thông tin ngoại hình. Từ đó tôi có thể quyết định cho phép cô ấy vào hay không. +""" + helium_instructions) +``` + +Chúng ta thêm `helium_instructions` vào prompt để điều hướng agent duyệt web đúng cách. + +Xem cách hoạt động qua video sau: + + + +Kết quả cuối cùng: + +```python +Final answer: Wonder Woman thường được mô tả mặc áo nịt ngực đỏ và vàng, quần/váy xanh dương có sao trắng, vương miện vàng, vòng tay bạc và dây thừng vàng Lasso of Truth. Cô là Công chúa Diana của Themyscira, được biết đến với tên Diana Prince. +``` + +Vậy là chúng ta đã tạo thành công bộ xác minh danh tính cho bữa tiệc! Alfred giờ đã có công cụ cần thiết để đảm bảo chỉ đúng người được vào. Mọi thứ đã sẵn sàng cho một bữa tiệc vui vẻ tại Dinh Wayne! + + +## Đọc thêm + +- [We just gave sight to smolagents](https://huggingface.co/blog/smolagents-can-see) - Blog mô tả chức năng vision agent +- [Web Browser Automation with Agents 🤖🌐](https://huggingface.co/docs/smolagents/examples/web_browser) - Ví dụ về duyệt web bằng vision agent +- [Web Browser Vision Agent Example](https://github.com/huggingface/smolagents/blob/main/src/smolagents/vision_web_browser.py) - Ví dụ về duyệt web bằng vision agent \ No newline at end of file diff --git a/units/vi/unit2/smolagents/why_use_smolagents.mdx b/units/vi/unit2/smolagents/why_use_smolagents.mdx new file mode 100644 index 000000000..57e9e9b3f --- /dev/null +++ b/units/vi/unit2/smolagents/why_use_smolagents.mdx @@ -0,0 +1,67 @@ +![smolagents banner](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smolagents/license_to_call.png) +# Tại sao nên dùng smolagents + +Trong Mô-đun này, chúng ta sẽ khám phá ưu nhược điểm của [smolagents](https://huggingface.co/docs/smolagents/en/index), giúp bạn đưa ra quyết định sáng suốt về việc liệu đây có phải framework phù hợp cho nhu cầu của mình không. + +## `smolagents` là gì? + +`smolagents` là một framework đơn giản nhưng mạnh mẽ để xây dựng các AI Agent. Nó cung cấp cho LLM khả năng _tương tác_ với thế giới thực, như tìm kiếm hay tạo ảnh. + +Như đã học ở Chương 1, AI Agent là các chương trình sử dụng LLM để tạo **'suy nghĩ'** dựa trên **'quan sát'** để thực hiện **'hành động'**. Hãy cùng tìm hiểu cách triển khai điều này trong smolagents. + +### Ưu điểm chính của `smolagents` +- **Đơn giản:** Độ phức tạp code và abstraction tối thiểu, giúp framework dễ hiểu, áp dụng và mở rộng +- **Hỗ trợ LLM linh hoạt:** Hoạt động với mọi LLM thông qua tích hợp công cụ Hugging Face và API bên ngoài +- **Tiếp cận Code-First:** Hỗ trợ hàng đầu cho Code Agent - các Agent viết hành động trực tiếp bằng code, loại bỏ nhu cầu parse và đơn giản hóa tool calling +- **Tích hợp HF Hub:** Liên kết liền mạch với Hugging Face Hub, cho phép sử dụng Gradio Space như công cụ + +### Khi nào nên dùng smolagents? + +Với những ưu điểm trên, khi nào ta nên chọn smolagents thay framework khác? + +smolagents lý tưởng khi: +- Bạn cần **giải pháp nhẹ và tối giản** +- Muốn **thử nghiệm nhanh** không cấu hình phức tạp +- **Logic ứng dụng đơn giản** + +### Hành động bằng Code vs. JSON +Khác với các framework khác nơi Agent viết hành động bằng JSON, `smolagents` **tập trung vào tool call bằng code**, đơn giản hóa quá trình thực thi. Vì không cần parse JSON để xây code gọi công cụ: đầu ra có thể chạy trực tiếp. + +Sơ đồ sau minh họa sự khác biệt: + +![Code vs. JSON actions](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/code_vs_json_actions.png) + +Để ôn lại khác biệt giữa Hành động Code vs JSON, bạn có thể xem lại [phần Actions trong Chương 1](https://huggingface.co/learn/agents-course/unit1/actions#actions-enabling-the-agent-to-engage-with-its-environment). + +### Các loại Agent trong `smolagents` + +Agent trong `smolagents` hoạt động như agent đa bước (**multi-step agent**). + +Mỗi [`MultiStepAgent`](https://huggingface.co/docs/smolagents/main/en/reference/agents#smolagents.MultiStepAgent) thực hiện: +- Một suy nghĩ +- Một tool call và thực thi + +Ngoài việc dùng **[CodeAgent](https://huggingface.co/docs/smolagents/main/en/reference/agents#smolagents.CodeAgent)** làm loại Agent chính, smolagents cũng hỗ trợ **[ToolCallingAgent](https://huggingface.co/docs/smolagents/main/en/reference/agents#smolagents.ToolCallingAgent)** - Agent viết tool call bằng JSON. + +Chúng ta sẽ khám phá chi tiết từng loại Agent trong các phần tiếp theo. + + +Trong smolagents, công cụ được định nghĩa bằng decorator @tool bao quanh hàm python hoặc lớp Tool. + + +### Tích hợp Model trong `smolagents` +`smolagents` hỗ trợ tích hợp LLM linh hoạt, cho phép dùng bất kỳ mô hình nào đáp ứng [tiêu chí nhất định](https://huggingface.co/docs/smolagents/main/en/reference/models). Framework cung cấp sẵn các lớp để đơn giản hóa kết nối mô hình: + +- **[TransformersModel](https://huggingface.co/docs/smolagents/main/en/reference/models#smolagents.TransformersModel):** Triển khai pipeline `transformers` local để tích hợp liền mạch +- **[HfApiModel](https://huggingface.co/docs/smolagents/main/en/reference/models#smolagents.HfApiModel):** Hỗ trợ gọi [serverless inference](https://huggingface.co/docs/huggingface_hub/main/en/guides/inference) qua [cơ sở hạ tầng Hugging Face](https://huggingface.co/docs/api-inference/index), hoặc qua nhiều [nhà cung cấp inference bên thứ ba](https://huggingface.co/docs/huggingface_hub/main/en/guides/inference#supported-providers-and-tasks) +- **[LiteLLMModel](https://huggingface.co/docs/smolagents/main/en/reference/models#smolagents.LiteLLMModel):** Tận dụng [LiteLLM](https://www.litellm.ai/) cho tương tác mô hình nhẹ +- **[OpenAIServerModel](https://huggingface.co/docs/smolagents/main/en/reference/models#smolagents.OpenAIServerModel):** Kết nối dịch vụ cung cấp giao diện API OpenAI +- **[AzureOpenAIServerModel](https://huggingface.co/docs/smolagents/main/en/reference/models#smolagents.AzureOpenAIServerModel):** Hỗ trợ tích hợp với triển khai Azure OpenAI + +Tính linh hoạt này đảm bảo developer có thể chọn mô hình và dịch vụ phù hợp nhất cho use case cụ thể, đồng thời dễ dàng thử nghiệm. + +Giờ chúng ta đã hiểu tại sao và khi nào dùng smolagents, hãy cùng khám phá sâu hơn thư viện mạnh mẽ này! + +## Tài nguyên + +- [Blog smolagents](https://huggingface.co/blog/smolagents) - Giới thiệu smolagents và tương tác code \ No newline at end of file diff --git a/units/vi/unit3/agentic-rag/agent.mdx b/units/vi/unit3/agentic-rag/agent.mdx new file mode 100644 index 000000000..78555cd25 --- /dev/null +++ b/units/vi/unit3/agentic-rag/agent.mdx @@ -0,0 +1,498 @@ +# Tạo Tác Nhân Gala Của Bạn + +Giờ đây khi đã xây dựng xong tất cả thành phần cần thiết cho Alfred, đã đến lúc kết hợp mọi thứ thành một tác nhân hoàn chỉnh có thể giúp tổ chức gala hoành tráng của chúng ta. + +## Lắp Ráp Alfred: Tác Nhân Hoàn Chỉnh + +Thay vì triển khai lại tất cả công cụ đã tạo ở các phần trước, ta sẽ nhập chúng từ các module tương ứng đã lưu trong file `tools.py` và `retriever.py`. + + +Nếu bạn chưa triển khai các công cụ này, hãy quay lại phần công cụtruy xuất thông tin để triển khai chúng, sau đó thêm vào file tools.pyretriever.py. + + +Hãy nhập các thư viện và công cụ cần thiết từ các phần trước: + + + + +```python +# Nhập các thư viện cần thiết +import random +from smolagents import CodeAgent, InferenceClientModel + +# Nhập các công cụ tùy chỉnh từ module +from tools import DuckDuckGoSearchTool, WeatherInfoTool, HubStatsTool +from retriever import load_guest_dataset +``` + +Giờ hãy kết hợp tất cả công cụ này thành một tác nhân duy nhất: + +```python +# Khởi tạo model Hugging Face +model = InferenceClientModel() + +# Khởi tạo công cụ tìm kiếm web +search_tool = DuckDuckGoSearchTool() + +# Khởi tạo công cụ thời tiết +weather_info_tool = WeatherInfoTool() + +# Khởi tạo công cụ thống kê Hub +hub_stats_tool = HubStatsTool() + +# Tải tập dữ liệu khách mời và khởi tạo công cụ thông tin khách +guest_info_tool = load_guest_dataset() + +# Tạo Alfred với tất cả công cụ +alfred = CodeAgent( + tools=[guest_info_tool, weather_info_tool, hub_stats_tool, search_tool], + model=model, + add_base_tools=True, # Thêm các công cụ cơ bản bổ sung + planning_interval=3 # Bật tính năng lập kế hoạch mỗi 3 bước +) +``` + + + + +```python +# Nhập các thư viện cần thiết +from llama_index.core.agent.workflow import AgentWorkflow +from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI + +from tools import search_tool, weather_info_tool, hub_stats_tool +from retriever import guest_info_tool +``` + +Giờ hãy kết hợp tất cả công cụ này thành một tác nhân duy nhất: + +```python +# Khởi tạo model Hugging Face +llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct") + +# Tạo Alfred với tất cả công cụ +alfred = AgentWorkflow.from_tools_or_functions( + [guest_info_tool, search_tool, weather_info_tool, hub_stats_tool], + llm=llm, +) +``` + + + + +```python +from typing import TypedDict, Annotated +from langgraph.graph.message import add_messages +from langchain_core.messages import AnyMessage, HumanMessage, AIMessage +from langgraph.prebuilt import ToolNode +from langgraph.graph import START, StateGraph +from langgraph.prebuilt import tools_condition +from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace + +from tools import DuckDuckGoSearchRun, weather_info_tool, hub_stats_tool +from retriever import guest_info_tool +``` + +Giờ hãy kết hợp tất cả công cụ này thành một tác nhân duy nhất: + +```python +# Khởi tạo công cụ tìm kiếm web +search_tool = DuckDuckGoSearchRun() + +# Tạo giao diện chat, bao gồm các công cụ +llm = HuggingFaceEndpoint( + repo_id="Qwen/Qwen2.5-Coder-32B-Instruct", + huggingfacehub_api_token=HUGGINGFACEHUB_API_TOKEN, +) + +chat = ChatHuggingFace(llm=llm, verbose=True) +tools = [guest_info_tool, search_tool, weather_info_tool, hub_stats_tool] +chat_with_tools = chat.bind_tools(tools) + +# Tạo AgentState và đồ thị tác nhân +class AgentState(TypedDict): + messages: Annotated[list[AnyMessage], add_messages] + +def assistant(state: AgentState): + return { + "messages": [chat_with_tools.invoke(state["messages"])], + } + +## Đồ thị +builder = StateGraph(AgentState) + +# Định nghĩa nút: thực hiện công việc +builder.add_node("assistant", assistant) +builder.add_node("tools", ToolNode(tools)) + +# Định nghĩa cạnh: xác định luồng điều khiển +builder.add_edge(START, "assistant") +builder.add_conditional_edges( + "assistant", + # Nếu tin nhắn mới nhất yêu cầu công cụ, chuyển đến tools + # Ngược lại, trả lời trực tiếp + tools_condition, +) +builder.add_edge("tools", "assistant") +alfred = builder.compile() +``` + + + +Tác nhân của bạn đã sẵn sàng sử dụng! + +## Sử Dụng Alfred: Ví Dụ End-to-End + +Giờ khi Alfred đã được trang bị đầy đủ các công cụ cần thiết, hãy xem cách anh ấy có thể giúp giải quyết các nhiệm vụ khác nhau trong gala. + +### Ví Dụ 1: Tìm Thông Tin Khách Mời + +Hãy xem Alfred có thể giúp ta với thông tin khách mời như thế nào. + + + + +```python +query = "Tell me about 'Lady Ada Lovelace'" +response = alfred.run(query) + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Based on the information I retrieved, Lady Ada Lovelace is an esteemed mathematician and friend. She is renowned for her pioneering work in mathematics and computing, often celebrated as the first computer programmer due to her work on Charles Babbage's Analytical Engine. Her email address is ada.lovelace@example.com. +``` + + + + +```python +query = "Tell me about Lady Ada Lovelace. What's her background?" +response = await alfred.run(query) + +print("🎩 Alfred's Response:") +print(response.response.blocks[0].text) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Lady Ada Lovelace was an English mathematician and writer, best known for her work on Charles Babbage's Analytical Engine. She was the first to recognize that the machine had applications beyond pure calculation. +``` + + + + +```python +response = alfred.invoke({"messages": "Tell me about 'Lady Ada Lovelace'"}) + +print("🎩 Alfred's Response:") +print(response['messages'][-1].content) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Ada Lovelace, also known as Augusta Ada King, Countess of Lovelace, was an English mathematician and writer. Born on December 10, 1815, and passing away on November 27, 1852, she is renowned for her work on Charles Babbage's Analytical Engine, a proposed mechanical general-purpose computer. Ada Lovelace is celebrated as one of the first computer programmers because she created a program for the Analytical Engine in 1843. She recognized that the machine could be used for more than mere calculation, envisioning its potential in a way that few did at the time. Her contributions to the field of computer science laid the groundwork for future developments. A day in October, designated as Ada Lovelace Day, honors women's contributions to science and technology, inspired by Lovelace's pioneering work. +``` + + + + + +### Ví dụ 2: Kiểm tra thời tiết cho màn pháo hoa + +Chúng ta xem Alfred có thể giúp gì về thời tiết. + + + + +```python +query = "What's the weather like in Paris tonight? Will it be suitable for our fireworks display?" +response = alfred.run(query) + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi (sẽ thay đổi do tính ngẫu nhiên): +``` +🎩 Alfred's Response: +I've checked the weather in Paris for you. Currently, it's clear with a temperature of 25°C. These conditions are perfect for the fireworks display tonight. The clear skies will provide excellent visibility for the spectacular show, and the comfortable temperature will ensure the guests can enjoy the outdoor event without discomfort. +``` + + + + +```python +query = "What's the weather like in Paris tonight? Will it be suitable for our fireworks display?" +response = await alfred.run(query) + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Thời tiết ở Paris tối nay có mưa với nhiệt độ 15°C. Với trời mưa, có thể không thích hợp cho màn pháo hoa. +``` + + + + +```python +response = alfred.invoke({"messages": "What's the weather like in Paris tonight? Will it be suitable for our fireworks display?"}) + +print("🎩 Alfred's Response:") +print(response['messages'][-1].content) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +The weather in Paris tonight is rainy with a temperature of 15°C. Given the rain, it may not be suitable for a fireworks display. +``` + + + +### Ví dụ 3: Gây ấn tượng với các nhà nghiên cứu AI + +Chúng ta xem Alfred có thể giúp gì để gây ấn tượng với các nhà nghiên cứu AI. + + + + +```python +query = "One of our guests is from Qwen. What can you tell me about their most popular model?" +response = alfred.run(query) + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +The most popular Qwen model is Qwen/Qwen2.5-VL-7B-Instruct with 3,313,345 downloads. +``` + + + +```python +query = "One of our guests is from Google. What can you tell me about their most popular model?" +response = await alfred.run(query) + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +The most popular model by Google on the Hugging Face Hub is google/electra-base-discriminator, with 28,546,752 downloads. +``` + + + + +```python +response = alfred.invoke({"messages": "One of our guests is from Qwen. What can you tell me about their most popular model?"}) + +print("🎩 Alfred's Response:") +print(response['messages'][-1].content) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +The most downloaded model by Qwen is Qwen/Qwen2.5-VL-7B-Instruct with 3,313,345 downloads. +``` + + + +### Ví dụ 4: Kết hợp nhiều công cụ + +Chúng ta xem Alfred có thể giúp gì để chuẩn bị cho cuộc trò chuyện với Tiến sĩ Nikola Tesla. + + + + +```python +query = "I need to speak with Dr. Nikola Tesla about recent advancements in wireless energy. Can you help me prepare for this conversation?" +response = alfred.run(query) + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +I've gathered information to help you prepare for your conversation with Dr. Nikola Tesla. + +Guest Information: +Name: Dr. Nikola Tesla +Relation: old friend from university days +Description: Dr. Nikola Tesla is an old friend from your university days. He's recently patented a new wireless energy transmission system and would be delighted to discuss it with you. Just remember he's passionate about pigeons, so that might make for good small talk. +Email: nikola.tesla@gmail.com + +Recent Advancements in Wireless Energy: +Based on my web search, here are some recent developments in wireless energy transmission: +1. Researchers have made progress in long-range wireless power transmission using focused electromagnetic waves +2. Several companies are developing resonant inductive coupling technologies for consumer electronics +3. There are new applications in electric vehicle charging without physical connections + +Conversation Starters: +1. "I'd love to hear about your new patent on wireless energy transmission. How does it compare to your original concepts from our university days?" +2. "Have you seen the recent developments in resonant inductive coupling for consumer electronics? What do you think of their approach?" +3. "How are your pigeons doing? I remember your fascination with them." + +This should give you plenty to discuss with Dr. Tesla while demonstrating your knowledge of his interests and recent developments in his field. +``` + + + + +```python +query = "I need to speak with Dr. Nikola Tesla about recent advancements in wireless energy. Can you help me prepare for this conversation?" +response = await alfred.run(query) + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Here are some recent advancements in wireless energy that you might find useful for your conversation with Dr. Nikola Tesla: + +1. **Advancements and Challenges in Wireless Power Transfer**: This article discusses the evolution of wireless power transfer (WPT) from conventional wired methods to modern applications, including solar space power stations. It highlights the initial focus on microwave technology and the current demand for WPT due to the rise of electric devices. + +2. **Recent Advances in Wireless Energy Transfer Technologies for Body-Interfaced Electronics**: This article explores wireless energy transfer (WET) as a solution for powering body-interfaced electronics without the need for batteries or lead wires. It discusses the advantages and potential applications of WET in this context. + +3. **Wireless Power Transfer and Energy Harvesting: Current Status and Future Trends**: This article provides an overview of recent advances in wireless power supply methods, including energy harvesting and wireless power transfer. It presents several promising applications and discusses future trends in the field. + +4. **Wireless Power Transfer: Applications, Challenges, Barriers, and the +``` + + + + +```python +response = alfred.invoke({"messages":"I need to speak with 'Dr. Nikola Tesla' about recent advancements in wireless energy. Can you help me prepare for this conversation?"}) + +print("🎩 Alfred's Response:") +print(response['messages'][-1].content) +``` + +Kết quả mong đợi: + +``` +Based on the provided information, here are key points to prepare for the conversation with 'Dr. Nikola Tesla' about recent advancements in wireless energy:\n1. **Wireless Power Transmission (WPT):** Discuss how WPT revolutionizes energy transfer by eliminating the need for cords and leveraging mechanisms like inductive and resonant coupling.\n2. **Advancements in Wireless Charging:** Highlight improvements in efficiency, faster charging speeds, and the rise of Qi/Qi2 certified wireless charging solutions.\n3. **5G-Advanced Innovations and NearLink Wireless Protocol:** Mention these as developments that enhance speed, security, and efficiency in wireless networks, which can support advanced wireless energy technologies.\n4. **AI and ML at the Edge:** Talk about how AI and machine learning will rely on wireless networks to bring intelligence to the edge, enhancing automation and intelligence in smart homes and buildings.\n5. **Matter, Thread, and Security Advancements:** Discuss these as key innovations that drive connectivity, efficiency, and security in IoT devices and systems.\n6. **Breakthroughs in Wireless Charging Technology:** Include any recent breakthroughs or studies, such as the one from Incheon National University, to substantiate the advancements in wireless charging. +``` + + + +## Tính năng nâng cao: Bộ nhớ hội thoại + +Để Alfred hữu ích hơn trong buổi tiệc, chúng ta có thể bật tính năng bộ nhớ hội thoại để anh ấy nhớ lại các tương tác trước đó: + + + + +```python +# Create Alfred with conversation memory +alfred_with_memory = CodeAgent( + tools=[guest_info_tool, weather_info_tool, hub_stats_tool, search_tool], + model=model, + add_base_tools=True, + planning_interval=3 +) + +# First interaction +response1 = alfred_with_memory.run("Tell me about Lady Ada Lovelace.") +print("🎩 Alfred's First Response:") +print(response1) + +# Second interaction (referencing the first) +response2 = alfred_with_memory.run("What projects is she currently working on?", reset=False) +print("🎩 Alfred's Second Response:") +print(response2) +``` + + + + +```python +from llama_index.core.workflow import Context + +alfred = AgentWorkflow.from_tools_or_functions( + [guest_info_tool, search_tool, weather_info_tool, hub_stats_tool], + llm=llm +) + +# Remembering state +ctx = Context(alfred) + +# First interaction +response1 = await alfred.run("Tell me about Lady Ada Lovelace.", ctx=ctx) +print("🎩 Alfred's First Response:") +print(response1) + +# Second interaction (referencing the first) +response2 = await alfred.run("What projects is she currently working on?", ctx=ctx) +print("🎩 Alfred's Second Response:") +print(response2) +``` + + + + +```python +# First interaction +response = alfred.invoke({"messages": [HumanMessage(content="Tell me about 'Lady Ada Lovelace'. What's her background and how is she related to me?")]}) + + +print("🎩 Alfred's Response:") +print(response['messages'][-1].content) +print() + +# Second interaction (referencing the first) +response = alfred.invoke({"messages": response["messages"] + [HumanMessage(content="What projects is she currently working on?")]}) + +print("🎩 Alfred's Response:") +print(response['messages'][-1].content) +``` + + + + + +Lưu ý rằng không có phương pháp agent nào trong ba phương pháp này kết hợp trực tiếp bộ nhớ với agent. Có lý do cụ thể nào cho lựa chọn thiết kế này không 🧐? +* smolagents: Bộ nhớ không được lưu giữ qua các lần chạy thực thi khác nhau, bạn phải chỉ định rõ ràng bằng cách sử dụng `reset=False`. +* LlamaIndex: Yêu cầu thêm rõ ràng một đối tượng ngữ cảnh để quản lý bộ nhớ trong một lần chạy. +* LangGraph: Cung cấp các tùy chọn để truy xuất các tin nhắn trước đó hoặc sử dụng thành phần [MemorySaver](https://langchain-ai.github.io/langgraph/tutorials/introduction/#part-3-adding-memory-to-the-chatbot) chuyên dụng. + +## Kết luận + +Chúc mừng! Bạn đã xây dựng thành công Alfred, một agent tinh vi được trang bị nhiều công cụ để giúp tổ chức buổi tiệc lớn nhất thế kỷ. Alfred giờ đây có thể: + +1. Truy xuất thông tin chi tiết về khách mời +2. Kiểm tra điều kiện thời tiết để lên kế hoạch cho các hoạt động ngoài trời +3. Cung cấp thông tin chi tiết về những người xây dựng AI có ảnh hưởng và các model của họ +4. Tìm kiếm trên web để có thông tin mới nhất +5. Duy trì ngữ cảnh hội thoại với bộ nhớ \ No newline at end of file diff --git a/units/vi/unit3/agentic-rag/agentic-rag.mdx b/units/vi/unit3/agentic-rag/agentic-rag.mdx new file mode 100644 index 000000000..3f5eb11e0 --- /dev/null +++ b/units/vi/unit3/agentic-rag/agentic-rag.mdx @@ -0,0 +1,27 @@ +# Agent tìm kiếm và tạo câu trả lời mang tính tác nhân (Agentic RAG) + +Trong Chương này, chúng ta sẽ cùng tìm hiểu cách sử dụng Agentic RAG để giúp Alfred chuẩn bị cho buổi tiệc gala tuyệt vời. + +Chúng mình biết các bạn đã được học về RAG và agentic RAG ở Chương trước, vì vậy hãy thoải mái bỏ qua phần này nếu đã nắm vững các khái niệm. + +LLM được huấn luyện trên kho dữ liệu khổng lồ để học kiến thức tổng quát. +Tuy nhiên, kiến thức thế giới trong LLM có thể không phải lúc nào cũng cập nhật và phù hợp. +**RAG giải quyết vấn đề này bằng cách tìm kiếm và trích xuất thông tin liên quan từ dữ liệu của bạn rồi chuyển cho LLM xử lý.** + +![RAG](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/rag.png) + +Giờ hãy xem cách Alfred hoạt động: + +1. Chúng ta yêu cầu Alfred hỗ trợ lên kế hoạch tổ chức gala +2. Alfred cần tìm kiếm thông tin thời tiết và tin tức mới nhất +3. Alfred cần sắp xếp và tìm kiếm thông tin khách mời + +Giống như Alfred cần tìm kiếm thông tin trong gia đình bạn để hỗ trợ, bất kỳ Agent nào cũng cần cách hiểu và tìm kiếm dữ liệu liên quan. +**Agentic RAG là phương pháp mạnh mẽ để sử dụng các Agent trả lời câu hỏi về dữ liệu của bạn.** Ta có thể cung cấp nhiều Tools khác nhau để Alfred trả lời câu hỏi. +Tuy nhiên, thay vì tự động trả lời dựa trên tài liệu, Alfred có thể quyết định sử dụng bất kỳ công cụ hay quy trình nào khác. + +![Agentic RAG](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/agentic-rag.png) + +**Hãy cùng bắt đầu xây dựng workflow agentic RAG!** + +Đầu tiên, ta sẽ tạo một công cụ RAG để lấy thông tin cập nhật về khách mời. Tiếp theo, ta phát triển các công cụ tìm kiếm web, cập nhật thời tiết và thống kê tải mô hình từ Hugging Face Hub. Cuối cùng, ta sẽ tích hợp mọi thứ để tạo nên Agentic RAG Agent hoàn chỉnh! \ No newline at end of file diff --git a/units/vi/unit3/agentic-rag/conclusion.mdx b/units/vi/unit3/agentic-rag/conclusion.mdx new file mode 100644 index 000000000..02f8a0406 --- /dev/null +++ b/units/vi/unit3/agentic-rag/conclusion.mdx @@ -0,0 +1,20 @@ +# Kết luận + +Trong Chương này, chúng ta đã học cách tạo hệ thống agentic RAG để giúp Alfred - agent thân thiện của chúng ta - chuẩn bị và quản lý một buổi tiệc xa hoa. + +Sự kết hợp giữa RAG và khả năng agent đã chứng minh sức mạnh của các trợ lý AI khi chúng có: +- Truy cập vào kiến thức có cấu trúc (thông tin khách mời) +- Khả năng truy xuất thông tin thời gian thực (tìm kiếm web) +- Công cụ chuyên biệt cho lĩnh vực (thông tin thời tiết, Hub stats) +- Trí nhớ về các tương tác trước đó + +Với những khả năng này, Alfred giờ đây đã được trang bị tốt để trở thành chủ nhà hoàn hảo, có thể trả lời các câu hỏi về khách mời, cung cấp thông tin cập nhật và đảm bảo buổi tiệc diễn ra suôn sẻ - thậm chí quản lý thời điểm hoàn hảo cho màn pháo hoa! + + +Giờ khi bạn đã xây dựng xong một agent hoàn chỉnh, hãy thử khám phá: +- Tạo thêm các công cụ chuyên biệt cho trường hợp sử dụng của bạn +- Xây dựng hệ thống RAG phức tạp hơn với embeddings +- Phát triển hệ thống đa tác nhân có khả năng hợp tác +- Triển khai agent dưới dạng dịch vụ cho người khác sử dụng + + \ No newline at end of file diff --git a/units/vi/unit3/agentic-rag/introduction.mdx b/units/vi/unit3/agentic-rag/introduction.mdx new file mode 100644 index 000000000..ac2cfa534 --- /dev/null +++ b/units/vi/unit3/agentic-rag/introduction.mdx @@ -0,0 +1,39 @@ +# Giới thiệu Use Case cho Agentic RAG + +![Agentic RAG banner](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit3/agentic-rag/thumbnail.jpg) + +Trong Chương này, chúng ta sẽ giúp Alfred - Agent thân thiện đang tổ chức buổi tiệc - bằng cách sử dụng Agentic RAG để tạo công cụ trả lời các câu hỏi về khách mời. + + +Đây là use case 'thực tế' cho Agentic RAG mà bạn có thể áp dụng trong dự án/công việc của mình. Nếu muốn khám phá sâu hơn, hãy thử áp dụng vào use case riêng và chia sẻ trên Discord nhé! + + +Bạn có thể chọn bất kỳ framework nào đã đề cập trong khóa học cho use case này. Chúng mình cung cấp code mẫu cho từng framework trong các tab riêng. + +## Một Buổi Tiệc Đáng Nhớ + +Giờ là lúc bắt tay vào use case thực tế. Hãy dựng sân khấu nào! + +**Bạn quyết định tổ chức bữa tiệc xa hoa nhất thế kỷ** với yến tiệc thịnh soạn, vũ công quyến rũ, DJ nổi tiếng, thức uống hảo hạng, màn pháo hoa ngoạn mục và nhiều hơn thế nữa. + +Alfred - Agent thân thiện của chúng ta - đang chuẩn bị đảm nhiệm mọi nhu cầu của bạn cho bữa tiệc này, và **Alfred sẽ tự mình quản lý tất cả**. Để làm được điều đó, cậu ấy cần truy cập mọi thông tin về bữa tiệc: thực đơn, danh sách khách mời, lịch trình, dự báo thời tiết và nhiều thứ khác! + +Không chỉ vậy, Alfred còn phải đảm bảo bữa tiệc thành công nên **cần có khả năng trả lời mọi câu hỏi về sự kiện trong suốt buổi tiệc**, đồng thời xử lý các tình huống bất ngờ phát sinh. + +Alfred không thể làm điều này một mình, nên chúng ta cần trang bị cho cậu ấy mọi thông tin và công cụ cần thiết. + +Trước hết, hãy đưa ra danh sách yêu cầu cứng cho buổi tiệc. + +## Yêu Cầu Cho Buổi Tiệc + +Một người có học thức đúng chuẩn thời **Phục Hưng** cần hội tụ ba đặc điểm chính: +- Am hiểu sâu sắc về **thể thao, văn hóa và khoa học**. Vì vậy, chúng ta cần gây ấn tượng với khách mời bằng kiến thức uyên thâm và mang đến cho họ một buổi tiệc thực sự khó quên. +- Tránh các **chủ đề nhạy cảm như chính trị và tôn giáo** để tránh xung đột. Đây phải là một bữa tiệc vui vẻ không tranh cãi về niềm tin hay lý tưởng. + +Theo nghi thức xã giao, **một chủ nhà tốt cần nắm rõ thông tin cá nhân của khách mời** như sở thích và thành tựu. Họ cũng cần biết cách chia sẻ những câu chuyện thú vị về các vị khách với nhau. + +Cuối cùng, chúng ta cần **cập nhật kiến thức chung về thời tiết** liên tục để chọn thời điểm hoàn hảo phóng pháo hoa và kết thúc buổi tiệc thật ngoạn mục! 🎆 + +Như bạn thấy, Alfred cần rất nhiều thông tin để tổ chức thành công. May mắn thay, chúng ta có thể giúp cậu ấy chuẩn bị qua **khóa học Retrieval Augmented Generation (RAG)!** + +Hãy bắt đầu bằng cách tạo các Tools cần thiết cho Alfred nào! \ No newline at end of file diff --git a/units/vi/unit3/agentic-rag/invitees.mdx b/units/vi/unit3/agentic-rag/invitees.mdx new file mode 100644 index 000000000..5346082f2 --- /dev/null +++ b/units/vi/unit3/agentic-rag/invitees.mdx @@ -0,0 +1,396 @@ +# Tạo công cụ RAG cho các câu chuyện về khách mời + +Alfred, trợ lý đáng tin cậy của bạn, đang chuẩn bị cho buổi tiệc xa hoa nhất thế kỷ. Để sự kiện diễn ra suôn sẻ, Alfred cần truy cập nhanh thông tin cập nhật về từng vị khách. Hãy giúp Alfred bằng cách tạo một công cụ Retrieval-Augmented Generation (RAG) tùy chỉnh, sử dụng tập dữ liệu riêng của chúng ta. + +## Tại sao dùng RAG cho tiệc? + +Hãy tưởng tượng Alfred đang giao lưu giữa các vị khách, cần nhớ lại chi tiết cụ thể về từng người trong nháy mắt. Một LLM truyền thống có thể gặp khó khăn vì: + +1. Danh sách khách cụ thể cho sự kiện của bạn và không có trong dữ liệu huấn luyện của model +2. Thông tin khách có thể thay đổi hoặc được cập nhật thường xuyên +3. Alfred cần truy xuất chi tiết chính xác như địa chỉ email + +Đây là lúc Retrieval Augmented Generation (RAG) tỏa sáng! Bằng cách kết hợp hệ thống truy xuất với LLM, Alfred có thể truy cập thông tin chính xác, cập nhật về khách của bạn theo yêu cầu. + + + +Bạn có thể chọn bất kỳ framework nào được đề cập trong khóa học cho trường hợp sử dụng này. Chọn tùy chọn ưa thích từ các tab mã. + + + +## Thiết lập ứng dụng + +Trong chương này, chúng ta sẽ phát triển agent trong một HF Space, như một dự án Python có cấu trúc. Cách tiếp cận này giúp chúng ta duy trì mã sạch, mô-đun hóa bằng cách tổ chức các chức năng khác nhau vào các tệp riêng biệt. Đồng thời, điều này tạo ra trường hợp sử dụng thực tế hơn khi bạn triển khai ứng dụng cho mục đích công cộng. + +### Cấu trúc dự án + +- **`tools.py`** – Cung cấp các công cụ hỗ trợ cho agent. +- **`retriever.py`** – Triển khai các hàm truy xuất để hỗ trợ truy cập kiến thức. +- **`app.py`** – Tích hợp tất cả thành phần thành một agent hoạt động đầy đủ, chúng ta sẽ hoàn thiện ở phần cuối chương này. + +Để tham khảo thực hành, hãy xem [Space này trên HF](https://huggingface.co/spaces/agents-course/Unit_3_Agentic_RAG), nơi Agentic RAG được phát triển trong chương này đang hoạt động. Hãy thoải mái sao chép và thử nghiệm! + +Bạn có thể kiểm tra trực tiếp agent bên dưới: + + + +## Tổng quan tập dữ liệu + +Tập dữ liệu [`agents-course/unit3-invitees`](https://huggingface.co/datasets/agents-course/unit3-invitees/) của chúng ta chứa các trường sau cho mỗi khách mời: + +- **Name**: Tên đầy đủ của khách +- **Relation**: Mối quan hệ của khách với chủ nhà +- **Description**: Tiểu sử ngắn hoặc thông tin thú vị về khách +- **Email Address**: Thông tin liên hệ để gửi lời mời hoặc theo dõi + +Dưới đây là bản xem trước tập dữ liệu: + + + +Trong kịch bản thực tế, tập dữ liệu này có thể mở rộng để bao gồm sở thích ăn uống, món quà quan tâm, chủ đề trò chuyện cần tránh và các chi tiết hữu ích khác cho chủ nhà. + + +## Xây dựng công cụ sổ khách + +Chúng ta sẽ tạo một công cụ tùy chỉnh để Alfred có thể sử dụng truy xuất nhanh thông tin khách trong buổi tiệc. Hãy chia nhỏ thành ba bước quản lý được: + +1. Tải và chuẩn bị tập dữ liệu +2. Tạo công cụ truy xuất +3. Tích hợp công cụ với Alfred + +Bắt đầu với việc tải và chuẩn bị tập dữ liệu! + +### Bước 1: Tải và chuẩn bị tập dữ liệu + +Đầu tiên, ta cần chuyển đổi dữ liệu khách thô sang định dạng tối ưu cho truy xuất. + + + + +Ta sẽ sử dụng thư viện `datasets` của Hugging Face để tải tập dữ liệu và chuyển đổi thành danh sách đối tượng `Document` từ mô-đun `langchain.docstore.document`. + +```python +import datasets +from langchain.docstore.document import Document + +# Tải tập dữ liệu +guest_dataset = datasets.load_dataset("agents-course/unit3-invitees", split="train") + +# Chuyển đổi mục dữ liệu thành đối tượng Document +docs = [ + Document( + page_content="\n".join([ + f"Name: {guest['name']}", + f"Relation: {guest['relation']}", + f"Description: {guest['description']}", + f"Email: {guest['email']}" + ]), + metadata={"name": guest["name"]} + ) + for guest in guest_dataset +] + +``` + + + + +Ta sẽ sử dụng thư viện `datasets` của Hugging Face để tải tập dữ liệu và chuyển đổi thành danh sách đối tượng `Document` từ mô-đun `llama_index.core.schema`. + +```python +import datasets +from llama_index.core.schema import Document + +# Tải tập dữ liệu +guest_dataset = datasets.load_dataset("agents-course/unit3-invitees", split="train") + +# Chuyển đổi mục dữ liệu thành đối tượng Document +docs = [ + Document( + text="\n".join([ + f"Name: {guest_dataset['name'][i]}", + f"Relation: {guest_dataset['relation'][i]}", + f"Description: {guest_dataset['description'][i]}", + f"Email: {guest_dataset['email'][i]}" + ]), + metadata={"name": guest_dataset['name'][i]} + ) + for i in range(len(guest_dataset)) +] +``` + + + + +Ta sẽ sử dụng thư viện `datasets` của Hugging Face để tải tập dữ liệu và chuyển đổi thành danh sách đối tượng `Document` từ mô-đun `langchain.docstore.document`. + +```python +import datasets +from langchain.docstore.document import Document + +# Tải tập dữ liệu +guest_dataset = datasets.load_dataset("agents-course/unit3-invitees", split="train") + +# Chuyển đổi mục dữ liệu thành đối tượng Document +docs = [ + Document( + page_content="\n".join([ + f"Name: {guest['name']}", + f"Relation: {guest['relation']}", + f"Description: {guest['description']}", + f"Email: {guest['email']}" + ]), + metadata={"name": guest["name"]} + ) + for guest in guest_dataset +] +``` + + + + +Trong đoạn code trên, ta: +- Tải tập dữ liệu +- Chuyển đổi mỗi mục khách thành đối tượng `Document` với nội dung được định dạng +- Lưu trữ các đối tượng `Document` trong danh sách + +Điều này có nghĩa ta đã có sẵn tất cả dữ liệu để bắt đầu cấu hình truy xuất. + +### Bước 2: Tạo công cụ truy xuất + +Giờ hãy tạo công cụ tùy chỉnh để Alfred tìm kiếm thông tin khách. + + + + +Ta sẽ sử dụng `BM25Retriever` từ mô-đun `langchain_community.retrievers` để tạo công cụ truy xuất. + + + BM25Retriever là điểm khởi đầu tốt cho truy xuất, nhưng để tìm kiếm ngữ nghĩa nâng cao, bạn có thể cân nhắc sử dụng bộ truy xuất dựa trên embedding như từ sentence-transformers. + + + +```python +from smolagents import Tool +from langchain_community.retrievers import BM25Retriever + +class GuestInfoRetrieverTool(Tool): + name = "guest_info_retriever" + description = "Retrieves detailed information about gala guests based on their name or relation." + inputs = { + "query": { + "type": "string", + "description": "The name or relation of the guest you want information about." + } + } + output_type = "string" + + def __init__(self, docs): + self.is_initialized = False + self.retriever = BM25Retriever.from_documents(docs) + + def forward(self, query: str): + results = self.retriever.get_relevant_documents(query) + if results: + return "\n\n".join([doc.page_content for doc in results[:3]]) + else: + return "No matching guest information found." + +# Initialize the tool +guest_info_tool = GuestInfoRetrieverTool(docs) +``` + +Hãy cùng tìm hiểu công cụ (tool) này từng bước: +- `name` và `description` giúp Agent hiểu khi nào và cách sử dụng công cụ này +- `inputs` định nghĩa các tham số mà công cụ mong đợi (trong trường hợp này là một truy vấn tìm kiếm) +- Chúng ta đang sử dụng `BM25Retriever`, một thuật toán truy xuất văn bản mạnh mẽ mà không cần embeddings +- Phương thức `forward` xử lý truy vấn và trả về thông tin khách mời phù hợp nhất + + + +Chúng ta sẽ sử dụng `BM25Retriever` từ mô-đun `llama_index.retrievers.bm25` để tạo công cụ truy xuất. + + + BM25Retriever là điểm khởi đầu tuyệt vời cho truy xuất, nhưng để tìm kiếm ngữ nghĩa nâng cao hơn, bạn có thể cân nhắc sử dụng bộ truy xuất dựa trên embedding như từ sentence-transformers. + + +```python +from llama_index.core.tools import FunctionTool +from llama_index.retrievers.bm25 import BM25Retriever + +bm25_retriever = BM25Retriever.from_defaults(nodes=docs) + +def get_guest_info_retriever(query: str) -> str: + """Retrieves detailed information about gala guests based on their name or relation.""" + results = bm25_retriever.retrieve(query) + if results: + return "\n\n".join([doc.text for doc in results[:3]]) + else: + return "No matching guest information found." + +# Initialize the tool +guest_info_tool = FunctionTool.from_defaults(get_guest_info_retriever) +``` + +Cùng mình tìm hiểu công cụ này từng bước: +- Phần docstring giúp agent hiểu khi nào và cách sử dụng công cụ này +- Các decorator kiểu dữ liệu xác định tham số mà công cụ mong đợi (trong trường hợp này là truy vấn tìm kiếm) +- Ta đang sử dụng `BM25Retriever`, một thuật toán truy xuất văn bản mạnh mẽ không yêu cầu embedding +- Phương thức xử lý truy vấn và trả về thông tin khách liên quan nhất + + + + +Chúng ta sẽ sử dụng `BM25Retriever` từ mô-đun `langchain_community.retrievers` để tạo công cụ truy xuất. + + + BM25Retriever là điểm khởi đầu tuyệt vời cho truy xuất, nhưng để tìm kiếm ngữ nghĩa nâng cao hơn, bạn có thể cân nhắc sử dụng bộ truy xuất dựa trên embedding như từ sentence-transformers. + + +```python +from langchain_community.retrievers import BM25Retriever +from langchain.tools import Tool + +bm25_retriever = BM25Retriever.from_documents(docs) + +def extract_text(query: str) -> str: + """Retrieves detailed information about gala guests based on their name or relation.""" + results = bm25_retriever.invoke(query) + if results: + return "\n\n".join([doc.page_content for doc in results[:3]]) + else: + return "No matching guest information found." + +guest_info_tool = Tool( + name="guest_info_retriever", + func=extract_text, + description="Retrieves detailed information about gala guests based on their name or relation." +) +``` + +Cùng mình tìm hiểu công cụ này từng bước: +- `name` và `description` giúp agent hiểu khi nào và cách sử dụng công cụ này +- Các decorator kiểu dữ liệu xác định tham số mà công cụ mong đợi (trong trường hợp này là truy vấn tìm kiếm) +- Ta đang sử dụng `BM25Retriever`, một thuật toán truy xuất văn bản mạnh mẽ không yêu cầu embedding +- Phương thức xử lý truy vấn và trả về thông tin khách liên quan nhất + + + + +### Bước 3: Tích hợp Công cụ với Alfred + +Cuối cùng, hãy kết hợp mọi thứ bằng cách tạo agent của chúng ta và trang bị cho nó công cụ tùy chỉnh: + + + + +```python +from smolagents import CodeAgent, InferenceClientModel + +# Khởi tạo model Hugging Face +model = InferenceClientModel() + +# Tạo Alfred, agent tiệc của chúng ta, với công cụ thông tin khách +alfred = CodeAgent(tools=[guest_info_tool], model=model) + +# Truy vấn mẫu Alfred có thể nhận được trong buổi tiệc +response = alfred.run("Tell me about our guest named 'Lady Ada Lovelace'.") + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Based on the information I retrieved, Lady Ada Lovelace is an esteemed mathematician and friend. She is renowned for her pioneering work in mathematics and computing, often celebrated as the first computer programmer due to her work on Charles Babbage's Analytical Engine. Her email address is ada.lovelace@example.com. +``` + +Điều gì đang diễn ra trong bước cuối này: +- Ta khởi tạo model Hugging Face bằng lớp `InferenceClientModel` +- Ta tạo agent (Alfred) dưới dạng `CodeAgent`, có thể thực thi mã Python để giải quyết vấn đề +- Ta yêu cầu Alfred truy xuất thông tin về vị khách tên "Lady Ada Lovelace" + + + + +```python +from llama_index.core.agent.workflow import AgentWorkflow +from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI + +# Khởi tạo model Hugging Face +llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct") + +# Tạo Alfred, agent tiệc của chúng ta, với công cụ thông tin khách +alfred = AgentWorkflow.from_tools_or_functions( + [guest_info_tool], + llm=llm, +) + +# Truy vấn mẫu Alfred có thể nhận được trong buổi tiệc +response = await alfred.run("Hãy cho tôi biết về vị khách tên 'Lady Ada Lovelace'.") + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Lady Ada Lovelace is an esteemed mathematician and friend, renowned for her pioneering work in mathematics and computing. She is celebrated as the first computer programmer due to her work on Charles Babbage's Analytical Engine. Her email is ada.lovelace@example.com. +``` + +Điều gì đang diễn ra trong bước cuối này: +- Ta khởi tạo model Hugging Face bằng lớp `HuggingFaceInferenceAPI` +- Ta tạo agent (Alfred) dưới dạng `AgentWorkflow`, bao gồm công cụ vừa tạo +- Ta yêu cầu Alfred truy xuất thông tin về vị khách tên "Lady Ada Lovelace" + + + + +## Ví dụ về Tương tác + +Trong buổi dạ hội, một cuộc trò chuyện có thể diễn ra như sau: + +**Bạn:** "Alfred, ngài đang nói chuyện với đại sứ là ai vậy?" + +**Alfred:** *nhanh chóng tìm kiếm cơ sở dữ liệu khách mời* "That's Dr. Nikola Tesla, sir. He's an old friend from your university days. He's recently patented a new wireless energy transmission system and would be delighted to discuss it with you. Just remember he's passionate about pigeons, so that might make for good small talk." + + +```json +{ + "name": "Dr. Nikola Tesla", + "relation": "old friend from university days", + "description": "Dr. Nikola Tesla is an old friend from your university days. He's recently patented a new wireless energy transmission system and would be delighted to discuss it with you. Just remember he's passionate about pigeons, so that might make for good small talk.", + "email": "nikola.tesla@gmail.com" +} +``` + +## Tiến Xa Hơn Nữa + +Giờ đây khi Alfred đã có thể truy xuất thông tin khách mời, hãy cân nhắc cách bạn có thể nâng cấp hệ thống này: + +1. **Cải thiện retriever** để sử dụng thuật toán tinh vi hơn như [sentence-transformers](https://www.sbert.net/) +2. **Triển khai bộ nhớ hội thoại** để Alfred nhớ các tương tác trước đó +3. **Kết hợp với tìm kiếm web** để lấy thông tin mới nhất về những vị khách chưa quen biết +4. **Tích hợp nhiều chỉ mục** để có thông tin đầy đủ hơn từ các nguồn đã xác minh + +Giờ đây Alfred đã được trang bị đầy đủ để xử lý các yêu cầu của khách một cách dễ dàng, đảm bảo buổi tiệc của bạn sẽ được nhớ đến như sự kiện tinh tế và thú vị nhất của thế kỷ! + + +Hãy thử mở rộng công cụ retriever để cũng trả về các chủ đề bắt đầu cuộc trò chuyện dựa trên sở thích hoặc nền tảng của mỗi vị khách. Bạn sẽ sửa đổi công cụ như thế nào để đạt được điều này? + +Khi hoàn thành, hãy triển khai công cụ truy xuất khách mời của bạn trong tệp retriever.py. + \ No newline at end of file diff --git a/units/vi/unit3/agentic-rag/tools.mdx b/units/vi/unit3/agentic-rag/tools.mdx new file mode 100644 index 000000000..2c59d677a --- /dev/null +++ b/units/vi/unit3/agentic-rag/tools.mdx @@ -0,0 +1,429 @@ +# Xây dựng và Tích hợp Công cụ cho Tác nhân của Bạn + +Trong phần này, chúng ta sẽ cấp cho Alfred quyền truy cập web để anh ấy có thể tìm kiếm tin tức mới nhất và cập nhật toàn cầu. +Ngoài ra, anh ấy sẽ có quyền truy cập dữ liệu thời tiết và thống kê tải xuống model từ Hugging Face hub, giúp anh ấy có thể trò chuyện về các chủ đề nóng hổi. + +## Cấp cho Tác nhân Quyền Truy cập Web + +Hãy nhớ rằng chúng ta muốn Alfred thể hiện hình ảnh một chủ nhà đa tài với kiến thức sâu rộng về thế giới. + +Để làm được điều này, ta cần đảm bảo Alfred có quyền truy cập tin tức và thông tin mới nhất về thế giới. + +Hãy bắt đầu bằng cách tạo công cụ tìm kiếm web cho Alfred! + + + + +```python +from smolagents import DuckDuckGoSearchTool + +# Khởi tạo công cụ tìm kiếm DuckDuckGo +search_tool = DuckDuckGoSearchTool() + +# Ví dụ sử dụng +results = search_tool("Who's the current President of France?") +print(results) +``` + +Kết quả mong đợi: + +``` +The current President of France in Emmanuel Macron. +``` + + + + + +```python +from llama_index.tools.duckduckgo import DuckDuckGoSearchToolSpec +from llama_index.core.tools import FunctionTool + +# Initialize the DuckDuckGo search tool +tool_spec = DuckDuckGoSearchToolSpec() + +search_tool = FunctionTool.from_defaults(tool_spec.duckduckgo_full_search) +# Example usage +response = search_tool("Who's the current President of France?") +print(response.raw_output[-1]['body']) +``` + +Kết quả mong đợi: + +``` +The President of the French Republic is the head of state of France. The current President is Emmanuel Macron since 14 May 2017 defeating Marine Le Pen in the second round of the presidential election on 7 May 2017. List of French presidents (Fifth Republic) N° Portrait Name ... +``` + + + + +```python +from langchain_community.tools import DuckDuckGoSearchRun + +search_tool = DuckDuckGoSearchRun() +results = search_tool.invoke("Who's the current President of France?") +print(results) +``` + +Kết quả mong đợi: + +``` +Emmanuel Macron (born December 21, 1977, Amiens, France) is a French banker and politician who was elected president of France in 2017... +``` + + + + +## Tạo Công cụ Tùy chỉnh để Lấy Thông tin Thời tiết cho Lịch Trình Bắn Pháo hoa + +Buổi tiệc gala hoàn hảo cần có pháo hoa trên bầu trời quang đãng, chúng ta phải đảm bảo pháo hoa không bị hủy do thời tiết xấu. + +Hãy tạo một công cụ tùy chỉnh để gọi API thời tiết bên ngoài và lấy thông tin thời tiết cho địa điểm cụ thể. + + +Để đơn giản, ta sử dụng API thời tiết ảo (dummy) cho ví dụ này. Nếu muốn dùng API thời tiết thật, bạn có thể triển khai công cụ sử dụng OpenWeatherMap API như trong Chương 1. + + + + + +```python +from smolagents import Tool +import random + +class WeatherInfoTool(Tool): + name = "weather_info" + description = "Lấy thông tin thời tiết ảo cho địa điểm chỉ định." + inputs = { + "location": { + "type": "string", + "description": "Địa điểm cần lấy thông tin thời tiết." + } + } + output_type = "string" + + def forward(self, location: str): + # Dữ liệu thời tiết ảo + weather_conditions = [ + {"condition": "Rainy", "temp_c": 15}, + {"condition": "Clear", "temp_c": 25}, + {"condition": "Windy", "temp_c": 20} + ] + # Chọn ngẫu nhiên điều kiện thời tiết + data = random.choice(weather_conditions) + return f"Weather in {location}: {data['condition']}, {data['temp_c']}°C" + +# Khởi tạo công cụ +weather_info_tool = WeatherInfoTool() +``` + + + + +```python +import random +from llama_index.core.tools import FunctionTool + +def get_weather_info(location: str) -> str: + """Lấy thông tin thời tiết ảo cho địa điểm chỉ định.""" + # Dữ liệu thời tiết ảo + weather_conditions = [ + {"condition": "Rainy", "temp_c": 15}, + {"condition": "Clear", "temp_c": 25}, + {"condition": "Windy", "temp_c": 20} + ] + # Chọn ngẫu nhiên điều kiện thời tiết + data = random.choice(weather_conditions) + return f"Weather in {location}: {data['condition']}, {data['temp_c']}°C" + +# Khởi tạo công cụ +weather_info_tool = FunctionTool.from_defaults(get_weather_info) +``` + + + + +```python +from langchain.tools import Tool +import random + +def get_weather_info(location: str) -> str: + """Lấy thông tin thời tiết ảo cho địa điểm chỉ định.""" + # Dữ liệu thời tiết ảo + weather_conditions = [ + {"condition": "Rainy", "temp_c": 15}, + {"condition": "Clear", "temp_c": 25}, + {"condition": "Windy", "temp_c": 20} + ] + # Chọn ngẫu nhiên điều kiện thời tiết + data = random.choice(weather_conditions) + return f"Weather in {location}: {data['condition']}, {data['temp_c']}°C" + +# Khởi tạo công cụ +weather_info_tool = Tool( + name="get_weather_info", + func=get_weather_info, + description="Lấy thông tin thời tiết ảo cho địa điểm chỉ định." +) +``` + + + + +## Tạo Công cụ Thống kê Hub cho Nhà Phát triển AI Có Tầm Ảnh Hưởng + +Tham dự buổi gala là những nhân vật hàng đầu trong giới phát triển AI. Alfred muốn gây ấn tượng bằng cách thảo luận về các mô hình, tập dữ liệu và Space phổ biến nhất của họ. Ta sẽ tạo công cụ lấy thống kê mô hình từ Hugging Face Hub dựa trên tên người dùng. + + + + +```python +from smolagents import Tool +from huggingface_hub import list_models + +class HubStatsTool(Tool): + name = "hub_stats" + description = "Lấy model được tải nhiều nhất từ tác giả cụ thể trên Hugging Face Hub." + inputs = { + "author": { + "type": "string", + "description": "Tên người dùng/tổ chức tác giả model cần tìm." + } + } + output_type = "string" + + def forward(self, author: str): + try: + # Liệt kê model từ tác giả chỉ định, sắp xếp theo lượt tải + models = list(list_models(author=author, sort="downloads", direction=-1, limit=1)) + + if models: + model = models[0] + return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads." + else: + return f"No models found for author {author}." + except Exception as e: + return f"Error fetching models for {author}: {str(e)}" + +# Khởi tạo công cụ +hub_stats_tool = HubStatsTool() + +# Ví dụ sử dụng +print(hub_stats_tool("facebook")) # Ví dụ: Lấy model được tải nhiều nhất của Facebook +``` + +Kết quả mong đợi: + +``` +The most downloaded model by facebook is facebook/esmfold_v1 with 12,544,550 downloads. +``` + + + + +```python +import random +from llama_index.core.tools import FunctionTool +from huggingface_hub import list_models + +def get_hub_stats(author: str) -> str: + """Lấy model được tải nhiều nhất từ tác giả cụ thể trên Hugging Face Hub.""" + try: + # Liệt kê model từ tác giả chỉ định, sắp xếp theo lượt tải + models = list(list_models(author=author, sort="downloads", direction=-1, limit=1)) + + if models: + model = models[0] + return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads." + else: + return f"No models found for author {author}." + except Exception as e: + return f"Error fetching models for {author}: {str(e)}" + +# Khởi tạo công cụ +hub_stats_tool = FunctionTool.from_defaults(get_hub_stats) + +# Ví dụ sử dụng +print(hub_stats_tool("facebook")) # Ví dụ: Lấy model được tải nhiều nhất của Facebook +``` + +Kết quả mong đợi: + +``` +The most downloaded model by facebook is facebook/esmfold_v1 with 12,544,550 downloads. +``` + + + + + +```python +from langchain.tools import Tool +from huggingface_hub import list_models + +def get_hub_stats(author: str) -> str: + """Fetches the most downloaded model from a specific author on the Hugging Face Hub.""" + try: + # List models from the specified author, sorted by downloads + models = list(list_models(author=author, sort="downloads", direction=-1, limit=1)) + + if models: + model = models[0] + return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads." + else: + return f"No models found for author {author}." + except Exception as e: + return f"Error fetching models for {author}: {str(e)}" + +# Initialize the tool +hub_stats_tool = Tool( + name="get_hub_stats", + func=get_hub_stats, + description="Fetches the most downloaded model from a specific author on the Hugging Face Hub." +) + +# Example usage +print(hub_stats_tool("facebook")) # Example: Get the most downloaded model by Facebook +``` + +Kết quả mong đợi: + +``` +The most downloaded model by facebook is facebook/esmfold_v1 with 13,109,861 downloads. +``` + + + + +Với Công cụ Thống kê Hub, giờ đây Alfred có thể gây ấn tượng với các nhà xây dựng AI có ảnh hưởng bằng cách thảo luận về các mô hình phổ biến nhất của họ. + +## Tích hợp Công cụ với Alfred + +Giờ chúng ta đã có tất cả công cụ, hãy tích hợp chúng vào tác nhân Alfred: + + + + +```python +from smolagents import CodeAgent, InferenceClientModel + +# Khởi tạo mô hình Hugging Face +model = InferenceClientModel() + +# Tạo Alfred với tất cả công cụ +alfred = CodeAgent( + tools=[search_tool, weather_info_tool, hub_stats_tool], + model=model +) + +# Truy vấn mẫu Alfred có thể nhận trong buổi tiệc +response = alfred.run("What is Facebook and what's their most popular model?") + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Facebook is a social networking website where users can connect, share information, and interact with others. The most downloaded model by Facebook on the Hugging Face Hub is ESMFold_v1. +``` + + + + +```python +from llama_index.core.agent.workflow import AgentWorkflow +from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI + +# Khởi tạo mô hình Hugging Face +llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct") +# Tạo Alfred với tất cả công cụ +alfred = AgentWorkflow.from_tools_or_functions( + [search_tool, weather_info_tool, hub_stats_tool], + llm=llm +) + +# Truy vấn mẫu Alfred có thể nhận trong buổi tiệc +response = await alfred.run("What is Facebook and what's their most popular model?") + +print("🎩 Alfred's Response:") +print(response) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Facebook is a social networking service and technology company based in Menlo Park, California. It was founded by Mark Zuckerberg and allows people to create profiles, connect with friends and family, share photos and videos, and join groups based on shared interests. The most popular model by Facebook on the Hugging Face Hub is `facebook/esmfold_v1` with 13,109,861 downloads. +``` + + + + +```python +from typing import TypedDict, Annotated +from langgraph.graph.message import add_messages +from langchain_core.messages import AnyMessage, HumanMessage, AIMessage +from langgraph.prebuilt import ToolNode +from langgraph.graph import START, StateGraph +from langgraph.prebuilt import tools_condition +from langchain_huggingface import HuggingFaceEndpoint, ChatHuggingFace + +# Tạo giao diện chat, bao gồm các công cụ +llm = HuggingFaceEndpoint( + repo_id="Qwen/Qwen2.5-Coder-32B-Instruct", + huggingfacehub_api_token=HUGGINGFACEHUB_API_TOKEN, +) + +chat = ChatHuggingFace(llm=llm, verbose=True) +tools = [search_tool, weather_info_tool, hub_stats_tool] +chat_with_tools = chat.bind_tools(tools) + +# Tạo AgentState và đồ thị Agent +class AgentState(TypedDict): + messages: Annotated[list[AnyMessage], add_messages] + +def assistant(state: AgentState): + return { + "messages": [chat_with_tools.invoke(state["messages"])], + } + +## Đồ thị +builder = StateGraph(AgentState) + +# Định nghĩa nút: thực hiện công việc +builder.add_node("assistant", assistant) +builder.add_node("tools", ToolNode(tools)) + +# Định nghĩa cạnh: xác định luồng điều khiển +builder.add_edge(START, "assistant") +builder.add_conditional_edges( + "assistant", + # Nếu tin nhắn mới nhất yêu cầu công cụ, chuyển đến tools + # Ngược lại, trả lời trực tiếp + tools_condition, +) +builder.add_edge("tools", "assistant") +alfred = builder.compile() + +messages = [HumanMessage(content="Who is Facebook and what's their most popular model?")] +response = alfred.invoke({"messages": messages}) + +print("🎩 Alfred's Response:") +print(response['messages'][-1].content) +``` + +Kết quả mong đợi: + +``` +🎩 Alfred's Response: +Facebook is a social media company known for its social networking site, Facebook, as well as other services like Instagram and WhatsApp. The most downloaded model by Facebook on the Hugging Face Hub is facebook/esmfold_v1 with 13,202,321 downloads. +``` + + + +## Kết luận + +Bằng cách tích hợp các công cụ này, Alfred giờ đã được trang bị để xử lý nhiều tác vụ đa dạng, từ tìm kiếm web đến cập nhật thời tiết và thống kê mô hình. Điều này đảm bảo anh ấy luôn là \ No newline at end of file diff --git a/units/vi/unit4/additional-readings.mdx b/units/vi/unit4/additional-readings.mdx new file mode 100644 index 000000000..55d10b687 --- /dev/null +++ b/units/vi/unit4/additional-readings.mdx @@ -0,0 +1,30 @@ +# Vậy giờ sao? Mình nên học chủ đề gì? + +Agentic AI là lĩnh vực phát triển cực kỳ nhanh, và việc hiểu các giao thức nền tảng là điều thiết yếu để xây dựng hệ thống thông minh, tự chủ. + +Hai tiêu chuẩn quan trọng bạn nên làm quen là: + +- **Model Context Protocol (MCP)** +- **Agent-to-Agent Protocol (A2A)** + +## 🔌 Model Context Protocol (MCP) + +**Model Context Protocol (MCP)** do Anthropic phát triển là một tiêu chuẩn mở giúp các mô hình AI **kết nối an toàn và liền mạch với công cụ bên ngoài, nguồn dữ liệu và ứng dụng**, giúp các agent (tác nhân) trở nên mạnh mẽ và tự chủ hơn. + +Hãy coi MCP như **bộ chuyển đổi đa năng**, giống cổng USB-C, cho phép mô hình AI cắm vào nhiều môi trường kỹ thuật số **mà không cần tích hợp tùy chỉnh cho từng hệ thống**. + +MCP đang nhanh chóng được ngành công nghiệp đón nhận, với các công ty lớn như OpenAI và Google bắt đầu áp dụng. + +📚 Tìm hiểu thêm: +- [Thông báo chính thức và tài liệu từ Anthropic](https://www.anthropic.com/news/model-context-protocol) +- [MCP trên Wikipedia](https://en.wikipedia.org/wiki/Model_Context_Protocol) +- [Blog về MCP](https://huggingface.co/blog/Kseniase/mcp) + +## 🤝 Agent-to-Agent (A2A) Protocol + +Google đã phát triển **Agent-to-Agent (A2A) protocol** như một bản bổ sung cho Model Context Protocol (MCP) của Anthropic. + +Trong khi MCP kết nối agent (tác nhân) với công cụ bên ngoài, **A2A kết nối các agent với nhau**, mở đường cho hệ thống đa tác nhân hợp tác có thể cùng giải quyết vấn đề phức tạp. + +📚 Khám phá sâu hơn về A2A: +- [Thông báo A2A từ Google](https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/) \ No newline at end of file diff --git a/units/vi/unit4/conclusion.mdx b/units/vi/unit4/conclusion.mdx new file mode 100644 index 000000000..d32fd3923 --- /dev/null +++ b/units/vi/unit4/conclusion.mdx @@ -0,0 +1,11 @@ +# Kết luận + +**Chúc mừng bạn đã hoàn thành Khóa học về Agent (tác nhân)!** + +Với sự kiên trì và cống hiến, bạn đã xây dựng nền tảng vững chắc trong thế giới AI Agents. + +Nhưng hoàn thành khóa học này **không phải điểm kết thúc hành trình** của bạn. Đây mới chỉ là khởi đầu: đừng ngần ngại khám phá phần tiếp theo nơi chúng tôi chia sẻ tài nguyên chọn lọc giúp bạn tiếp tục học hỏi, bao gồm chủ đề nâng cao như **MCPs** và hơn thế nữa. + +**Cảm ơn** bạn đã đồng hành cùng khóa học. **Chúng tôi hy vọng bạn yêu thích khóa học này như cách chúng tôi đã say mê viết nó.** + +Và đừng quên: **Tiếp tục học hỏi, luôn tuyệt vời!** 🤗 \ No newline at end of file diff --git a/units/vi/unit4/get-your-certificate.mdx b/units/vi/unit4/get-your-certificate.mdx new file mode 100644 index 000000000..1e880a1ff --- /dev/null +++ b/units/vi/unit4/get-your-certificate.mdx @@ -0,0 +1,18 @@ +# Nhận Chứng Chỉ Của Bạn 🎓 + +Nếu bạn đạt điểm **trên 30%, xin chúc mừng! 👏 Bạn đã đủ điều kiện để nhận chứng chỉ chính thức.** + +Hãy làm theo các bước sau để nhận chứng chỉ: + +1. Truy cập [trang chứng chỉ](https://huggingface.co/spaces/agents-course/Unit4-Final-Certificate). +2. **Đăng nhập** bằng tài khoản Hugging Face của bạn bằng nút được cung cấp. +3. **Nhập họ tên đầy đủ của bạn**. Đây là tên sẽ xuất hiện trên chứng chỉ. +4. Nhấp **“Get My Certificate”** để xác minh điểm số và tải chứng chỉ về. + +Chúc mừng! + +Sau khi nhận được chứng chỉ, bạn có thể: +- Thêm vào **hồ sơ LinkedIn** 🧑‍💼 +- Chia sẻ trên **X**, **Bluesky**, v.v. 🎉 + +**Đừng quên gắn thẻ [@huggingface](https://huggingface.co/huggingface). Chúng tôi sẽ rất tự hào và rất muốn cổ vũ bạn! 🤗** \ No newline at end of file diff --git a/units/vi/unit4/hands-on.mdx b/units/vi/unit4/hands-on.mdx new file mode 100644 index 000000000..b420cb374 --- /dev/null +++ b/units/vi/unit4/hands-on.mdx @@ -0,0 +1,50 @@ +# Thực hành + +Giờ bạn đã sẵn sàng đi sâu vào việc tạo tác nhân cuối cùng, hãy xem cách nộp bài để được đánh giá. + +## Tập dữ liệu + +Tập dữ liệu dùng trong bảng xếp hạng này gồm 20 câu hỏi trích từ phần **kiểm định** cấp độ 1 của GAIA. Các câu hỏi được chọn dựa trên số lượng công cụ và bước cần thiết để trả lời. + +Dựa trên diện mạo hiện tại của benchmark GAIA, chúng tôi cho rằng mục tiêu đạt 30% câu hỏi cấp độ 1 là bài kiểm tra công bằng. + +Trạng thái hiện tại của GAIA! + +## Quy trình + +Câu hỏi lớn nhất trong tâm trí bạn có lẽ là: "Làm thế nào để tôi bắt đầu nộp bài?" + +Đối với chương này, chúng tôi đã tạo ra một API cho phép bạn lấy câu hỏi và gửi câu trả lời để đánh giá. +Đây là tóm tắt các tuyến (xem [tài liệu trực tiếp](https://agents-course-unit4-scoring.hf.space/docs) để xem chi tiết): + +* **`GET /questions`**: Lấy danh sách đầy đủ các câu hỏi đánh giá đã lọc. +* **`GET /random-question`**: Lấy một câu hỏi ngẫu nhiên từ danh sách. +* **`GET /files/{task_id}`**: Tải xuống tệp cụ thể được liên kết với ID công việc đã cho. +* **`POST /submit`**: Gửi câu trả lời của agent, tính điểm và cập nhật bảng xếp hạng. + +Hàm nộp sẽ so sánh câu trả lời với đáp án cơ bản (ground truth) theo cách **TRÙNG KHỚP CHÍNH XÁC**, vì vậy hãy prompt tốt! Đội GAIA đã chia sẻ một ví dụ về prompting cho agent của bạn [tại đây](https://huggingface.co/spaces/gaia-benchmark/leaderboard) (để đơn giản hóa khóa học, hãy đảm bảo không bao gồm văn bản "CÂU TRẢ LỜI CUỐI CÙNG" trong nộp, chỉ cần cho agent trả lời với câu trả lời và không có gì khác). + +🎨 **Làm Template Của Bạn!** + +Để minh họa quy trình tương tác với API, chúng tôi đã bao gồm một [template cơ bản](https://huggingface.co/spaces/agents-course/Final_Assignment_Template) làm điểm khởi đầu. + +Vui lòng tự do -và chúng tôi **khuyến khích mạnh mẽ**- thay đổi, thêm yếu tố hoặc đảo lộn hoàn toàn. Thay đổi nó theo cách phù hợp với bạn và sáng tạo của bạn. + +Để gửi bằng template này, hãy tính toán 3 thứ cần thiết cho API: + +* **Tên người dùng (`Username`):** Tên người dùng của bạn trên Hugging Face (được lấy thông qua đăng nhập Gradio), được sử dụng để xác định gửi của bạn. +* **Liên kết đến Code (`agent_code`):** URL liên kết đến code của Space của bạn trên Hugging Face (`.../tree/main`) để kiểm tra, vì vậy hãy giữ Space của bạn công khai. +* **Câu trả lời (`answers`):** Danh sách câu trả lời (`{"task_id": ..., "submitted_answer": ...}`) được agent của bạn tạo ra cho điểm. + +Vì vậy, chúng tôi khuyến khích bạn bắt đầu bằng cách nhân bản [template này](https://huggingface.co/spaces/agents-course/Final_Assignment_Template) trên tài khoản Hugging Face của bạn. + +🏆 Xem bảng xếp hạng [tại đây](https://huggingface.co/spaces/agents-course/Students_leaderboard) + +*Lưu ý thân thiện: Bảng xếp hạng này chỉ mang tính chất giải trí! Chúng tôi biết bạn có thể gửi điểm mà không cần xác minh đầy đủ. Nếu chúng tôi thấy quá nhiều điểm cao được đăng mà không có liên kết công khai để sao lưu, chúng tôi có thể cần xem xét, điều chỉnh hoặc xóa một số mục để bảng xếp hạng hữu ích.* +Bảng xếp hạng sẽ hiển thị liên kết đến space code của bạn. Vì bảng xếp hạng này chỉ dành cho học sinh, vui lòng giữ space của bạn ở chế độ công khai nếu bạn đạt được điểm số mà bạn tự hào. + \ No newline at end of file diff --git a/units/vi/unit4/introduction.mdx b/units/vi/unit4/introduction.mdx new file mode 100644 index 000000000..bd9125f28 --- /dev/null +++ b/units/vi/unit4/introduction.mdx @@ -0,0 +1,23 @@ +# Chào mừng đến với chương cuối + +AI Agents Course thumbnail + +Chào mừng bạn đến với chương cuối của khóa học! 🎉 + +Cho đến giờ, bạn đã **xây dựng nền tảng mạnh mẽ trong AI Agents**, từ việc hiểu các thành phần của chúng đến việc tạo Agent của riêng mình. Với kiến thức này, bạn giờ đây đã sẵn sàng để **xây dựng các Agent mạnh mẽ** và theo dõi những tiến bộ mới nhất trong lĩnh vực này, đang phát triển rất nhanh. + +Chương này là về việc áp dụng những gì bạn đã học. Đây là **dự án thực hành cuối cùng** của bạn, và hoàn thành nó là điều kiện để nhận được **chứng chỉ khóa học**. + +## Thử thách là gì? + +Bạn sẽ tạo Agent của riêng mình và **đánh giá hiệu suất của nó bằng cách sử dụng một tập con của [GAIA benchmark](https://huggingface.co/spaces/gaia-benchmark/leaderboard)**. + +Để hoàn thành khóa học, Agent của bạn cần đạt điểm **30% trở lên** trên benchmark. Đạt được điểm đó, bạn sẽ nhận được **Chứng chỉ hoàn thành**, chính thức xác nhận kỹ năng của bạn. 🏅 + +Ngoài ra, hãy xem bạn đứng vị trí như thế nào so với bạn bè! Một **[Bảng xếp hạng Học sinh](https://huggingface.co/spaces/agents-course/Students_leaderboard)** được cung cấp cho bạn để gửi điểm và xem tiến trình cộng đồng. + +> ** 🚨 Cảnh báo: Chương nâng cao & Thực hành** +> +> Vui lòng lưu ý rằng chương này chuyển hướng về một tiếp cận thực tế, thực hành hơn. Thành công trong phần này sẽ yêu cầu **kiến thức lập trình nâng cao hơn** và phụ thuộc vào bạn điều hướng các tác vụ với **ít hướng dẫn rõ ràng hơn** so với các phần trước của khóa học. + +Nghe thú vị phải không? Hãy bắt đầu! 🚀 \ No newline at end of file diff --git a/units/vi/unit4/what-is-gaia.mdx b/units/vi/unit4/what-is-gaia.mdx new file mode 100644 index 000000000..6dc181852 --- /dev/null +++ b/units/vi/unit4/what-is-gaia.mdx @@ -0,0 +1,70 @@ +# GAIA là gì? + +[GAIA](https://huggingface.co/papers/2311.12983) là một **benchmark (tiêu chuẩn đánh giá) được thiết kế để đánh giá các trợ lý AI trên các nhiệm vụ thực tế** đòi hỏi sự kết hợp của các khả năng cốt lõi — như suy luận, hiểu đa phương thức, duyệt web và sử dụng công cụ thành thạo. + +Nó được giới thiệu trong bài báo _"[GAIA: A Benchmark for General AI Assistants](https://huggingface.co/papers/2311.12983)"_. + +Benchmark này bao gồm **466 câu hỏi được tuyển chọn cẩn thận**, **về mặt khái niệm đơn giản đối với con người**, nhưng **lại cực kỳ thách thức đối với các hệ thống AI hiện tại**. + +Để minh họa khoảng cách: +- **Con người**: tỷ lệ thành công ~92% +- **GPT-4 với plugins**: ~15% +- **Deep Research (OpenAI)**: 67.36% trên tập kiểm định + +GAIA nêu bật những hạn chế hiện tại của các mô hình AI và cung cấp một benchmark nghiêm ngặt để đánh giá tiến trình hướng tới các trợ lý AI thực sự đa năng. + +## 🌱 Nguyên tắc Cốt lõi của GAIA + +GAIA được thiết kế cẩn thận dựa trên các trụ cột sau: + +- 🔍 **Độ khó thực tế**: Các nhiệm vụ đòi hỏi suy luận nhiều bước, hiểu đa phương thức và tương tác với công cụ. +- 🧾 **Khả năng diễn giải của con người**: Mặc dù khó đối với AI, các nhiệm vụ vẫn đơn giản về mặt khái niệm và dễ theo dõi đối với con người. +- 🛡️ **Không thể gian lận**: Câu trả lời đúng đòi hỏi thực hiện đầy đủ nhiệm vụ, khiến việc dùng vũ lực (brute-forcing) trở nên vô hiệu. +- 🧰 **Đơn giản trong đánh giá**: Câu trả lời ngắn gọn, thực tế và rõ ràng — lý tưởng cho việc đánh giá benchmark. + +## Các Mức độ Khó + +Các nhiệm vụ của GAIA được tổ chức thành **ba cấp độ phức tạp tăng dần**, mỗi cấp độ kiểm tra các kỹ năng cụ thể: + +- **Cấp độ 1**: Yêu cầu ít hơn 5 bước và sử dụng công cụ tối thiểu. +- **Cấp độ 2**: Bao gồm suy luận phức tạp hơn và sự phối hợp giữa nhiều công cụ với 5-10 bước. +- **Cấp độ 3**: Đòi hỏi lập kế hoạch dài hạn và tích hợp nâng cao nhiều công cụ khác nhau. + +![Các cấp độ GAIA](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit4/gaia_levels.png) + +## Ví dụ về một Câu hỏi GAIA Khó + +> Trong số các loại trái cây được thể hiện trong bức tranh năm 2008 "Embroidery from Uzbekistan", những loại nào đã được phục vụ trong thực đơn bữa sáng tháng 10 năm 1949 của con tàu du lịch mà sau này được sử dụng làm đạo cụ nổi cho bộ phim "The Last Voyage"? Hãy liệt kê các mục dưới dạng danh sách phân tách bằng dấu phẩy, sắp xếp chúng theo chiều kim đồng hồ dựa trên cách bố trí trong bức tranh bắt đầu từ vị trí 12 giờ. Sử dụng dạng số nhiều của mỗi loại trái cây. + +Như bạn có thể thấy, câu hỏi này thách thức các hệ thống AI theo nhiều cách: + +- Yêu cầu **định dạng phản hồi có cấu trúc** +- Liên quan đến **suy luận đa phương thức** (ví dụ: phân tích hình ảnh) +- Đòi hỏi **truy xuất đa bước** các sự kiện phụ thuộc lẫn nhau: + - Xác định các loại trái cây trong bức tranh + - Khám phá con tàu du lịch nào đã được sử dụng trong *The Last Voyage* + - Tra cứu thực đơn bữa sáng từ tháng 10 năm 1949 của con tàu đó +- Cần **sắp xếp trình tự chính xác** và lập kế hoạch cấp cao để giải quyết theo đúng thứ tự + +Loại nhiệm vụ này làm nổi bật nơi mà các LLM độc lập thường không đáp ứng được, khiến GAIA trở thành một benchmark lý tưởng cho **các hệ thống dựa trên agent (tác nhân)** có thể suy luận, truy xuất và thực thi qua nhiều bước và phương thức. + +![Biểu đồ khả năng của GAIA](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit4/gaia_capabilities.png) + +## Đánh giá Trực tiếp (Live Evaluation) + +Để khuyến khích đánh benchmark liên tục, **GAIA cung cấp bảng xếp hạng công khai được lưu trữ trên Hugging Face**, nơi bạn có thể kiểm tra các mô hình của mình với **300 câu hỏi kiểm tra**. + +👉 Xem bảng xếp hạng tại [đây](https://huggingface.co/spaces/gaia-benchmark/leaderboard) + + + +Bạn muốn tìm hiểu sâu hơn về GAIA? + +- 📄 [Đọc toàn văn bài báo](https://huggingface.co/papers/2311.12983) +- 📄 [Bài đăng phát hành Deep Research của OpenAI](https://openai.com/index/introducing-deep-research/) +- 📄 [DeepResearch mã nguồn mở – Giải phóng các agent tìm kiếm của chúng ta](https://huggingface.co/blog/open-deep-research)