diff --git a/literature.html b/literature.html
index 3fcb32c..36101be 100644
--- a/literature.html
+++ b/literature.html
@@ -654,70 +654,78 @@
// Get analysis status and results for each literature
references.forEach(async (ref) => {
try {
- const analysisResponse = await fetch(`${API_BASE_URL}/references/${ref._id}/report`, {
- headers: {
- 'Authorization': `Bearer ${token}`
- }
- });
-
- if (!analysisResponse.ok) {
- throw new Error('Failed to fetch analysis');
- }
-
- const analysisResult = await analysisResponse.json();
- const contentElement = document.querySelector(`.analysis-content-${ref._id}`);
- const statusElement = document.querySelector(`.analysis-status-${ref._id}`);
-
- if (analysisResult.status === 'processing') {
- // Processing status
- contentElement.innerHTML = `
-
-
- Loading...
-
-
Analyzing literature content...
-
- `;
- statusElement.innerHTML = 'Analysis in progress...';
- } else if (analysisResult.status === 'completed') {
- // Completed status
- let author = 'N/A';
- let publicationDate = 'N/A';
- let journal = 'N/A';
-
- try {
- if (analysisResult['1. Basic Information']) {
- const basicInfo = analysisResult['1. Basic Information'];
- author = basicInfo.author || 'N/A';
- publicationDate = basicInfo.publication_date || 'N/A';
- journal = basicInfo.journal_publisher || 'N/A';
-
- // 更新卡片标题为分析结果中的标题
- const titleElement = document.querySelector(`#reference-${ref._id} .card-title`);
- if (titleElement && basicInfo.title) {
- titleElement.textContent = basicInfo.title;
- }
+ const checkAnalysisStatus = async () => {
+ const analysisResponse = await fetch(`${API_BASE_URL}/references/${ref._id}/report`, {
+ headers: {
+ 'Authorization': `Bearer ${token}`
}
-
- contentElement.innerHTML = `
- Author: ${author}
- Publication Date: ${publicationDate}
- Journal/Publisher: ${journal}
- `;
- statusElement.innerHTML = 'Analysis completed';
- } catch (parseError) {
- console.error('Failed to parse analysis result:', parseError);
+ });
+
+ if (!analysisResponse.ok) {
+ throw new Error('Failed to fetch analysis');
}
- } else if (analysisResult.status === 'failed') {
- // Failed status
- contentElement.innerHTML = `
-
-
- Analysis failed
-
- `;
- statusElement.innerHTML = `Analysis failed: ${analysisResult.message || 'Unknown error'}`;
- }
+
+ const analysisResult = await analysisResponse.json();
+ const contentElement = document.querySelector(`.analysis-content-${ref._id}`);
+ const statusElement = document.querySelector(`.analysis-status-${ref._id}`);
+
+ if (analysisResult.status === 'processing') {
+ // Processing status
+ contentElement.innerHTML = `
+
+
+ Loading...
+
+
Analyzing literature content...
+
+ `;
+ statusElement.innerHTML = 'Analysis in progress...';
+
+ // 如果还在处理中,5秒后再次检查
+ setTimeout(checkAnalysisStatus, 10000);
+ } else if (analysisResult.status === 'completed') {
+ // Completed status
+ let author = 'N/A';
+ let publicationDate = 'N/A';
+ let journal = 'N/A';
+
+ try {
+ if (analysisResult['1. Basic Information']) {
+ const basicInfo = analysisResult['1. Basic Information'];
+ author = basicInfo.author || 'N/A';
+ publicationDate = basicInfo.publication_date || 'N/A';
+ journal = basicInfo.journal_publisher || 'N/A';
+
+ // 更新卡片标题为分析结果中的标题
+ const titleElement = document.querySelector(`#reference-${ref._id} .card-title`);
+ if (titleElement && basicInfo.title) {
+ titleElement.textContent = basicInfo.title;
+ }
+ }
+
+ contentElement.innerHTML = `
+ Author: ${author}
+ Publication Date: ${publicationDate}
+ Journal/Publisher: ${journal}
+ `;
+ statusElement.innerHTML = 'Analysis completed';
+ } catch (parseError) {
+ console.error('Failed to parse analysis result:', parseError);
+ }
+ } else if (analysisResult.status === 'failed') {
+ // Failed status
+ contentElement.innerHTML = `
+
+
+ Analysis failed
+
+ `;
+ statusElement.innerHTML = `Analysis failed: ${analysisResult.message || 'Unknown error'}`;
+ }
+ };
+
+ // 开始首次检查
+ await checkAnalysisStatus();
} catch (error) {
console.error(`Failed to fetch analysis for reference ${ref._id}:`, error);
const contentElement = document.querySelector(`.analysis-content-${ref._id}`);
diff --git a/main.py b/main.py
index b6894dd..19da826 100644
--- a/main.py
+++ b/main.py
@@ -1648,71 +1648,7 @@ async def analyze_project_data(project_data):
print(f"Error calling DeepSeek API: {e}")
return None
-async def analyze_reference_document_async(content: str):
- """分析文献的基本信息和内容"""
- system_prompt = """
- You are an AI assistant tasked with analyzing academic literature.
- Generate a comprehensive analysis in JSON format covering both basic information and content analysis.
- The JSON structure must strictly follow the provided template.
- """
-
- user_prompt = f"""Analyze the following literature and extract all relevant information:
- Content: {content}
- Generate a JSON response with the following structure:
-
- {{
- "1. Basic Information": {{
- "author": "[Author name(s) and affiliations]",
- "publication_date": "[Publication date in YYYY-MM format]",
- "title": "[Full title of the document]",
- "journal_publisher": "[Journal name or publisher details]",
- "document_type": "[Type: journal article/book/conference paper etc.]"
- }},
- "2. Content Analysis": {{
- "abstract": "[Paper abstract]",
- "research_purpose": "[Main objectives and research questions]",
- "methodology": "[Research methods, data collection and analysis approaches]",
- "main_arguments": "[Key theoretical frameworks and arguments]",
- "conclusions": "[Primary findings and conclusions]",
- "innovations": "[Novel contributions and original aspects]"
- }}
- }}
- """
-
- return await call_deepseek_api_async([
- {"role": "system", "content": system_prompt},
- {"role": "user", "content": user_prompt}
- ])
-
-async def analyze_reference_value_async(content_analysis: dict):
- """基于内容分析结果评估文献的价值"""
- system_prompt = """
- You are an AI assistant tasked with evaluating the value of academic literature based on its content analysis.
- Generate a comprehensive value evaluation in JSON format.
- The JSON structure must strictly follow the provided template.
- """
-
- user_prompt = f"""Based on the following content analysis, evaluate the literature's value:
- Content Analysis: {json.dumps(content_analysis, ensure_ascii=False)}
-
- Generate a JSON response with the following structure:
-
- {{
- "3. Value Evaluation": {{
- "academic_contribution": "[Significance to the field of study]",
- "practical_significance": "[Real-world applications and implications]",
- "limitations": "[Research constraints and weaknesses]",
- "implications": "[Suggestions for future research and practice]"
- }}
- }}
- """
-
- return await call_deepseek_api_async([
- {"role": "system", "content": system_prompt},
- {"role": "user", "content": user_prompt}
- ])
-
# 修改函数定义为异步函数
async def analyze_reference_summary(reference_data):
system_prompt = """
@@ -2810,25 +2746,72 @@ async def process_batch_analysis(references: List[dict]):
print(f"Reference file not found: {file_path}")
return
+ print(f"\n开始处理文献 {ref.get('reference_title', '未知标题')}")
+ print(f"文献ID: {reference_id}")
+ print(f"文件路径: {file_path}")
+
# 异步读取PDF
+ print("\n=== 步骤1: 读取PDF文件 ===")
pdf_content = await read_pdf_async(file_path)
if not pdf_content:
raise Exception("Failed to read PDF content")
- # 异步分析文档
- document_analysis = await analyze_reference_document_async(pdf_content)
- if not document_analysis:
- raise Exception("Failed to analyze document")
+ # 打印字符数
+ content_length = len(pdf_content)
+ print(f"\n=== 步骤2: 内容长度检查 ===")
+ print(f"PDF内容总字符数: {content_length}")
+
+ # 根据内容长度选择不同的处理方式
+ if content_length <= 200000:
+ print(f"\n=== 步骤3A: 使用直接分析方式 ===")
+ print(f"文档长度在处理范围内 ({content_length} <= 200000)")
+ # 直接分析文档内容
+ print("开始分析文档内容...")
+ document_analysis = await analyze_reference_document_async(pdf_content[:180000])
+ if not document_analysis:
+ raise Exception("Failed to analyze document")
+ print("文档分析完成")
+ else:
+ print(f"\n=== 步骤3B: 使用分段分析方式 ===")
+ print(f"文档超过200000字符 ({content_length} > 200000)")
+ # 分段分析长文档
+ print("\n--- 开始分段分析 ---")
+ print("正在调用 analyze_long_document_async...")
+ try:
+ analysis_results = await analyze_long_document_async(pdf_content)
+ except Exception as e:
+ print(f"分段分析过程中出错: {str(e)}")
+ raise
+
+ if not analysis_results:
+ raise Exception("Failed to analyze document in segments")
+ print(f"分段分析完成,共分析了 {len(analysis_results)} 个段落")
+
+ # 合并分析结果
+ try:
+ document_analysis = await merge_analysis_results(analysis_results)
+ except Exception as e:
+ raise
+
+ if not document_analysis:
+ raise Exception("Failed to merge analysis results")
# 等待一小段时间避免API限制
await asyncio.sleep(1)
- # 异步分析价值
- value_evaluation = await analyze_reference_value_async(document_analysis)
+ # 异步分析文献价值
+ try:
+ value_evaluation = await analyze_reference_value_async(document_analysis)
+ print(f"analyze_reference_value_async 返回结果类型: {type(value_evaluation)}")
+ except Exception as e:
+ raise
+
if not value_evaluation:
raise Exception("Failed to evaluate value")
+ print("文献价值分析完成")
# 合并结果
+ print("\n=== 步骤5: 保存最终结果 ===")
analysis_result = {
**document_analysis,
**value_evaluation,
@@ -2841,7 +2824,6 @@ async def process_batch_analysis(references: List[dict]):
await redis.set(report_key, json.dumps(analysis_result))
except Exception as e:
- print(f"Error processing reference {ref['reference_id']}: {str(e)}")
try:
await redis.select(203)
report_key = f"reference_report:{ref['reference_id']}"
@@ -2884,7 +2866,21 @@ async def read_pdf_async(file_path: str) -> str:
for page in pdf_reader.pages:
content = page.extract_text()
pdf_content += content
- return pdf_content[:180000] # 限制内容长度
+
+ # 根据内容长度返回不同的结果
+ content_length = len(pdf_content)
+ print(f"\nPDF原始内容字符数: {content_length}")
+
+ if content_length <= 180000:
+ print("文档长度 ≤ 180000,返回完整内容")
+ return pdf_content
+ elif content_length <= 200000:
+ print("文档长度在 180000-200000 之间,截取前 180000 个字符")
+ return pdf_content[:180000]
+ else:
+ print("文档长度 > 200000,返回完整内容供分段处理")
+ return pdf_content # 返回完整内容,由调用者处理分段
+
except Exception as e:
print(f"Error reading PDF: {e}")
return ""
@@ -2906,62 +2902,191 @@ async def call_deepseek_api_async(messages: list) -> dict:
else:
raise Exception(f"API调用失败: {await response.text()}")
-async def process_reference_analysis(reference_id: str, reference: dict):
- """后台处理文献分析"""
- redis = await get_redis()
+async def analyze_long_document_async(content: str) -> List[dict]:
+ """分段分析长文档"""
+ # 将内容分成多个段落,每段约60000个字符(估算后约50000 tokens)
+ segments = []
+ content_length = len(content)
+ segment_size = 60000 # 减小段落大小
- try:
- file_path = reference.get("reference_link")
- if not file_path or not os.path.exists(file_path):
- print(f"Reference file not found: {file_path}")
- return
-
- # 异步读取PDF
- pdf_content = await read_pdf_async(file_path)
- if not pdf_content:
- raise Exception("Failed to read PDF content")
+ print(f"\n开始分段处理,总字符数: {content_length}")
+ print(f"每段大小: {segment_size} 字符")
+
+ for i in range(0, content_length, segment_size):
+ segment = content[i:i + segment_size]
+ segments.append(segment)
+
+ print(f"文档已分段,共 {len(segments)} 个段落")
+
+ # 对每个段落进行分析
+ analysis_results = []
+ for i, segment in enumerate(segments):
+ print(f"\n开始分析第 {i+1}/{len(segments)} 个段落...")
- # 异步分析文档内容
- document_analysis = await analyze_reference_document_async(pdf_content)
- if not document_analysis:
- print("Failed to analyze document")
- return
-
- # 异步分析文献价值
- value_evaluation = await analyze_reference_value_async(document_analysis)
- if not value_evaluation:
- print("Failed to evaluate value")
- return
-
- # 合并分析结果
- analysis_result = {
- **document_analysis,
- **value_evaluation
- }
+ system_prompt = f"""
+ You are an AI assistant tasked with analyzing part {i+1} of {len(segments)} of an academic literature.
+ Generate a comprehensive analysis in JSON format covering both basic information and content analysis.
+ Note that this is part {i+1} of a longer document, so focus on the content provided.
+ The JSON structure must strictly follow the provided template.
+ """
+
+ user_prompt = f"""Analyze the following literature segment and extract all relevant information:
+ Content: {segment}
- # 保存分析结果到db203
- await redis.select(203)
- report_key = f"reference_report:{reference_id}"
- await redis.set(report_key, json.dumps(analysis_result))
+ Generate a JSON response with the following structure:
+
+ {{
+ "1. Basic Information": {{
+ "author": "[Author name(s) and affiliations]",
+ "publication_date": "[Publication date in YYYY-MM format]",
+ "title": "[Full title of the document]",
+ "journal_publisher": "[Journal name or publisher details]",
+ "document_type": "[Type: journal article/book/conference paper etc.]"
+ }},
+ "2. Content Analysis": {{
+ "abstract": "[Paper abstract]",
+ "research_purpose": "[Main objectives and research questions]",
+ "methodology": "[Research methods, data collection and analysis approaches]",
+ "main_arguments": "[Key theoretical frameworks and arguments]",
+ "conclusions": "[Primary findings and conclusions]",
+ "innovations": "[Novel contributions and original aspects]"
+ }}
+ }}
+ """
- except Exception as e:
- print(f"Error analyzing reference data: {str(e)}")
try:
- await redis.select(203)
- report_key = f"reference_report:{reference_id}"
- error_status = {
- "status": "failed",
- "message": str(e)
- }
- await redis.set(report_key, json.dumps(error_status))
- except Exception as redis_error:
- print(f"Error updating Redis status: {redis_error}")
- finally:
- try:
- await redis.aclose()
+ result = await call_deepseek_api_async([
+ {"role": "system", "content": system_prompt},
+ {"role": "user", "content": user_prompt}
+ ])
+
+ if result:
+ print(f"第 {i+1} 个段落分析完成")
+ analysis_results.append(result)
+ # 等待一小段时间避免API限制
+ await asyncio.sleep(1)
+ else:
+ print(f"第 {i+1} 个段落分析失败")
except Exception as e:
- print(f"Error closing Redis connection: {e}")
+ print(f"分析段落时出错: {str(e)}")
+ continue
+
+ return analysis_results
+async def merge_analysis_results(results: List[dict]) -> dict:
+ """合并多个分析结果"""
+ if not results:
+ return {}
+
+ print(f"开始合并 {len(results)} 个分析结果...")
+
+ system_prompt = """
+ You are an AI assistant tasked with merging multiple analysis results of different parts of the same academic literature.
+ Generate a comprehensive merged analysis in JSON format.
+ The JSON structure must strictly follow the provided template.
+ Ensure the merged result is coherent and eliminates redundancy.
+ """
+
+ user_prompt = f"""Merge the following analysis results into a single coherent analysis:
+ Analysis Results: {json.dumps(results, ensure_ascii=False)}
+
+ Generate a JSON response with the following structure:
+
+ {{
+ "1. Basic Information": {{
+ "author": "[Merged author information]",
+ "publication_date": "[Publication date]",
+ "title": "[Complete title]",
+ "journal_publisher": "[Journal/publisher information]",
+ "document_type": "[Document type]"
+ }},
+ "2. Content Analysis": {{
+ "abstract": "[Complete abstract]",
+ "research_purpose": "[Comprehensive research objectives]",
+ "methodology": "[Complete methodology description]",
+ "main_arguments": "[Comprehensive theoretical frameworks and arguments]",
+ "conclusions": "[Complete findings and conclusions]",
+ "innovations": "[Complete list of innovations]"
+ }}
+ }}
+ """
+
+ result = await call_deepseek_api_async([
+ {"role": "system", "content": system_prompt},
+ {"role": "user", "content": user_prompt}
+ ])
+
+ if result:
+ print("分析结果合并完成")
+ else:
+ print("分析结果合并失败")
+
+ return result
+async def analyze_reference_document_async(content: str):
+ """分析文献的基本信息和内容"""
+ system_prompt = """
+ You are an AI assistant tasked with analyzing academic literature.
+ Generate a comprehensive analysis in JSON format covering both basic information and content analysis.
+ The JSON structure must strictly follow the provided template.
+ """
+
+ user_prompt = f"""Analyze the following literature and extract all relevant information:
+ Content: {content}
+
+ Generate a JSON response with the following structure:
+
+ {{
+ "1. Basic Information": {{
+ "author": "[Author name(s) and affiliations]",
+ "publication_date": "[Publication date in YYYY-MM format]",
+ "title": "[Full title of the document]",
+ "journal_publisher": "[Journal name or publisher details]",
+ "document_type": "[Type: journal article/book/conference paper etc.]"
+ }},
+ "2. Content Analysis": {{
+ "abstract": "[Paper abstract]",
+ "research_purpose": "[Main objectives and research questions]",
+ "methodology": "[Research methods, data collection and analysis approaches]",
+ "main_arguments": "[Key theoretical frameworks and arguments]",
+ "conclusions": "[Primary findings and conclusions]",
+ "innovations": "[Novel contributions and original aspects]"
+ }}
+ }}
+ """
+
+ return await call_deepseek_api_async([
+ {"role": "system", "content": system_prompt},
+ {"role": "user", "content": user_prompt}
+ ])
+
+async def analyze_reference_value_async(content_analysis: dict):
+ """基于内容分析结果评估文献的价值"""
+ system_prompt = """
+ You are an AI assistant tasked with evaluating the value of academic literature based on its content analysis.
+ Generate a comprehensive value evaluation in JSON format.
+ The JSON structure must strictly follow the provided template.
+ """
+
+ user_prompt = f"""Based on the following content analysis, evaluate the literature's value:
+ Content Analysis: {json.dumps(content_analysis, ensure_ascii=False)}
+
+ Generate a JSON response with the following structure:
+
+ {{
+ "3. Value Evaluation": {{
+ "academic_contribution": "[Significance to the field of study]",
+ "practical_significance": "[Real-world applications and implications]",
+ "limitations": "[Research constraints and weaknesses]",
+ "implications": "[Suggestions for future research and practice]"
+ }}
+ }}
+ """
+
+ return await call_deepseek_api_async([
+ {"role": "system", "content": system_prompt},
+ {"role": "user", "content": user_prompt}
+ ])
+
if __name__ == "__main__":
import uvicorn
- uvicorn.run(app, host="0.0.0.0", port=6000)
\ No newline at end of file
+ uvicorn.run(app, host="0.0.0.0", port=6000)