Các hệ thống RAG truyền thống có một vấn đề lớn: chúng tìm kiếm mọi thứ. Người dùng hỏi công thức làm pizza? Tìm trong kho tri thức. Hỏi thời tiết? Lại tìm nữa. Chỉ trò chuyện xã giao thôi? Cũng tìm kiếm.
Cách tiếp cận "bắn đại bác vào chim sẻ" này dẫn đến:
- Bối cảnh không liên quan làm rối input của LLM
- Chi phí cao hơn do các truy vấn và prompt dài không cần thiết
- Phản hồi chậm hơn vì phải truy cập cơ sở dữ liệu liên tục
- AI bối rối khi cố gắng hiểu các tài liệu không liên quan
Điều gì sẽ xảy ra nếu AI có thể tự quyết định khi nào nó thật sự cần tìm kiếm?
Agentic RAG: Để LLM quyết định
Agentic RAG lật ngược thế cờ. Thay vì tìm kiếm tự động cho mọi truy vấn, chúng ta cung cấp cho mô hình ngôn ngữ một bộ công cụ mà nó có thể tùy chọn sử dụng. Hãy tưởng tượng bạn đưa cho ai đó một hộp dụng cụ — họ sẽ dùng búa khi cần đóng đinh, chứ không phải khi đang khuấy súp.
Trong cách triển khai này, LLM có hai công cụ chính:
- Công cụ tìm kiếm: "Tôi cần thông tin về X"
- Công cụ chọn tài liệu: "Tôi sẽ dùng chính xác các tài liệu này"
Điều kỳ diệu xảy ra khi AI quyết định rằng nó cần thêm thông tin — chỉ lúc đó nó mới sử dụng công cụ tìm kiếm. Nếu bạn chỉ quan tâm đến mã nguồn (viết bằng Rust 😉), bạn có thể xem trên Github tại đây.
Tự thử: Chỉ với hai lệnh API
Muốn tích hợp RAG thông minh vào ứng dụng của bạn? Bạn có thể dùng hệ thống tìm kiếm agentic chỉ với hai lệnh API đơn giản. Không cần xây dựng lại từ đầu.
Bước 1: Tạo một chủ đề trò chuyện
Trước tiên, hãy tạo một chủ đề để lưu cuộc trò chuyện. Tham khảo tài liệu chi tiết tại: docs.trieve.ai/api-reference/topic/create-topic.
curl -X POST "https://api.trieve.ai/api/topic" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "TR-Dataset: YOUR_DATASET_ID" \ -H "Content-Type: application/json" \ -d '{ "owner_id": "user_123", "name": "My Chat Session" }'
Điều này trả về một ID chủ đề mà bạn sẽ sử dụng trong cuộc trò chuyện.
Bước 2: Gửi tin nhắn với Tìm kiếm Agentic
Bây giờ, gửi tin nhắn và để AI quyết định có nên tìm kiếm hay không. Tham khảo tài liệu đầy đủ tại: docs.trieve.ai/api-reference/message/create-message.
curl -X POST "https://api.trieve.ai/api/message" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "TR-Dataset: YOUR_DATASET_ID" \ -H "Content-Type: application/json" \ -d '{ "topic_id": "TOPIC_ID_FROM_STEP_1", "new_message_content": "How do I configure authentication?", "use_agentic_search": true }'
Vậy là xong! Hệ thống sẽ:
- Phân tích xem câu hỏi của bạn có cần tìm kiếm không
- Chỉ tìm kiếm khi thật sự cần
- Phản hồi theo thời gian thực
- Hiển thị rõ ràng các tài liệu đã được sử dụng
Điểm mấu chốt nằm ở use_agentic_search: true
— nó kích hoạt hành vi tìm kiếm thông minh như mô tả dưới đây.
Cách chúng tôi xây dựng: Một API đơn giản
Toàn bộ hệ thống Agentic RAG nằm gọn trong một hàm: stream_response_with_agentic_search
. Khi phân tách ra, nó thực ra rất dễ hiểu.
Bước 1: Thiết lập cuộc trò chuyện
// Simplified: Prepare messages for the LLM
let mut openai_messages: Vec<ChatMessage> = messages .iter() .map(|message| ChatMessage::from(message.clone())) .collect(); // Add the current user query
openai_messages.push(ChatMessage::User { content: ChatMessageContent::Text(user_message_query.clone()), name: None,
});
Chúng tôi chỉ cần lấy lịch sử trò chuyện và tin nhắn người dùng, định dạng lại cho LLM. Nếu có hình ảnh đính kèm, chúng cũng được thêm vào.
Bước 2: Tạo bộ dụng cụ
Chúng tôi định nghĩa các công cụ mà LLM có thể gọi:
// Simplified: Define tools the LLM can use
let tools = vec![ ChatCompletionTool { function: ChatCompletionFunction { name: "search".to_string(), description: "Search for relevant information in the knowledge base", parameters: json!({ "type": "object", "properties": { "query": { "type": "string", "description": "The search query to find relevant information" } } }), }, }, ChatCompletionTool { function: ChatCompletionFunction { name: "chunks_used".to_string(), description: "Tell the user which chunks you plan to use", parameters: json!({ "type": "object", "properties": { "chunks": { "type": "array", "items": {"type": "string"} } } }), }, }
];
Công cụ search
cho phép AI truy vấn kho tri thức. Công cụ chunks_used
giúp AI thông báo chính xác tài liệu nào được sử dụng — không còn chuyện "AI bốc đại" nữa.
Bước 3: Vòng lặp trò chuyện
// Simplified: Main conversation loop
loop { // Get response from LLM let response = client.chat().create(parameters.clone()).await?; // Add assistant message to conversation conversation_messages.push(response.message.clone()); // Check if AI wants to use tools if let Some(tool_calls) = response.tool_calls { for tool_call in tool_calls { match tool_call.function.name.as_str() { "search" => { // AI decided it needs to search let (results, formatted_results) = handle_search_tool_call( tool_call, dataset, pool, redis_pool, dataset_config, event_queue, ).await?; // Add search results back to conversation conversation_messages.push(ChatMessage::Tool { content: formatted_results, tool_call_id: tool_call.id, }); searched_chunks.extend(results); } "chunks_used" => { // AI specified which chunks it's using let chunks_to_use: Vec<String> = parse_chunks_used(&tool_call)?; // Filter to only keep specified chunks searched_chunks.retain(|chunk| { chunks_to_use.contains(&chunk.id.to_string()) }); } _ => {} } } // Continue conversation with tool results continue; } else { // No tool calls - we have the final response break; }
}
Vòng lặp này là trái tim của hành vi "agentic". LLM phản hồi, nếu có lời gọi công cụ thì chúng tôi xử lý và tiếp tục vòng lặp. Kết thúc khi LLM có phản hồi cuối cùng mà không cần công cụ.
Bước 4: Phát trực tiếp theo thời gian thực
// Simplified: Streaming with tool support
while let Some(response_chunk) = stream.next().await { match response_chunk { Ok(chunk) => { // Stream content to user if let Some(content) = chunk.content { tx.send(content).await; } // Handle tool calls mid-stream if chunk.finish_reason == Some("tool_calls") { // AI wants to use tools - pause streaming tx.send("[Searching...]").await; // Execute tool calls handle_tool_calls(&chunk.tool_calls).await; // Resume streaming with updated context continue; } } Err(e) => break, }
}
Người dùng thấy câu trả lời hiện ra ngay lập tức, cùng với các chỉ báo như “[Đang tìm kiếm...]”
khi AI cần thêm dữ liệu.
Yếu tố giúp hệ thống hoạt động hiệu quả
Khả năng tự quyết định dùng công cụ
LLM học được khi nào cần tìm kiếm dựa trên ngữ cảnh. Nếu ai đó hỏi "Thời tiết hôm nay thế nào?", nó sẽ không tìm trong tài liệu kỹ thuật. Nhưng nếu hỏi "Cấu hình xác thực như thế nào?", nó sẽ tìm tài liệu liên quan.
Minh bạch qua chọn lọc tài liệu
Công cụ chunks_used giải quyết vấn đề lớn của RAG: không biết câu trả lời đến từ đâu. Giờ đây AI chỉ rõ "Tôi đang dùng các tài liệu này".
Phát trực tuyến có thể gián đoạn
Khác với các hệ thống truyền thống (gộp yêu cầu, tìm kiếm, rồi phản hồi một lần), hệ thống này vẫn phát trực tiếp nhưng có thể tạm ngưng để tìm kiếm — tạo trải nghiệm tự nhiên hơn.
Hiệu quả thực tế
Từ khi triển khai phương pháp này, chúng tôi thấy:
- Giảm 60% các tìm kiếm không cần thiết
- Phản hồi nhanh hơn 40% với truy vấn đơn giản
- Độ chính xác cao hơn vì chỉ truy xuất bối cảnh liên quan
- Trải nghiệm người dùng tốt hơn nhờ minh bạch về nguồn thông tin
Hệ thống hoạt động mượt mà từ lời chào đơn giản (không cần tìm) đến các câu hỏi kỹ thuật phức tạp (có thể cần nhiều lần tìm kiếm).
Những cái giá phải trả
Dù hiệu quả, hệ thống này cũng có một số đánh đổi:
Ưu điểm:
- Tìm kiếm thông minh hơn
- Ghi nguồn rõ ràng
- Phản hồi theo thời gian thực
- Chi phí và độ trễ thấp hơn
Nhược điểm:
- Phức tạp hơn RAG truyền thống một chút
- Yêu cầu LLM hỗ trợ công cụ
- Nhiều lần gọi API với truy vấn phức tạp
Hướng phát triển tiếp theo
Chúng tôi đang tiếp tục cải tiến hệ thống:
- Mô tả công cụ thông minh hơn để LLM ra quyết định chính xác hơn
- Lý luận nhiều bước với các truy vấn cần nhiều lần tìm kiếm
- Thêm các công cụ chuyên biệt cho từng lĩnh vực
- Lựa chọn tài liệu tốt hơn dựa trên lập luận về độ liên quan
Kết luận
Agentic RAG không phải là thêm phức tạp, mà là thêm thông minh. Khi LLM tự quyết định khi nào và tìm cái gì, chúng tôi có một hệ thống vừa hiệu quả, vừa chính xác hơn các cách tiếp cận truyền thống.
Vẻ đẹp nằm ở sự đơn giản: Một API, vài công cụ rõ ràng — và đột nhiên hệ thống RAG của bạn trở thành một “trợ lý” thực sự thông minh.