Browse Source

fix: 修复main.py网页查询缺失max_iter的问题

test: 暂时移除前端最后报告输出
chore: 优化提示词
main
tanxing 6 days ago
parent
commit
5742170b51
  1. 56
      deepsearcher/agent/deep_search.py
  2. 51
      deepsearcher/backend/templates/index.html
  3. 3
      deepsearcher/llm/openai_llm.py
  4. 8
      deepsearcher/online_query.py
  5. 11
      main.py

56
deepsearcher/agent/deep_search.py

@ -12,8 +12,8 @@ COLLECTION_ROUTE_PROMPT = """
请你选择可能与问题相关的合集名称并返回一个字符串列表 请你选择可能与问题相关的合集名称并返回一个字符串列表
如果没有相关合集请返回一个空列表 如果没有相关合集请返回一个空列表
"Query": {query} "问题": {query}
"COLLECTION_INFO": {collection_info} "合集信息": {collection_info}
使用的语言与问题相同 使用的语言与问题相同
你需要返回的格式是 a python list of str without any addtional content: 你需要返回的格式是 a python list of str without any addtional content:
@ -25,18 +25,18 @@ SUB_QUERY_PROMPT = """
如果原问题本身非常简单没有必要进行拆分则保留输出原问题本身 如果原问题本身非常简单没有必要进行拆分则保留输出原问题本身
需要保证每个子问题都具体清晰不可分原子性最终返回一个字符串列表 需要保证每个子问题都具体清晰不可分原子性最终返回一个字符串列表
Original Question: {original_query} 原问题: {original_query}
<EXAMPLE> <EXAMPLE>
示例输入: 示例输入:
"Explain deep learning" "请解释机器学习"
示例输出: 示例输出例子中的数量不是要求:
[ [
"What is deep learning?", "什么是机器学习?",
"What is deep learning's purpose?", "机器学习的使用目的是什么?",
"What is the difference between deep learning and machine learning?", "机器学习和深度学习的区别是什么?",
"What is the history of deep learning?" "机器学习的历史演进过程?"
] ]
</EXAMPLE> </EXAMPLE>
@ -47,15 +47,16 @@ Original Question: {original_query}
RERANK_PROMPT = """ RERANK_PROMPT = """
根据当前的问题和获取到的文档片段请你对当前获取到的文档是否能帮助回答这个问题给出一个快速判断 根据当前的问题和获取到的文档片段
对于每一个文档片段你只应该返回"YES"或者"NO" 请你对当前获取到的文档是否能帮助回答这个问题直接或间接全面或部分都可以给出一个快速判断
对于每一个文档片段你只应该返回"YES"或者"NO"需要注意顺序和数量
Query: {query} 问题: {query}
Retrieved Chunks: 检索到的文档片段:
{chunks} {chunks}
例如对于4个chunks返回: ["YES", "NO", "YES", "YES"] 例如给定4个chunks实际检索到的文档片段不一定是4个返回: ["YES", "NO", "YES", "YES"]
使用的语言与问题相同 使用的语言与问题相同
你需要返回的是 a python list of str without any addtional content: 你需要返回的是 a python list of str without any addtional content:
""" """
@ -67,11 +68,11 @@ REFLECT_PROMPT = """
你可以尝试生成相似但些许不同的问题来尝试重新检索但是也可以根据获得到的文档片段进行批评思考生成新的问题来保证原问题的回答的准确和全面 你可以尝试生成相似但些许不同的问题来尝试重新检索但是也可以根据获得到的文档片段进行批评思考生成新的问题来保证原问题的回答的准确和全面
如果没有真的必要继续研究取决于你的判断返回一个空列表 如果没有真的必要继续研究取决于你的判断返回一个空列表
Original Query: {original_query} 原问题: {original_query}
Previous Sub Queries: {all_sub_queries} 子问题: {all_sub_queries}
Related Chunks: 检索到的文档片段:
{chunks} {chunks}
使用的语言与原问题相同 使用的语言与原问题相同
@ -91,23 +92,20 @@ SUMMARY_PROMPT = """
<EXAMPLE> <EXAMPLE>
文内引用示例使用markdown和html的混合语法格式必须和例子一致: 文内引用示例使用markdown和html的混合语法格式必须和例子一致:
"XGBoost is a powerful ensemble learning method [<sup>[2]</sup>](#2)" "XGBoost是非常强大的集成学习模型[<sup>[2]</sup>](#2)"
(必须使用 "[<sup>[index]</sup>](#index)" 而不是 "[index]"注意不要遗漏"(#index)") (必须使用 "[<sup>[index]</sup>](#index)" 而不是 "[index]"注意不要遗漏"(#index)"这里的index是chunk对应的reference的id)
文末参考资料列表 (超链接必须和href属性一致不允许简化): 文末引用示例 (需要href与前文参考中的一致不需要对每个chunk分配一个引用而是每一个referecen共用一个引用):
前文输入
<reference id="2" href="href="files/docs/chap_001_003_models.md"><chunk id="1">...</chunk></reference>
参考输出
<div id="2"><a href="files/docs/chap_001_003_models.md" style="text-decoration: none;>[2] chap_001_models.md</a></div> <div id="2"><a href="files/docs/chap_001_003_models.md" style="text-decoration: none;>[2] chap_001_models.md</a></div>
</EXAMPLE> </EXAMPLE>
问题: {original_query} 原问题: {original_query}
已经拆分出的子问题: {all_sub_queries} 子问题: {all_sub_queries}
相关片段: 检索到的文档片段:
{chunks} {chunks}
注意你需要使用与原始问题的相同的语言来回答 注意你需要使用与原始问题的相同的语言来回答
@ -175,7 +173,7 @@ class DeepSearch(BaseAgent):
collection_infos = self.vector_db.list_collections(dim=dim) collection_infos = self.vector_db.list_collections(dim=dim)
if len(collection_infos) == 0: if len(collection_infos) == 0:
log.color_print( log.color_print(
"数据库中没有找到任何合集!" "No collection found in the vector database!"
) )
return [] return []
if len(collection_infos) == 1: if len(collection_infos) == 1:
@ -421,9 +419,9 @@ class DeepSearch(BaseAgent):
chunks = [] chunks = []
chunk_count = 0 chunk_count = 0
for i, reference in enumerate(references): for i, reference in enumerate(references):
formated = f"<reference id='{i}' href='{reference}'>\n" + "".join( formated = f"<reference id='{i + 1}' href='{reference}'>\n" + "".join(
[ [
f"<chunk id='{j + chunk_count}'>\n{chunk}\n</chunk>\n" f"<chunk id='{j + 1 + chunk_count}'>\n{chunk}\n</chunk>\n"
for j, chunk in enumerate(references[reference]) for j, chunk in enumerate(references[reference])
] ]
) + "</reference>\n" ) + "</reference>\n"

