tthhanh commited on
Commit
b97ad7d
·
1 Parent(s): 2ffacfa

feat: add toctree and translation unit 2 3 4

Browse files
units/vi/unit2/clients.mdx ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Xây dựng MCP Clients
2
+
3
+ Trong phần này, chúng ta sẽ tạo các client có thể tương tác với MCP server bằng các ngôn ngữ lập trình khác nhau. Chúng ta sẽ triển khai cả client JavaScript sử dụng HuggingFace.js và client Python sử dụng smolagents.
4
+
5
+ ## Cấu hình MCP Clients
6
+
7
+ Việc triển khai hiệu quả MCP servers và clients yêu cầu cấu hình phù hợp. Đặc tả MCP vẫn đang phát triển, vì vậy các phương pháp cấu hình có thể thay đổi. Chúng ta sẽ tập trung vào các best practice hiện tại về cấu hình.
8
+
9
+ ### Cấu hình Files của MCP
10
+
11
+ Các MCP hosts sử dụng configuration files để quản lý kết nối server. Những files này xác định các servers nào có sẵn và cách kết nối đến chúng.
12
+
13
+ Các configuration files rất đơn giản, dễ hiểu và thống nhất giữa các MCP hosts chính.
14
+
15
+ #### Cấu trúc `mcp.json`
16
+
17
+ File cấu hình chuẩn cho MCP có tên `mcp.json`. Đây là cấu trúc cơ bản:
18
+
19
+ ```json
20
+ {
21
+ "servers": [
22
+ {
23
+ "name": "MCP Server",
24
+ "transport": {
25
+ "type": "sse",
26
+ "url": "http://localhost:7860/gradio_api/mcp/sse"
27
+ }
28
+ }
29
+ ]
30
+ }
31
+ ```
32
+
33
+ Trong ví dụ này, chúng ta có một server được cấu hình sử dụng SSE transport, kết nối đến Gradio server local chạy trên cổng 7860.
34
+
35
+ <Tip>
36
+
37
+ Chúng ta đã kết nối đến ứng dụng Gradio qua giao thức SSE vì giả định rằng ứng dụng gradio đang chạy trên một Server từ xa. Tuy nhiên nếu bạn muốn kết nối đến script local, `stdio` transport thay vì `sse` transport là lựa chọn tốt hơn.
38
+
39
+ </Tip>
40
+
41
+ #### Cấu hình cho HTTP+SSE Transport
42
+
43
+ Với các servers từ xa sử dụng HTTP+SSE transport, cấu hình bao gồm URL của server:
44
+
45
+ ```json
46
+ {
47
+ "servers": [
48
+ {
49
+ "name": "Remote MCP Server",
50
+ "transport": {
51
+ "type": "sse",
52
+ "url": "https://example.com/gradio_api/mcp/sse"
53
+ }
54
+ }
55
+ ]
56
+ }
57
+ ```
58
+
59
+ Cấu hình này cho phép UI client của bạn giao tiếp với Gradio MCP server sử dụng MCP protocol, giúp tích hợp liền mạch giữa frontend và dịch vụ MCP.
60
+
61
+ ## Cấu hình UI MCP Client
62
+
63
+ Khi làm việc với Gradio MCP servers, bạn có thể cấu hình UI client để kết nối đến server sử dụng MCP protocol. Cách thiết lập như sau:
64
+
65
+ ### Cấu hình cơ bản
66
+
67
+ Tạo file mới tên `config.json` với cấu hình sau:
68
+
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "mcp": {
73
+ "url": "http://localhost:7860/gradio_api/mcp/sse"
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ Cấu hình này cho phép UI client của bạn giao tiếp với Gradio MCP server sử dụng MCP protocol, giúp tích hợp liền mạch giữa frontend và dịch vụ MCP.
units/vi/unit2/gradio-client.mdx ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gradio với vai trò Máy khách MCP
2
+
3
+ Ở chương trước, chúng ta đã tìm hiểu cách tạo MCP Server bằng Gradio và kết nối đến nó bằng một MCP Client. Trong chương này, chúng ta sẽ khám phá cách sử dụng Gradio như một MCP Client để kết nối đến MCP Server.
4
+
5
+ <Tip>
6
+
7
+ Gradio phù hợp nhất để tạo UI client và MCP server, nhưng cũng có thể dùng nó như MCP Client và hiển thị dưới dạng UI.
8
+
9
+ </Tip>
10
+
11
+ Chúng ta sẽ kết nối đến MCP server đã tạo ở chương trước và dùng nó để trả lời câu hỏi.
12
+
13
+ ## MCP Client trong Gradio
14
+
15
+ Đầu tiên, cần cài đặt các thư viện `smolagents`, gradio và mcp-client nếu chưa có:
16
+
17
+ ```bash
18
+ pip install smolagents[mcp] gradio[mcp] mcp
19
+ ```
20
+
21
+ Giờ chúng ta có thể import các thư viện cần thiết và tạo giao diện Gradio đơn giản sử dụng MCP Client để kết nối đến MCP Server.
22
+
23
+ ```python
24
+ import gradio as gr
25
+
26
+ from mcp.client.stdio import StdioServerParameters
27
+ from smolagents import ToolCollection, CodeAgent
28
+ from smolagents import CodeAgent, InferenceClientModel
29
+ from smolagents.mcp_client import MCPClient
30
+ ```
31
+
32
+ Tiếp theo, kết nối đến MCP Server và lấy các công cụ có thể dùng để trả lời câu hỏi.
33
+
34
+ ```python
35
+ mcp_client = MCPClient(
36
+ {"url": "http://localhost:7860/gradio_api/mcp/sse"}
37
+ )
38
+ tools = mcp_client.get_tools()
39
+ ```
40
+
41
+ Sau khi có các công cụ, ta có thể tạo một agent đơn giản sử dụng chúng để trả lời câu hỏi. Hiện tại chúng ta sẽ dùng `InferenceClientModel` và mô hình mặc định từ `smolagents`.
42
+
43
+ ```python
44
+ model = InferenceClientModel()
45
+ agent = CodeAgent(tools=[*tools], model=model)
46
+ ```
47
+
48
+ Giờ tạo giao diện Gradio đơn giản sử dụng agent để trả lời câu hỏi.
49
+
50
+ ```python
51
+ demo = gr.ChatInterface(
52
+ fn=lambda message, history: str(agent.run(message)),
53
+ type="messages",
54
+ examples=["Prime factorization of 68"],
55
+ title="Agent with MCP Tools",
56
+ description="Đây là agent đơn giản sử dụng các công cụ MCP để trả lời câu hỏi.",
57
+ messages=[],
58
+ )
59
+
60
+ demo.launch()
61
+ ```
62
+
63
+ Vậy là xong! Chúng ta đã tạo một giao diện Gradio đơn giản dùng MCP Client để kết nối đến MCP Server và trả lời câu hỏi.
64
+
65
+ <iframe
66
+ src="https://mcp-course-unit2-gradio-client.hf.space"
67
+ frameborder="0"
68
+ width="850"
69
+ height="450"
70
+ ></iframe>
71
+
72
+
73
+ ## Ví dụ hoàn chỉnh
74
+
75
+ Dưới đây là ví dụ hoàn chỉnh của MCP Client trong Gradio:
76
+
77
+ ```python
78
+ import gradio as gr
79
+
80
+ from mcp.client.stdio import StdioServerParameters
81
+ from smolagents import ToolCollection, CodeAgent
82
+ from smolagents import CodeAgent, InferenceClientModel
83
+ from smolagents.mcp_client import MCPClient
84
+
85
+
86
+ try:
87
+ mcp_client = MCPClient(
88
+ # {"url": "https://abidlabs-mcp-tools.hf.space/gradio_api/mcp/sse"}
89
+ {"url": "http://localhost:7860/gradio_api/mcp/sse"}
90
+ )
91
+ tools = mcp_client.get_tools()
92
+
93
+ model = InferenceClientModel()
94
+ agent = CodeAgent(tools=[*tools], model=model)
95
+
96
+ def call_agent(message, history):
97
+ return str(agent.run(message))
98
+
99
+
100
+ demo = gr.ChatInterface(
101
+ fn=lambda message, history: str(agent.run(message)),
102
+ type="messages",
103
+ examples=["Prime factorization of 68"],
104
+ title="Agent with MCP Tools",
105
+ description="Đây là agent đơn giản sử dụng các công cụ MCP để trả lời câu hỏi.",
106
+ messages=[],
107
+ )
108
+
109
+ demo.launch()
110
+ finally:
111
+ mcp_client.close()
112
+ ```
113
+
114
+ Bạn sẽ thấy chúng ta đóng MCP Client trong khối `finally`. Điều này quan trọng vì MCP Client là đối tượng tồn tại lâu dài cần được đóng khi chương trình kết thúc.
115
+
116
+ ## Triển khai lên Hugging Face Spaces
117
+
118
+ Để chia sẻ server của bạn với mọi người, bạn có thể triển khai lên Hugging Face Spaces như đã làm ở chương trước.
119
+ Để triển khai Gradio MCP client lên Hugging Face Spaces:
120
+
121
+ 1. Tạo Space mới trên Hugging Face:
122
+ - Truy cập huggingface.co/spaces
123
+ - Click "Create new Space"
124
+ - Chọn "Gradio" làm SDK
125
+ - Đặt tên cho Space (ví dụ: "mcp-client")
126
+
127
+ 2. Tạo một tệp `requirements.txt`:
128
+ ```txt
129
+ gradio[mcp]
130
+ smolagents[mcp]
131
+ ```
132
+
133
+ 3. Đẩy code lên Space:
134
+ ```bash
135
+ git init
136
+ git add server.py requirements.txt
137
+ git commit -m "Initial commit"
138
+ git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-client
139
+ git push -u origin main
140
+ ```
141
+
142
+ ## Kết luận
143
+
144
+ Trong phần này, chúng ta đã tìm hiểu cách sử dụng Gradio như một MCP Client để kết nối đến một MCP Server. Chúng ta cũng đã xem qua cách triển khai MCP Client trên Hugging Face Spaces.
units/vi/unit2/gradio-server.mdx ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Xây dựng Gradio MCP Server
2
+
3
+ Trong phần này, chúng ta sẽ tạo một MCP server phân tích cảm xúc bằng Gradio. Server này sẽ cung cấp công cụ phân tích cảm xúc cho cả người dùng qua giao diện web và các mô hình AI thông qua giao thức MCP.
4
+
5
+ ## Giới thiệu tích hợp Gradio MCP
6
+
7
+ Gradio cung cấp cách đơn giản để tạo MCP server bằng việc tự động chuyển đổi các hàm Python thành MCP Tools. Khi bạn đặt `mcp_server=True` trong `launch()`, Gradio sẽ:
8
+
9
+ 1. Tự động chuyển đổi các hàm thành MCP Tools
10
+ 2. Ánh xạ các thành phần đầu vào sang schema tham số công cụ
11
+ 3. Xác định định dạng phản hồi từ các thành phần đầu ra
12
+ 4. Thiết lập JSON-RPC qua HTTP+SSE cho giao tiếp client-server
13
+ 5. Tạo cả giao diện web và endpoint MCP server
14
+
15
+ ## Thiết lập dự án
16
+
17
+ Đầu tiên, hãy tạo thư mục mới cho dự án và cài đặt các phụ thuộc cần thiết:
18
+
19
+ ```bash
20
+ mkdir mcp-sentiment
21
+ cd mcp-sentiment
22
+ python -m venv venv
23
+ source venv/bin/activate # Trên Windows: venv\Scripts\activate
24
+ pip install "gradio[mcp]" textblob
25
+ ```
26
+
27
+ ## Tạo Server
28
+
29
+ Tạo một tệp mới có tên `server.py` với mã sau:
30
+
31
+ <details>
32
+ <summary>Bấm để xem bản dịch tiếng Việt</summary>
33
+ ```python
34
+ import gradio as gr
35
+ from textblob import TextBlob
36
+
37
+ def sentiment_analysis(text: str) -> dict:
38
+ """
39
+ Phân tích cảm xúc của văn bản được cung cấp.
40
+
41
+ Args:
42
+ text (str): Văn bản cần phân tích
43
+
44
+ Returns:
45
+ dict: Từ điển chứa thông tin về độ phân cực, tính chủ quan và đánh giá
46
+ """
47
+ blob = TextBlob(text)
48
+ sentiment = blob.sentiment
49
+
50
+ return {
51
+ "polarity": round(sentiment.polarity, 2), # -1 (tiêu cực) đến 1 (tích cực)
52
+ "subjectivity": round(sentiment.subjectivity, 2), # 0 (khách quan) đến 1 (chủ quan)
53
+ "assessment": "positive" if sentiment.polarity > 0 else "negative" if sentiment.polarity < 0 else "neutral"
54
+ }
55
+
56
+ # Tạo giao diện Gradio
57
+ demo = gr.Interface(
58
+ fn=sentiment_analysis,
59
+ inputs=gr.Textbox(placeholder="Nhập văn bản để phân tích..."),
60
+ outputs=gr.JSON(),
61
+ title="Phân Tích Cảm Xúc Văn Bản",
62
+ description="Phân tích cảm xúc văn bản sử dụng TextBlob"
63
+ )
64
+
65
+ # Khởi chạy giao diện và Server MCP
66
+ if __name__ == "__main__":
67
+ demo.launch(mcp_server=True)
68
+ ```
69
+ </details>
70
+
71
+ ```python
72
+ import gradio as gr
73
+ from textblob import TextBlob
74
+
75
+ def sentiment_analysis(text: str) -> dict:
76
+ """
77
+ Analyze the sentiment of the given text.
78
+
79
+ Args:
80
+ text (str): The text to analyze
81
+
82
+ Returns:
83
+ dict: A dictionary containing polarity, subjectivity, and assessment
84
+ """
85
+ blob = TextBlob(text)
86
+ sentiment = blob.sentiment
87
+
88
+ return {
89
+ "polarity": round(sentiment.polarity, 2), # -1 (negative) to 1 (positive)
90
+ "subjectivity": round(sentiment.subjectivity, 2), # 0 (objective) to 1 (subjective)
91
+ "assessment": "positive" if sentiment.polarity > 0 else "negative" if sentiment.polarity < 0 else "neutral"
92
+ }
93
+
94
+ # Create the Gradio interface
95
+ demo = gr.Interface(
96
+ fn=sentiment_analysis,
97
+ inputs=gr.Textbox(placeholder="Enter text to analyze..."),
98
+ outputs=gr.JSON(),
99
+ title="Text Sentiment Analysis",
100
+ description="Analyze the sentiment of text using TextBlob"
101
+ )
102
+
103
+ # Launch the interface and MCP server
104
+ if __name__ == "__main__":
105
+ demo.launch(mcp_server=True)
106
+ ```
107
+
108
+ ## Hiểu về Mã
109
+
110
+ Hãy cùng phân tích các thành phần chính:
111
+
112
+ 1. **Định nghĩa Hàm**:
113
+ - Hàm `sentiment_analysis` nhận đầu vào là văn bản và trả về một từ điển
114
+ - Sử dụng TextBlob để phân tích cảm xúc
115
+ - Docstring rất quan trọng vì giúp Gradio tạo lược đồ công cụ MCP
116
+ - Gợi ý kiểu dữ liệu (`str` và `dict`) giúp xác định lược đồ đầu vào/đầu ra
117
+
118
+ 2. **Giao diện Gradio**:
119
+ - `gr.Interface` tạo cả giao diện web và Server MCP
120
+ - Hàm được hiển thị như một công cụ MCP tự động
121
+ - Các thành phần đầu vào và đầu ra xác định lược đồ công cụ
122
+ - Thành phần đầu ra JSON đảm bảo tuần tự hóa đúng cách
123
+
124
+ 3. **Server MCP**:
125
+ - Thiết lập `mcp_server=True` kích hoạt Server MCP
126
+ - Server sẽ có sẵn tại `http://localhost:7860/gradio_api/mcp/sse`
127
+ - Bạn cũng có thể kích hoạt bằng biến môi trường:
128
+ ```bash
129
+ export GRADIO_MCP_SERVER=True
130
+ ```
131
+
132
+ ## Chạy Server
133
+
134
+ Khởi động Server bằng cách chạy:
135
+
136
+ ```bash
137
+ python server.py
138
+ ```
139
+
140
+ Bạn sẽ thấy đầu ra cho biết cả giao diện web và Server MCP đang chạy. Giao diện web sẽ có sẵn tại `http://localhost:7860`, và Server MCP tại `http://localhost:7860/gradio_api/mcp/sse`.
141
+
142
+ ## Kiểm tra Server
143
+
144
+ Bạn có thể kiểm tra Server bằng hai cách:
145
+
146
+ 1. **Giao diện Web**:
147
+ - Mở `http://localhost:7860` trong trình duyệt
148
+ - Nhập văn bản và nhấp "Submit"
149
+ - Bạn sẽ thấy kết quả phân tích cảm xúc
150
+
151
+ 2. **Lược đồ MCP**:
152
+ - Truy cập `http://localhost:7860/gradio_api/mcp/schema`
153
+ - Hiển thị lược đồ công cụ MCP mà các Client sẽ sử dụng
154
+ - Bạn cũng có thể tìm thấy liên kết này trong phần "View API" ở chân trang ứng dụng Gradio
155
+
156
+ ## Mẹo Xử lý Sự cố
157
+
158
+ 1. **Gợi ý Kiểu dữ liệu và Docstring**:
159
+ - Luôn cung cấp gợi ý kiểu dữ liệu cho tham số hàm và giá trị trả về
160
+ - Bao gồm docstring với khối "Args:" cho mỗi tham số
161
+ - Điều này giúp Gradio tạo lược đồ công cụ MCP chính xác
162
+
163
+ 2. **Đầu vào Chuỗi**:
164
+ - Khi không chắc chắn, hãy chấp nhận đối số đầu vào dưới dạng `str`
165
+ - Chuyển đổi chúng sang kiểu mong muốn bên trong hàm
166
+ - Cung cấp khả năng tương thích tốt hơn với các Client MCP
167
+
168
+ 3. **Hỗ trợ SSE**:
169
+ - Một số Client MCP không hỗ trợ Server MCP dựa trên SSE
170
+ - Trong trường hợp đó, sử dụng `mcp-remote`:
171
+ ```json
172
+ {
173
+ "mcpServers": {
174
+ "gradio": {
175
+ "command": "npx",
176
+ "args": [
177
+ "mcp-remote",
178
+ "http://localhost:7860/gradio_api/mcp/sse"
179
+ ]
180
+ }
181
+ }
182
+ }
183
+ ```
184
+
185
+ 4. **Sự cố Kết nối**:
186
+ - Nếu gặp vấn đề kết nối, thử khởi động lại cả Client và Server
187
+ - Kiểm tra xem Server đang chạy và có thể truy cập được không
188
+ - Xác nhận rằng lược đồ MCP có sẵn tại URL mong đợi
189
+
190
+ ## Triển khai lên Hugging Face Spaces
191
+
192
+ Để làm cho Server của bạn có sẵn cho người khác, bạn có thể triển khai lên Hugging Face Spaces:
193
+
194
+ 1. Tạo một Space mới trên Hugging Face:
195
+ - Truy cập huggingface.co/spaces
196
+ - Nhấp "Create new Space"
197
+ - Chọn "Gradio" làm SDK
198
+ - Đặt tên cho Space của bạn (ví dụ: "mcp-sentiment")
199
+
200
+ 2. Tạo tệp `requirements.txt`:
201
+ ```txt
202
+ gradio[mcp]
203
+ textblob
204
+ ```
205
+
206
+ 3. Đẩy mã của bạn lên Space:
207
+ ```bash
208
+ git init
209
+ git add server.py requirements.txt
210
+ git commit -m "Initial commit"
211
+ git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/mcp-sentiment
212
+ git push -u origin main
213
+ ```
214
+
215
+ Server MCP của các bạn giờ đã có thể truy cập tại:
216
+ ```
217
+ https://YOUR_USERNAME-mcp-sentiment.hf.space/gradio_api/mcp/sse
218
+ ```
219
+
220
+ ## Bước tiếp theo
221
+
222
+ Giờ khi đã có Server MCP đang chạy, chúng ta sẽ tạo các Client để tương tác với nó. Trong các phần tiếp theo, chúng ta sẽ:
223
+
224
+ 1. Tạo một Client dựa trên HuggingFace.js lấy cảm hứng từ Tiny Agents
225
+ 2. Triển khai một Client Python dựa trên SmolAgents
226
+ 3. Kiểm tra cả hai Client với Server đã triển khai
227
+
228
+ Hãy cùng chuyển sang phần xây dựng Client đầu tiên nào!
units/vi/unit2/introduction.mdx ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Xây Dựng Ứng Dụng MCP Đầu Cuối
2
+
3
+ Chào mừng các bạn đến với Chương 2 của Khóa học MCP!
4
+
5
+ Trong chương này, chúng ta sẽ xây dựng một ứng dụng MCP hoàn chỉnh từ đầu, tập trung vào việc tạo Server với Gradio và kết nối nó với nhiều Client. Cách tiếp cận thực hành này sẽ giúp bạn có được kinh nghiệm thực tế với toàn bộ hệ sinh thái MCP.
6
+
7
+ <Tip>
8
+
9
+ Trong chương này, chúng ta sẽ xây dựng một Server và Client MCP đơn giản bằng Gradio và HuggingFace Hub. Ở chương tiếp theo, chúng ta sẽ phát triển một Server phức tạp hơn để giải quyết các bài toán thực tế.
10
+
11
+ </Tip>
12
+
13
+ ## Những Nội Dung Bạn Sẽ Học
14
+
15
+ Trong chương này, các bạn sẽ:
16
+
17
+ - Tạo Server MCP sử dụng tính năng hỗ trợ MCP tích hợp của Gradio
18
+ - Xây dựng công cụ phân tích cảm xúc có thể được sử dụng bởi các Mô hình AI
19
+ - Kết nối với Server bằng các cách triển khai Client khác nhau:
20
+ - Client dựa trên HuggingFace.js
21
+ - Client SmolAgents dành cho Python
22
+ - Triển khai Server MCP lên Hugging Face Spaces
23
+ - Kiểm tra và gỡ lỗi toàn bộ hệ thống
24
+
25
+ Kết thúc chương này, bạn sẽ có một ứng dụng MCP hoạt động thể hiện được sức mạnh và tính linh hoạt của giao thức này.
26
+
27
+ ## Điều Kiện Tiên Quyết
28
+
29
+ Trước khi bắt đầu chương này, hãy đảm bảo bạn:
30
+
31
+ - Đã hoàn thành Chương 1 hoặc hiểu cơ bản về các khái niệm MCP
32
+ - Thành thạo cả Python và JavaScript/TypeScript
33
+ - Hiểu cơ bản về API và kiến trúc Client-Server
34
+ - Có môi trường phát triển với:
35
+ - Python 3.10+
36
+ - Node.js 18+
37
+ - Tài khoản Hugging Face (để triển khai)
38
+
39
+ ## Dự Án End-to-End Của Chúng Ta
40
+
41
+ Chúng ta sẽ xây dựng ứng dụng phân tích cảm xúc bao gồm 3 phần chính: Server, Client và phần triển khai.
42
+
43
+ ![sentiment analysis application](https://huggingface.co/datasets/mcp-course/images/resolve/main/unit2/1.png)
44
+
45
+ ### Phía Server
46
+
47
+ - Sử dụng Gradio để tạo giao diện web và Server MCP qua `gr.Interface`
48
+ - Triển khai công cụ phân tích cảm xúc bằng TextBlob
49
+ - Cung cấp công cụ qua cả giao thức HTTP và MCP
50
+
51
+ ### Phía Client
52
+
53
+ - Triển khai Client HuggingFace.js
54
+ - Hoặc tạo Client Python smolagents
55
+ - Minh họa cách sử dụng cùng một Server với các cách triển khai Client khác nhau
56
+
57
+ ### Triển Khai
58
+
59
+ - Đưa Server lên Hugging Face Spaces
60
+ - Cấu hình các Client để làm việc với Server đã triển khai
61
+
62
+ ## Hãy Bắt Đầu Nào!
63
+
64
+ ## Hãy Bắt Đầu Nào!
65
+
66
+ Bạn đã sẵn sàng xây dựng ứng dụng MCP đầu cuối đầu tiên chưa? Hãy bắt đầu bằng cách thiết lập môi trường phát triển và tạo máy chủ MCP Gradio của chúng ta.
units/vi/unit2/tiny-agents.mdx ADDED
@@ -0,0 +1,475 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Tiny Agents: Một agent chạy bằng MCP chỉ với 50 dòng mã
2
+
3
+ Sau khi đã xây dựng các máy chủ MCP bằng Gradio, giờ chúng ta sẽ khám phá sâu hơn về máy khách MCP. Phần này phát triển từ dự án thử nghiệm [Tiny Agents](https://huggingface.co/blog/tiny-agents) - minh họa cách triển khai máy khách MCP siêu đơn giản có thể kết nối với các dịch vụ như máy chủ phân tích cảm xúc Gradio của chúng ta.
4
+
5
+ Trong bài thực hành ngắn này, chúng mình sẽ hướng dẫn các bạn cách triển khai máy khách MCP bằng TypeScript (JS) có thể giao tiếp với bất kỳ máy chủ MCP nào, bao gồm cả máy chủ phân tích cảm xúc dựa trên Gradio đã xây dựng ở phần trước. Bạn sẽ thấy MCP chuẩn hóa cách các agent tương tác với công cụ như thế nào, giúp phát triển AI Agent trở nên đơn giản hơn đáng kể.
6
+
7
+ ![meme](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/tiny-agents/thumbnail.jpg)
8
+ <figcaption>Ảnh được cung cấp bởi https://x.com/adamdotdev</figcaption>
9
+
10
+ Chúng ta sẽ chỉ cách kết nối tiny agent của bạn với các máy chủ MCP chạy trên Gradio, cho phép nó tận dụng cả công cụ phân tích cảm xúc tùy chỉnh của bạn lẫn các công cụ có sẵn khác.
11
+
12
+ ## Cách chạy bản demo hoàn chỉnh
13
+
14
+ Nếu đã cài NodeJS (với `pnpm` hoặc `npm`), chỉ cần chạy lệnh sau trong terminal:
15
+
16
+ ```bash
17
+ npx @huggingface/mcp-client
18
+ ```
19
+
20
+ hoặc nếu dùng `pnpm`:
21
+
22
+ ```bash
23
+ pnpx @huggingface/mcp-client
24
+ ```
25
+
26
+ Lệnh này sẽ cài đặt gói vào thư mục tạm rồi thực thi lệnh của nó.
27
+
28
+ Bạn sẽ thấy Agent đơn giản của mình kết nối với nhiều máy chủ MCP (chạy local), tải các công cụ của chúng (tương tự cách nó tải công cụ phân tích cảm xúc Gradio của bạn), sau đó nhắc bạn bắt đầu hội thoại.
29
+
30
+ <video controls autoplay loop>
31
+ <source src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/tiny-agents/use-filesystem.mp4" type="video/mp4">
32
+ </video>
33
+
34
+ Mặc định, ví dụ của chúng ta kết nối với hai máy chủ MCP:
35
+
36
+ - Máy chủ ["hệ thống file" chuẩn](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem) - có quyền truy cập vào Desktop của bạn
37
+ - Máy chủ [Playwright MCP](https://github.com/microsoft/playwright-mcp) - biết cách dùng trình duyệt Chromium trong môi trường sandbox
38
+
39
+ Bạn có thể dễ dàng thêm máy chủ phân tích cảm xúc Gradio của mình vào danh sách này như chúng ta sẽ minh họa sau.
40
+
41
+ > [!NOTE]
42
+ > Lưu ý: Hiện tại tất cả máy chủ MCP trong tiny agents đều là các tiến trình local (dù các máy chủ từ xa sẽ sớm được hỗ trợ). Điều này không bao gồm máy chủ Gradio của chúng ta chạy trên localhost:7860.
43
+
44
+ Đầu vào cho video đầu tiên là:
45
+
46
+ > write a haiku about the Hugging Face community and write it to a file named "hf.txt" on my Desktop
47
+
48
+ Giờ thử prompt liên quan đến duyệt Web:
49
+
50
+ > do a Web Search for HF inference providers on Brave Search and open the first 3 results
51
+
52
+ <video controls autoplay loop>
53
+ <source src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/tiny-agents/brave-search.mp4" type="video/mp4">
54
+ </video>
55
+
56
+ Với công cụ phân tích cảm xúc Gradio đã kết nối, chúng ta có thể hỏi tương tự:
57
+ > analyze the sentiment of this review: "I absolutely loved the product, it exceeded all my expectations!"
58
+
59
+ ### Mô hình và nhà cung cấp mặc định
60
+
61
+ Về cặp mô hình/nhà cung cấp, Agent mẫu của chúng ta mặc định dùng:
62
+ - ["Qwen/Qwen2.5-72B-Instruct"](https://huggingface.co/Qwen/Qwen2.5-72B-Instruct)
63
+ - chạy trên [Nebius](https://huggingface.co/docs/inference-providers/providers/nebius)
64
+
65
+ Tất cả cài đặt này đều có thể tùy chỉnh qua biến môi trường! Ở đây, chúng ta cũng sẽ hướng dẫn cách thêm máy chủ Gradio MCP của mình:
66
+
67
+ ```ts
68
+ const agent = new Agent({
69
+ provider: process.env.PROVIDER ?? "nebius",
70
+ model: process.env.MODEL_ID ?? "Qwen/Qwen2.5-72B-Instruct",
71
+ apiKey: process.env.HF_TOKEN,
72
+ servers: [
73
+ // Các máy chủ mặc định
74
+ {
75
+ command: "npx",
76
+ args: ["@modelcontextprotocol/servers", "filesystem"]
77
+ },
78
+ {
79
+ command: "npx",
80
+ args: ["playwright-mcp"]
81
+ },
82
+ // Máy chủ phân tích cảm xúc Gradio của chúng ta
83
+ {
84
+ command: "npx",
85
+ args: [
86
+ "mcp-remote",
87
+ "http://localhost:7860/gradio_api/mcp/sse"
88
+ ]
89
+ }
90
+ ],
91
+ });
92
+ ```
93
+
94
+ <Tip>
95
+
96
+ Chúng ta kết nối tới máy chủ MCP dựa trên Gradio thông qua gói [`mcp-remote`](https://www.npmjs.com/package/mcp-remote).
97
+
98
+ </Tip>
99
+
100
+
101
+ ## Nền tảng cho điều này: hỗ trợ gọi công cụ native trong LLMs
102
+
103
+ Điều giúp kết nối các m��y chủ MCP Gradio với Tiny Agent của chúng ta là các LLM (cả closed và open) gần đây đã được huấn luyện để gọi hàm (function calling), hay còn gọi là sử dụng công cụ. Chính khả năng này hỗ trợ tích hợp của chúng ta với công cụ phân tích cảm xúc mà chúng ta đã xây dựng bằng Gradio.
104
+
105
+ Một công cụ được định nghĩa bởi tên, mô tả và biểu diễn JSONSchema của các tham số - giống hệt cách chúng ta định nghĩa hàm phân tích cảm xúc trong máy chủ Gradio. Hãy xem một ví dụ đơn giản:
106
+
107
+ <details>
108
+ <summary>Bấm để xem bản dịch tiếng Việt</summary>
109
+ ```ts
110
+ const weatherTool = {
111
+ type: "function",
112
+ function: {
113
+ name: "get_weather",
114
+ description: "Nhận nhiệt độ hiện tại cho một địa điểm cụ thể.",
115
+ parameters: {
116
+ type: "object",
117
+ properties: {
118
+ location: {
119
+ type: "string",
120
+ description: "Thành phố và quốc gia, ví dụ: Hà Nội, Việt Nam",
121
+ },
122
+ },
123
+ },
124
+ },
125
+ };
126
+ ```
127
+ </details>
128
+
129
+ ```ts
130
+ const weatherTool = {
131
+ type: "function",
132
+ function: {
133
+ name: "get_weather",
134
+ description: "Get current temperature for a given location.",
135
+ parameters: {
136
+ type: "object",
137
+ properties: {
138
+ location: {
139
+ type: "string",
140
+ description: "City and country e.g. Bogotá, Colombia",
141
+ },
142
+ },
143
+ },
144
+ },
145
+ };
146
+ ```
147
+
148
+ Công cụ phân tích cảm xúc Gradio của chúng ta sẽ có cấu trúc tương tự, với `text` làm tham số đầu vào thay vì `location`.
149
+
150
+ Tài liệu chính thức mà mình sẽ liên kết ở đây là [tài liệu function calling của OpenAI](https://platform.openai.com/docs/guides/function-calling?api-mode=chat). (Đúng vậy... OpenAI gần như định nghĩa các tiêu chuẩn LLM cho cả cộng đồng 😅).
151
+
152
+ Các inference engine cho phép bạn truyền một danh sách công cụ khi gọi LLM, và LLM có thể tự do gọi không, một hoặc nhiều công cụ trong số đó.
153
+ Là một developer, bạn chạy các công cụ và đưa kết quả của chúng trở lại LLM để tiếp tục quá trình sinh kết quả.
154
+
155
+ > Lưu ý rằng ở backend (ở cấp độ inference engine), các công cụ đơn giản được truyền vào mô hình trong một `chat_template` được định dạng đặc biệt, giống như bất kỳ tin nhắn nào khác, sau đó được phân tích từ phản hồi (sử dụng các token đặc biệt của mô hình) để hiển thị dưới dạng các lệnh gọi công cụ.
156
+
157
+ ## Triển khai MCP client trên InferenceClient
158
+
159
+ Giờ chúng ta đã biết tool là gì trong các LLM hiện đại, hãy cùng triển khai MCP client thực tế để giao tiếp với Gradio server và các MCP server khác.
160
+
161
+ Tài liệu chính thức tại https://modelcontextprotocol.io/quickstart/client khá chi tiết. Bạn chỉ cần thay thế mọi đề cập đến SDK client Anthropic bằng bất kỳ SDK client tương thích OpenAI nào khác. (Có một file [llms.txt](https://modelcontextprotocol.io/llms-full.txt) bạn có thể dùng để huấn luyện LLM của mình hỗ trợ viết code).
162
+
163
+ Nhắc lại, chúng ta dùng `InferenceClient` của HF cho inference client.
164
+
165
+ > [!TIP]
166
+ > File code hoàn chỉnh `McpClient.ts` có tại [đây](https://github.com/huggingface/huggingface.js/blob/main/packages/mcp-client/src/McpClient.ts) nếu bạn muốn xem code thực tế 🤓
167
+
168
+ Lớp `McpClient` của chúng ta có:
169
+ - Một Inference Client (hoạt động với mọi Nhà cung cấp Inference, và `huggingface/inference` hỗ trợ cả endpoint từ xa lẫn local)
170
+ - Một tập hợp các phiên MCP client, mỗi phiên cho một MCP server được kết nối (cho phép kết nối đến nhiều server, bao gồm cả Gradio server của chúng ta)
171
+ - Danh sách các tool khả dụng sẽ được điền từ các server đã kết nối và định dạng lại một chút.
172
+
173
+ ```ts
174
+ export class McpClient {
175
+ protected client: InferenceClient;
176
+ protected provider: string;
177
+ protected model: string;
178
+ private clients: Map<ToolName, Client> = new Map();
179
+ public readonly availableTools: ChatCompletionInputTool[] = [];
180
+
181
+ constructor({ provider, model, apiKey }: { provider: InferenceProvider; model: string; apiKey: string }) {
182
+ this.client = new InferenceClient(apiKey);
183
+ this.provider = provider;
184
+ this.model = model;
185
+ }
186
+
187
+ // [...]
188
+ }
189
+ ```
190
+
191
+ Để kết nối đến MCP server (như Gradio server phân tích cảm xúc của chúng ta), SDK TypeScript chính thức `@modelcontextprotocol/sdk/client` cung cấp lớp `Client` với phương thức `listTools()`:
192
+
193
+ ```ts
194
+ async addMcpServer(server: StdioServerParameters): Promise<void> {
195
+ const transport = new StdioClientTransport({
196
+ ...server,
197
+ env: { ...server.env, PATH: process.env.PATH ?? "" },
198
+ });
199
+ const mcp = new Client({ name: "@huggingface/mcp-client", version: packageVersion });
200
+ await mcp.connect(transport);
201
+
202
+ const toolsResult = await mcp.listTools();
203
+ debug(
204
+ "Connected to server with tools:",
205
+ toolsResult.tools.map(({ name }) => name)
206
+ );
207
+
208
+ for (const tool of toolsResult.tools) {
209
+ this.clients.set(tool.name, mcp);
210
+ }
211
+
212
+ this.availableTools.push(
213
+ ...toolsResult.tools.map((tool) => {
214
+ return {
215
+ type: "function",
216
+ function: {
217
+ name: tool.name,
218
+ description: tool.description,
219
+ parameters: tool.inputSchema,
220
+ },
221
+ } satisfies ChatCompletionInputTool;
222
+ })
223
+ );
224
+ }
225
+ ```
226
+
227
+ `StdioServerParameters` là một interface từ MCP SDK giúp bạn dễ dàng tạo một process local: như đã đề cập, hiện tại tất cả MCP server đều là các process local, bao gồm cả Gradio server của chúng ta (dù chúng ta truy cập qua HTTP).
228
+
229
+ Với mỗi MCP server được kết nối (bao gồm Gradio server phân tích cảm xúc), chúng ta định dạng lại danh sách tool của nó và thêm vào `this.availableTools`.
230
+
231
+ ### Cách sử dụng các công cụ
232
+
233
+ Sử dụng công cụ phân tích cảm xúc của chúng ta (hoặc bất kỳ công cụ MCP nào khác) rất đơn giản. Bạn chỉ cần truyền `this.availableTools` vào LLM chat-completion, cùng với mảng messages thông thường:
234
+
235
+ ```ts
236
+ const stream = this.client.chatCompletionStream({
237
+ provider: this.provider,
238
+ model: this.model,
239
+ messages,
240
+ tools: this.availableTools,
241
+ tool_choice: "auto",
242
+ });
243
+ ```
244
+
245
+ `tool_choice: "auto"` là tham số bạn truyền để LLM có thể tạo ra không, một hoặc nhiều lệnh gọi công cụ.
246
+
247
+ Khi phân tích hoặc stream kết quả, LLM sẽ tạo ra các lệnh gọi công cụ (ví dụ: tên hàm và các đối số được mã hóa JSON) mà bạn (với tư cách là nhà phát triển) cần xử lý. SDK MCP Client một lần nữa giúp việc này trở nên dễ dàng; nó có phương thức `client.callTool()`:
248
+
249
+ ```ts
250
+ const toolName = toolCall.function.name;
251
+ const toolArgs = JSON.parse(toolCall.function.arguments);
252
+
253
+ const toolMessage: ChatCompletionInputMessageTool = {
254
+ role: "tool",
255
+ tool_call_id: toolCall.id,
256
+ content: "",
257
+ name: toolName,
258
+ };
259
+
260
+ /// Lấy session phù hợp cho công cụ này
261
+ const client = this.clients.get(toolName);
262
+ if (client) {
263
+ const result = await client.callTool({ name: toolName, arguments: toolArgs });
264
+ toolMessage.content = result.content[0].text;
265
+ } else {
266
+ toolMessage.content = `Error: No session found for tool: ${toolName}`;
267
+ }
268
+ ```
269
+
270
+ Nếu LLM chọn sử dụng công cụ phân tích cảm xúc của chúng ta, đoạn code này sẽ tự động định tuyến lệnh gọi đến Gradio server của chúng ta, thực thi phân tích và trả về kết quả cho LLM.
271
+
272
+ Cuối cùng, bạn sẽ thêm message công cụ kết quả vào mảng `messages` và đưa ngược lại vào LLM.
273
+
274
+ ## Agent 50-dòng-code của chúng ta 🤯
275
+
276
+ Giờ đây khi đã có MCP client có khả năng kết nối đến các MCP server tùy ý (bao gồm cả Gradio sentiment analysis server) để lấy danh sách công cụ và chèn chúng vào LLM inference, vậy... Agent là gì?
277
+
278
+ > Khi bạn đã có một inference client với một bộ công cụ, thì Agent chỉ đơn giản là một vòng lặp while bao quanh nó.
279
+
280
+ Cụ thể hơn, Agent là sự kết hợp của:
281
+ - một system prompt
282
+ - một LLM Inference client
283
+ - một MCP client để kết nối các công cụ từ nhiều MCP server (bao gồm Gradio server của chúng ta)
284
+ - một số luồng điều khiển cơ bản (xem vòng lặp while bên dưới)
285
+
286
+ > [!TIP]
287
+ > File code hoàn chỉnh `Agent.ts` có tại [đây](https://github.com/huggingface/huggingface.js/blob/main/packages/mcp-client/src/Agent.ts).
288
+
289
+ Lớp Agent của chúng ta đơn giản kế thừa từ McpClient:
290
+
291
+ ```ts
292
+ export class Agent extends McpClient {
293
+ private readonly servers: StdioServerParameters[];
294
+ protected messages: ChatCompletionInputMessage[];
295
+
296
+ constructor({
297
+ provider,
298
+ model,
299
+ apiKey,
300
+ servers,
301
+ prompt,
302
+ }: {
303
+ provider: InferenceProvider;
304
+ model: string;
305
+ apiKey: string;
306
+ servers: StdioServerParameters[];
307
+ prompt?: string;
308
+ }) {
309
+ super({ provider, model, apiKey });
310
+ this.servers = servers;
311
+ this.messages = [
312
+ {
313
+ role: "system",
314
+ content: prompt ?? DEFAULT_SYSTEM_PROMPT,
315
+ },
316
+ ];
317
+ }
318
+ }
319
+ ```
320
+
321
+ Mặc định, chúng ta sử dụng system prompt đơn giản lấy cảm hứng từ [hướng dẫn prompt GPT-4.1](https://cookbook.openai.com/examples/gpt4-1_prompting_guide).
322
+
323
+ Mặc dù điều này đến từ OpenAI 😈, nhưng câu này đặc biệt áp dụng cho ngày càng nhiều mô hình, cả đóng và mở:
324
+
325
+ > Chúng tôi khuyến khích nhà phát triển chỉ sử dụng trường tools để truyền công cụ, thay vì thủ công chèn mô tả công cụ vào prompt và viết parser riêng cho lệnh gọi công cụ như một số đã làm trước đây.
326
+
327
+ Nghĩa là chúng ta không cần cung cấp danh sách ví dụ về cách sử dụng công cụ được định dạng kỹ lưỡng trong prompt. Tham số `tools: this.availableTools` là đủ, và LLM sẽ biết cách sử dụng cả công cụ hệ thống file và công cụ phân tích cảm xúc Gradio của chúng ta.
328
+
329
+ Việc tải công cụ lên Agent đơn giản chỉ là kết nối đến các MCP server mong muốn (song song vì rất dễ thực hiện trong JS):
330
+
331
+ ```ts
332
+ async loadTools(): Promise<void> {
333
+ await Promise.all(this.servers.map((s) => this.addMcpServer(s)));
334
+ }
335
+ ```
336
+
337
+ Chúng ta thêm hai công cụ bổ sung (ngoài MCP) mà LLM có thể sử dụng cho luồng điều khiển của Agent:
338
+
339
+ ```ts
340
+ const taskCompletionTool: ChatCompletionInputTool = {
341
+ type: "function",
342
+ function: {
343
+ name: "task_complete",
344
+ description: "Call this tool when the task given by the user is complete",
345
+ parameters: {
346
+ type: "object",
347
+ properties: {},
348
+ },
349
+ },
350
+ };
351
+ const askQuestionTool: ChatCompletionInputTool = {
352
+ type: "function",
353
+ function: {
354
+ name: "ask_question",
355
+ description: "Ask a question to the user to get more info required to solve or clarify their problem.",
356
+ parameters: {
357
+ type: "object",
358
+ properties: {},
359
+ },
360
+ },
361
+ };
362
+ const exitLoopTools = [taskCompletionTool, askQuestionTool];
363
+ ```
364
+
365
+ Khi gọi bất kỳ công cụ nào trong số này, Agent sẽ ngắt vòng lặp và trả lại quyền kiểm soát cho người dùng để có dữ liệu đầu vào mới.
366
+
367
+ ### Vòng lặp while hoàn chỉnh
368
+
369
+ Hãy xem vòng lặp while hoàn chỉnh của chúng tôi.🎉
370
+
371
+ Điểm mấu chốt của vòng lặp while chính của Agent là chúng tôi chỉ lặp lại với LLM luân phiên giữa việc gọi công cụ và cung cấp cho nó kết quả công cụ, và chúng tôi làm như vậy **cho đến khi LLM bắt đầu phản hồi bằng hai thông báo không phải công cụ liên tiếp**.
372
+
373
+ Đây là vòng lặp while hoàn chỉnh:
374
+
375
+ ```ts
376
+ let numOfTurns = 0;
377
+ let nextTurnShouldCallTools = true;
378
+ while (true) {
379
+ try {
380
+ yield* this.processSingleTurnWithTools(this.messages, {
381
+ exitLoopTools,
382
+ exitIfFirstChunkNoTool: numOfTurns > 0 && nextTurnShouldCallTools,
383
+ abortSignal: opts.abortSignal,
384
+ });
385
+ } catch (err) {
386
+ if (err instanceof Error && err.message === "AbortError") {
387
+ return;
388
+ }
389
+ throw err;
390
+ }
391
+ numOfTurns++;
392
+ const currentLast = this.messages.at(-1)!;
393
+ if (
394
+ currentLast.role === "tool" &&
395
+ currentLast.name &&
396
+ exitLoopTools.map((t) => t.function.name).includes(currentLast.name)
397
+ ) {
398
+ return;
399
+ }
400
+ if (currentLast.role !== "tool" && numOfTurns > MAX_NUM_TURNS) {
401
+ return;
402
+ }
403
+ if (currentLast.role !== "tool" && nextTurnShouldCallTools) {
404
+ return;
405
+ }
406
+ if (currentLast.role === "tool") {
407
+ nextTurnShouldCallTools = false;
408
+ } else {
409
+ nextTurnShouldCallTools = true;
410
+ }
411
+ }
412
+ ```
413
+
414
+ ## Kết nối Tiny Agents với Gradio MCP Servers
415
+
416
+ Giờ thì chúng ta đã hiểu về cả Tiny Agents và Gradio MCP servers, hãy xem cách chúng hoạt động cùng nhau nhé! Điểm tuyệt vời của MCP là nó cung cấp cách chuẩn hóa để các agent tương tác với bất kỳ server nào tương thích MCP, bao gồm cả máy chủ phân tích cảm xúc (sentiment analysis) dựa trên Gradio của chúng ta.
417
+
418
+ ### Sử dụng Gradio Server với Tiny Agents
419
+
420
+ Để kết nối Tiny Agent của chúng ta với máy chủ phân tích cảm xúc Gradio đã xây dựng trước đó, chúng ta chỉ cần thêm nó vào danh sách servers. Dưới đây là cách chúng ta có thể điều chỉnh cấu hình agent:
421
+
422
+ ```ts
423
+ const agent = new Agent({
424
+ provider: process.env.PROVIDER ?? "nebius",
425
+ model: process.env.MODEL_ID ?? "Qwen/Qwen2.5-72B-Instruct",
426
+ apiKey: process.env.HF_TOKEN,
427
+ servers: [
428
+ // ... existing servers ...
429
+ {
430
+ command: "npx",
431
+ args: [
432
+ "mcp-remote",
433
+ "http://localhost:7860/gradio_api/mcp/sse" // Your Gradio MCP server
434
+ ]
435
+ }
436
+ ],
437
+ });
438
+ ```
439
+
440
+ Giờ đây agent của chúng ta đã có thể sử dụng công cụ phân tích cảm xúc cùng với các công cụ khác! Ví dụ, nó có thể:
441
+ 1. Đọc văn bản từ file bằng filesystem server
442
+ 2. Phân tích cảm xúc bằng Gradio server của chúng ta
443
+ 3. Ghi kết quả trở lại file
444
+
445
+ ### Ví dụ tương tác
446
+
447
+ Đây là ví dụ về cuộc hội thoại với agent:
448
+
449
+ ```
450
+ User: Read the file "feedback.txt" from my Desktop and analyze its sentiment
451
+
452
+ Agent: I'll help you analyze the sentiment of the feedback file. Let me break this down into steps:
453
+
454
+ 1. First, I'll read the file using the filesystem tool
455
+ 2. Then, I'll analyze its sentiment using the sentiment analysis tool
456
+ 3. Finally, I'll write the results to a new file
457
+
458
+ [Agent tiến hành sử dụng các công cụ và cung cấp phân tích]
459
+ ```
460
+
461
+ ### Lưu ý khi triển khai
462
+
463
+ Khi triển khai Gradio MCP server của bạn lên Hugging Face Spaces, bạn cần cập nhật URL server trong cấu hình agent để trỏ tới space đã triển khai:
464
+
465
+ ```ts
466
+ {
467
+ command: "npx",
468
+ args: [
469
+ "mcp-remote",
470
+ "https://YOUR_USERNAME-mcp-sentiment.hf.space/gradio_api/mcp/sse"
471
+ ]
472
+ }
473
+ ```
474
+
475
+ Cách này cho phép agent của bạn sử dụng công cụ phân tích cảm xúc từ bất kỳ đâu, không chỉ trên local!
units/vi/unit3/introduction.mdx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Sắp ra mắt
2
+
3
+ Đây sẽ là một trường hợp sử dụng khác đi sâu hơn vào giao thức MCP và cách sử dụng nó theo những phương pháp phức tạp hơn.
units/vi/unit4/introduction.mdx ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # Sắp ra mắt
2
+
3
+ Chương này sẽ là sự hợp tác với các đối tác từ cộng đồng AI.
4
+
5
+ Nếu các bạn đang xây dựng công cụ MCP, hãy liên hệ với chúng mình để được thêm vào chương. Mở [thảo luận](https://huggingface.co/spaces/mcp-course/README/discussions) trên hub.