Skip to content

Commit 3fc9df1

Browse files
Merge pull request #40 from DUT-Team-21TCLC-DT3/feat/enhance-output-from-website-search
feat: Enhance output from web search and answer composer
2 parents c1c7a85 + eeb3bd5 commit 3fc9df1

File tree

3 files changed

+54
-51
lines changed

3 files changed

+54
-51
lines changed

ai_service/app/pipelines/answer_composer.py

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -71,39 +71,35 @@ def compose(
7171
{graph_context_str}
7272
{web_context_str}
7373
74-
QUY TẮC TRÍCH DẪN & HIỂN THỊ LINK (BẮT BUỘC TUÂN THỦ):
75-
7674
QUY TẮC ĐỊNH DẠNG (MARKDOWN):
7775
1. **Cấu trúc văn bản**:
7876
- Sử dụng **Markdown** để trình bày.
79-
- Dùng dấu `**...**` để **in đậm** những thông tin quan trọng như: số tiền phạt, số năm tù, tên điều luật.
77+
- Dùng dấu `**...**` để **in đậm** những thông tin quan trọng.
8078
- Dùng gạch đầu dòng (`-`) để liệt kê các ý.
81-
- Dùng tiêu đề (`###`) để phân chia các phần (Ví dụ: ### Đối với Ô tô, ### Đối với Xe máy).
82-
83-
2. **Quy tắc trích dẫn**:
84-
- **TUYỆT ĐỐI KHÔNG** chèn trực tiếp URL hay thẻ [[...]] vào giữa dòng.
85-
- Chỉ sử dụng **số thứ tự trong ngoặc vuông** để đánh dấu nguồn minh chứng. Ví dụ: [1], [2], [3].
86-
- Đặt số thứ tự này ở cuối câu hoặc cuối mệnh đề quan trọng.
87-
- Ví dụ đúng: "Mức phạt là 20 triệu đồng [1]."
88-
- Ví dụ sai: "Mức phạt là 20 triệu [[Link...]] đồng."
89-
90-
3. **Phần danh sách nguồn cuối cùng**:
91-
- Bắt buộc tạo một mục riêng ở cuối câu trả lời với tiêu đề: "**NGUỒN THAM KHẢO**".
92-
- Tại mục này, hãy liệt kê chi tiết các nguồn tương ứng với số thứ tự đã đánh dấu ở trên.
93-
- Sử dụng định dạng FE chuẩn cho từng dòng:
94-
**[n] [[Tên Tiêu Đề Ngắn Gọn | URL]]**
95-
96-
3. **Yêu cầu nội dung**:
79+
- Dùng tiêu đề (`###`) để phân chia các phần.
80+
81+
2. **Quy tắc trích dẫn (Footnote)**:
82+
- Trong nội dung bài viết, **TUYỆT ĐỐI KHÔNG** chèn URL.
83+
- Chỉ sử dụng **số thứ tự trong ngoặc vuông** để đánh dấu nguồn. Ví dụ: [1], [2].
84+
- Đặt số thứ tự này ở cuối câu chứa thông tin.
85+
86+
3. **Phần danh sách nguồn cuối cùng (QUAN TRỌNG)**:
87+
- Bắt buộc tạo một mục riêng ở cuối cùng với tiêu đề: `### Nguồn tham khảo`
88+
- Liệt kê các nguồn theo định dạng **Markdown Link chuẩn**:
89+
`1. [Tên tiêu đề ngắn gọn](URL)`
90+
`2. [Tên tiêu đề ngắn gọn](URL)`
91+
92+
4. **Yêu cầu nội dung**:
9793
- Trả lời thẳng vào vấn đề, giọng văn pháp lý chuyên nghiệp.
98-
- Nếu nhiều nguồn cùng xác nhận một thông tin, hãy gộp số: ví dụ [1, 2].
94+
- Nếu nhiều nguồn cùng xác nhận, hãy gộp số: ví dụ [1, 2].
9995
- Không bịa đặt URL, chỉ dùng URL có trong Context.
10096
10197
-----
10298
VÍ DỤ OUTPUT MONG MUỐN:
103-
Chào bạn, theo quy định tại **Nghị định 100/2019/NĐ-CP** (sửa đổi bởi Nghị định 123/2021), mức phạt cho lỗi vượt đèn đỏ như sau:
99+
Chào bạn, theo quy định tại **Nghị định 100/2019/NĐ-CP**, mức phạt như sau:
104100
105101
### 1. Đối với xe Ô tô
106-
Người điều khiển xe ô tô vượt đèn đỏ sẽ bị phạt tiền từ **4.000.000 đồng đến 6.000.000 đồng** [1]. Ngoài ra, tài xế còn bị tước quyền sử dụng Giấy phép lái xe từ **01 đến 03 tháng** [2].
102+
Phạt tiền từ **4.000.000 đồng đến 6.000.000 đồng** [1]. Ngoài ra bị tước bằng lái 01-03 tháng [2].
107103
108104
### 2. Đối với xe Máy
109105
Mức phạt tiền từ **800.000 đồng đến 1.000.000 đồng** [1].
@@ -184,39 +180,35 @@ def compose_stream(
184180
{graph_context_str}
185181
{web_context_str}
186182
187-
QUY TẮC TRÍCH DẪN & HIỂN THỊ LINK (BẮT BUỘC TUÂN THỦ):
188-
189183
QUY TẮC ĐỊNH DẠNG (MARKDOWN):
190184
1. **Cấu trúc văn bản**:
191185
- Sử dụng **Markdown** để trình bày.
192-
- Dùng dấu `**...**` để **in đậm** những thông tin quan trọng như: số tiền phạt, số năm tù, tên điều luật.
186+
- Dùng dấu `**...**` để **in đậm** những thông tin quan trọng.
193187
- Dùng gạch đầu dòng (`-`) để liệt kê các ý.
194-
- Dùng tiêu đề (`###`) để phân chia các phần (Ví dụ: ### Đối với Ô tô, ### Đối với Xe máy).
195-
196-
2. **Quy tắc trích dẫn**:
197-
- **TUYỆT ĐỐI KHÔNG** chèn trực tiếp URL hay thẻ [[...]] vào giữa dòng.
198-
- Chỉ sử dụng **số thứ tự trong ngoặc vuông** để đánh dấu nguồn minh chứng. Ví dụ: [1], [2], [3].
199-
- Đặt số thứ tự này ở cuối câu hoặc cuối mệnh đề quan trọng.
200-
- Ví dụ đúng: "Mức phạt là 20 triệu đồng [1]."
201-
- Ví dụ sai: "Mức phạt là 20 triệu [[Link...]] đồng."
202-
203-
3. **Phần danh sách nguồn cuối cùng**:
204-
- Bắt buộc tạo một mục riêng ở cuối câu trả lời với tiêu đề: "**NGUỒN THAM KHẢO**".
205-
- Tại mục này, hãy liệt kê chi tiết các nguồn tương ứng với số thứ tự đã đánh dấu ở trên.
206-
- Sử dụng định dạng FE chuẩn cho từng dòng:
207-
**[n] [[Tên Tiêu Đề Ngắn Gọn | URL]]**
208-
209-
3. **Yêu cầu nội dung**:
188+
- Dùng tiêu đề (`###`) để phân chia các phần.
189+
190+
2. **Quy tắc trích dẫn (Footnote)**:
191+
- Trong nội dung bài viết, **TUYỆT ĐỐI KHÔNG** chèn URL.
192+
- Chỉ sử dụng **số thứ tự trong ngoặc vuông** để đánh dấu nguồn. Ví dụ: [1], [2].
193+
- Đặt số thứ tự này ở cuối câu chứa thông tin.
194+
195+
3. **Phần danh sách nguồn cuối cùng (QUAN TRỌNG)**:
196+
- Bắt buộc tạo một mục riêng ở cuối cùng với tiêu đề: `### Nguồn tham khảo`
197+
- Liệt kê các nguồn theo định dạng **Markdown Link chuẩn**:
198+
`1. [Tên tiêu đề ngắn gọn](URL)`
199+
`2. [Tên tiêu đề ngắn gọn](URL)`
200+
201+
4. **Yêu cầu nội dung**:
210202
- Trả lời thẳng vào vấn đề, giọng văn pháp lý chuyên nghiệp.
211-
- Nếu nhiều nguồn cùng xác nhận một thông tin, hãy gộp số: ví dụ [1, 2].
203+
- Nếu nhiều nguồn cùng xác nhận, hãy gộp số: ví dụ [1, 2].
212204
- Không bịa đặt URL, chỉ dùng URL có trong Context.
213205
214206
-----
215207
VÍ DỤ OUTPUT MONG MUỐN:
216-
Chào bạn, theo quy định tại **Nghị định 100/2019/NĐ-CP** (sửa đổi bởi Nghị định 123/2021), mức phạt cho lỗi vượt đèn đỏ như sau:
208+
Chào bạn, theo quy định tại **Nghị định 100/2019/NĐ-CP**, mức phạt như sau:
217209
218210
### 1. Đối với xe Ô tô
219-
Người điều khiển xe ô tô vượt đèn đỏ sẽ bị phạt tiền từ **4.000.000 đồng đến 6.000.000 đồng** [1]. Ngoài ra, tài xế còn bị tước quyền sử dụng Giấy phép lái xe từ **01 đến 03 tháng** [2].
211+
Phạt tiền từ **4.000.000 đồng đến 6.000.000 đồng** [1]. Ngoài ra bị tước bằng lái 01-03 tháng [2].
220212
221213
### 2. Đối với xe Máy
222214
Mức phạt tiền từ **800.000 đồng đến 1.000.000 đồng** [1].

ai_service/app/services/streaming_service.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
import asyncio
55
import logging
6+
import re
67
from typing import AsyncGenerator
78
from ..utils.stream_utils import create_tool_thought, create_content_chunk, AgentTool
89

@@ -19,6 +20,14 @@
1920
class StreamingService:
2021
"""Service for handling streaming responses"""
2122

23+
@staticmethod
24+
async def _perform_web_search(question: str) -> tuple[str, int]:
25+
"""Helper function to perform web search and return context with reference count"""
26+
ws = WebSearchService()
27+
web_context = await asyncio.to_thread(ws.search, question)
28+
reference_count = len(re.findall(r'Link:\s*https?://[^\s\n]+', web_context))
29+
return web_context, reference_count
30+
2231
@staticmethod
2332
async def generate_streaming_response(question: str, is_debug: bool = False) -> AsyncGenerator[str, None]:
2433
"""
@@ -59,8 +68,9 @@ async def generate_streaming_response(question: str, is_debug: bool = False) ->
5968
if category == 'WEBSITE_SEARCH':
6069
yield create_tool_thought(AgentTool.WEB_SEARCH)
6170
log.info("Direct Web Search - skipping vector/graph search")
62-
ws = WebSearchService()
63-
web_context = await asyncio.to_thread(ws.search, question)
71+
web_context, reference_count = await StreamingService._perform_web_search(question)
72+
yield create_tool_thought(AgentTool.WEB_SEARCH, f"Số lượng website cung cấp thông tin tham khảo: {reference_count}")
73+
6474
yield create_tool_thought(AgentTool.CONCLUSION)
6575
composer = AnswerComposerService()
6676

@@ -98,8 +108,8 @@ async def generate_streaming_response(question: str, is_debug: bool = False) ->
98108
if not final_choice:
99109
yield create_tool_thought(AgentTool.WEB_SEARCH)
100110
log.info("Triggering Web Search...")
101-
ws = WebSearchService()
102-
web_context = await asyncio.to_thread(ws.search, question)
111+
web_context, reference_count = await StreamingService._perform_web_search(question)
112+
yield create_tool_thought(AgentTool.WEB_SEARCH, f"Số lượng website cung cấp thông tin tham khảo: {reference_count}")
103113

104114
# 6. Compose
105115
yield create_tool_thought(AgentTool.CONCLUSION)

ai_service/app/utils/stream_utils.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
AgentTool.FALLBACK: "Đang tìm phương án trả lời thay thế..."
1515
}
1616

17-
def create_tool_thought(tool_name: str) -> str:
17+
def create_tool_thought(tool_name: str, content: str = None) -> str:
1818
"""
19-
Tạo ra một SSE string cho 'thought' dựa trên tên tool.
19+
Tạo ra một SSE string cho 'thought' dựa trên tên tool và nội dung (nếu có).
2020
Input: "WebSearch"
2121
Output: data: {"type": "thought", "data": "Đang tìm kiếm...", ...}\n\n
2222
"""
2323
# Lấy nội dung thân thiện, nếu không có thì dùng mặc định
24-
content = TOOL_DESCRIPTIONS.get(tool_name, f"Đang xử lý tác vụ: {tool_name}...")
24+
if content is None:
25+
content = TOOL_DESCRIPTIONS.get(tool_name, f"Đang xử lý tác vụ: {tool_name}...")
2526

2627
chunk = StreamingChunk(
2728
type="thought",

0 commit comments

Comments
 (0)