51
deepsearcher/backend/templates/index.html

@ -192,29 +192,6 @@
line-height: 1.6; line-height: 1.6;
} }
/* 进度日志样式 */
.progress-log {
background-color: #1e1e1e;
color: #d4d4d4;
border-radius: 6px;
padding: 16px;
font-family: 'Courier New', monospace;
font-size: 14px;
margin: 16px 0;
max-height: 300px;
overflow-y: auto;
display: none;
}
.progress-log.visible {
display: block;
}
.progress-log-entry {
margin: 4px 0;
line-height: 1.4;
}
footer { footer {
text-align: center; text-align: center;
margin-top: 30px; margin-top: 30px;
@ -291,9 +268,6 @@
<button id="queryBtn">执行查询</button> <button id="queryBtn">执行查询</button>
<div id="queryStatus" class="status"></div> <div id="queryStatus" class="status"></div>
<!-- 进度日志显示区域 -->
<div id="progressLog" class="progress-log"></div>
<div id="queryResult" class="result-container"> <div id="queryResult" class="result-container">
<h3>查询结果:</h3> <h3>查询结果:</h3>
<div class="query-result" id="resultText"></div> <div class="query-result" id="resultText"></div>
@ -346,25 +320,6 @@
resultElement.classList.remove('visible'); resultElement.classList.remove('visible');
} }
// 工具函数:显示进度日志
function showProgressLog(messages) {
const logElement = document.getElementById('progressLog');
if (messages && messages.length > 0) {
logElement.innerHTML = messages.map(msg =>
`<div class="progress-log-entry">${escapeHtml(msg)}</div>`
).join('');
logElement.classList.add('visible');
} else {
logElement.classList.remove('visible');
}
}
// 工具函数:隐藏进度日志
function hideProgressLog() {
const logElement = document.getElementById('progressLog');
logElement.classList.remove('visible');
}
// 工具函数:转义HTML特殊字符 // 工具函数:转义HTML特殊字符
function escapeHtml(text) { function escapeHtml(text) {
const map = { const map = {
@ -405,7 +360,6 @@
setButtonLoading(button, true); setButtonLoading(button, true);
showStatus('loadStatus', '正在加载文件...', 'loading'); showStatus('loadStatus', '正在加载文件...', 'loading');
hideResult(); hideResult();
hideProgressLog();
try { try {
const response = await fetch('/load-files/', { const response = await fetch('/load-files/', {
@ -451,7 +405,6 @@
setButtonLoading(button, true); setButtonLoading(button, true);
showStatus('webLoadStatus', '正在加载网站内容...', 'loading'); showStatus('webLoadStatus', '正在加载网站内容...', 'loading');
hideResult(); hideResult();
hideProgressLog();
try { try {
const response = await fetch('/load-website/', { const response = await fetch('/load-website/', {
@ -499,7 +452,6 @@
setButtonLoading(button, true); setButtonLoading(button, true);
showStatus('queryStatus', '正在处理查询...', 'loading'); showStatus('queryStatus', '正在处理查询...', 'loading');
hideResult(); hideResult();
hideProgressLog();
try { try {
const response = await fetch(`/query/?original_query=${encodeURIComponent(queryText)}&max_iter=${maxIter}`, { const response = await fetch(`/query/?original_query=${encodeURIComponent(queryText)}&max_iter=${maxIter}`, {
@ -515,9 +467,6 @@
showStatus('queryStatus', '查询完成', 'success'); showStatus('queryStatus', '查询完成', 'success');
document.getElementById('resultText').textContent = data.result; document.getElementById('resultText').textContent = data.result;
showResult(); showResult();
// 显示进度日志
showProgressLog(data.progress_messages);
} else { } else {
showStatus('queryStatus', `查询失败: ${data.detail}`, 'error'); showStatus('queryStatus', `查询失败: ${data.detail}`, 'error');
} }

3
deepsearcher/llm/openai_llm.py

@ -50,6 +50,7 @@ class OpenAILLM(BaseLLM):
stream=True, stream=True,
temperature=0.6 temperature=0.6
) as stream: ) as stream:
# stream仅做测试,不需要发送到前端
content = "" content = ""
reasoning_content = "" reasoning_content = ""
for chunk in stream: for chunk in stream:
@ -63,5 +64,5 @@ class OpenAILLM(BaseLLM):
if hasattr(delta, 'content') and delta.content is not None: if hasattr(delta, 'content') and delta.content is not None:
print(delta.content, end="", flush=True) print(delta.content, end="", flush=True)
content += delta.content content += delta.content
print("\n") print("\n")
return content return content

8
deepsearcher/online_query.py

@ -3,7 +3,7 @@ from deepsearcher import configuration
from deepsearcher.vector_db.base import RetrievalResult from deepsearcher.vector_db.base import RetrievalResult
def query(original_query: str) -> tuple[str, list[RetrievalResult]]: def query(original_query: str, max_iter: int | None = None) -> tuple[str, list[RetrievalResult]]:
""" """
Query the knowledge base with a question and get an answer. Query the knowledge base with a question and get an answer.
@ -20,10 +20,10 @@ def query(original_query: str) -> tuple[str, list[RetrievalResult]]:
- A list of retrieval results that were used to generate the answer - A list of retrieval results that were used to generate the answer
""" """
default_searcher = configuration.default_searcher default_searcher = configuration.default_searcher
return default_searcher.query(original_query) return default_searcher.query(original_query, max_iter=max_iter)
def retrieve(original_query: str) -> tuple[list[RetrievalResult], list[str]]: def retrieve(original_query: str, max_iter: int | None = None) -> tuple[list[RetrievalResult], list[str]]:
""" """
Retrieve relevant information from the knowledge base without generating an answer. Retrieve relevant information from the knowledge base without generating an answer.
@ -40,5 +40,5 @@ def retrieve(original_query: str) -> tuple[list[RetrievalResult], list[str]]:
- A list of strings representing consumed tokens - A list of strings representing consumed tokens
""" """
default_searcher = configuration.default_searcher default_searcher = configuration.default_searcher
retrieved_results, metadata = default_searcher.retrieve(original_query) retrieved_results, metadata = default_searcher.retrieve(original_query, max_iter=max_iter)
return retrieved_results return retrieved_results

11
main.py

@ -203,19 +203,10 @@ def perform_query(
HTTPException: If the query fails. HTTPException: If the query fails.
""" """
try: try:
# 清除之前的进度消息
from deepsearcher.utils.log import clear_progress_messages
clear_progress_messages()
result_text, _ = query(original_query, max_iter) result_text, _ = query(original_query, max_iter)
# 获取进度消息
from deepsearcher.utils.log import get_progress_messages
progress_messages = get_progress_messages()
return { return {
"result": result_text, "result": result_text
"progress_messages": progress_messages
} }
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))

Loading…
Cancel
Save