Spaces:
Sleeping
Sleeping
feat: add toctree and translation unit 2 3 4
Browse files- units/vi/unit2/clients.mdx +79 -0
- units/vi/unit2/gradio-client.mdx +144 -0
- units/vi/unit2/gradio-server.mdx +228 -0
- units/vi/unit2/introduction.mdx +66 -0
- units/vi/unit2/tiny-agents.mdx +475 -0
- units/vi/unit3/introduction.mdx +3 -0
- units/vi/unit4/introduction.mdx +5 -0
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 |
+

|
| 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 |
+

|
| 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.
|