# deepdeek_document_processor.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
文档智能处理器 - DeepSeek版本
支持长文档摘要、公文润色、关键点提取等功能
"""

import json
import re
from typing import Dict, List, Optional, Union, Any
from datetime import datetime


class DeepSeekDocumentProcessor:
    def __init__(self, api_key: str, model: str = "deepseek-chat"):
        """
        初始化DeepSeek文档处理器
        
        Args:
            api_key: DeepSeek API密钥
            model: 模型名称,deepseek-chat 或 deepseek-reasoner
        """
        self.api_key = api_key
        self.model = model
        self.base_url = "https://api.deepseek.com"
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        # 统计信息
        self.total_tokens = 0
        self.total_requests = 0
        self.processed_docs = 0
    
    def _call_api(self, prompt: str, temperature: float = 0.3, 
                  max_tokens: int = 2000) -> str:
        """
        调用DeepSeek API的核心方法
        
        Args:
            prompt: 提示词
            temperature: 温度参数
            max_tokens: 最大输出token数
            
        Returns:
            str: API返回的内容
        """
        import requests
        
        payload = {
            "model": self.model,
            "messages": [
                {"role": "system", "content": "你是一位专业的文档处理专家,擅长文本摘要、润色、信息提取等工作,输出准确、规范、结构化。"},
                {"role": "user", "content": prompt}
            ],
            "temperature": temperature,
            "max_tokens": max_tokens,
            "stream": False
        }
        
        try:
            response = requests.post(
                f"{self.base_url}/chat/completions",
                headers=self.headers,
                json=payload,
                timeout=120  # 长文档处理需要更长时间
            )
            response.raise_for_status()
            result = response.json()
            
            # 统计token使用
            if 'usage' in result:
                self.total_tokens += result['usage']['total_tokens']
                self.total_requests += 1
            
            return result['choices'][0]['message']['content']
            
        except Exception as e:
            return f"API调用失败: {str(e)}"
    
    def summarize_long_document(self, text: str, max_length: int = 300, 
                                style: str = "结构化", extract_quotes: bool = False) -> Dict[str, Any]:
        """
        长文档摘要(增强版)
        
        Args:
            text: 文档内容
            max_length: 摘要最大字数
            style: 摘要风格("结构化"、"简洁"、"详细")
            extract_quotes: 是否提取关键引用
            
        Returns:
            Dict: 包含摘要、关键信息、引用等
        """
        # 处理超长文本(DeepSeek上下文128K,但这里做分段处理)
        max_input_len = 10000  # 限制输入长度,避免超时
        if len(text) > max_input_len:
            text = text[:max_input_len] + "...\n[内容过长,已截取前部分]"
        
        if style == "结构化":
            prompt = f"""
【任务】请对以下文档进行结构化摘要处理。

【要求】
1. 核心观点:提炼文档的核心思想(50字以内)
2. 主要内容:分点列出关键内容,每个要点不超过50字
3. 关键数据:提取文档中的重要数字、百分比、时间等
4. 结论建议:文档的主要结论或建议
5. 总字数严格控制在{max_length}字以内

【输出格式】
核心观点:
[内容]

主要内容:
1. ...
2. ...
3. ...

关键数据:
- ...
- ...

结论建议:
[内容]

【文档内容】
{text}
"""
        elif style == "简洁":
            prompt = f"""
请用简洁的语言概括以下文档,保留最核心的信息,字数控制在{max_length}字以内。

文档:
{text}

简洁摘要:
"""
        else:  # 详细
            prompt = f"""
请对以下文档进行详细摘要,保留重要细节和论证过程,字数控制在{max_length}字以内。

文档:
{text}

详细摘要:
"""
        
        summary = self._call_api(prompt, temperature=0.3, max_tokens=2000)
        
        result = {
            "summary": summary,
            "style": style,
            "word_count": len(summary),
            "original_length": len(text)
        }
        
        # 如果需要提取关键引用
        if extract_quotes:
            quote_prompt = f"""
从以下文档中提取3-5句最关键的引用句(原句),要求:
1. 每句不超过50字
2. 体现文档核心观点
3. 直接引用原文

文档:
{text[:2000]}

关键引用:
"""
            quotes = self._call_api(quote_prompt, temperature=0.2)
            result["key_quotes"] = quotes
        
        self.processed_docs += 1
        return result
    
    def polish_official_document(self, text: str, style: str = "正式", 
                                  doc_type: str = "一般公文") -> Dict[str, str]:
        """
        公文润色(增强版)
        
        Args:
            text: 原文
            style: 风格("正式"、"亲切"、"简洁"、"庄重")
            doc_type: 文档类型("通知"、"报告"、"请示"、"函"、"一般公文")
            
        Returns:
            Dict: 包含润色后文本、修改说明、优化建议
        """
        # 根据文档类型调整要求
        style_requirements = {
            "通知": "语言简洁明了,要求明确,使用'现将...通知如下'句式",
            "报告": "客观全面,数据准确,使用'现将...报告如下'句式",
            "请示": "语气恳切,理由充分,使用'妥否,请批示'结尾",
            "函": "语气平等,礼貌得体,使用'特此函告'等用语",
            "一般公文": "规范严谨,条理清晰"
        }
        
        requirement = style_requirements.get(doc_type, style_requirements["一般公文"])
        
        prompt = f"""
【角色】你是一位资深公文写作专家,精通党政机关公文处理工作条例。

【任务】请对以下原文进行公文润色。

【文档类型】{doc_type}
【风格要求】{style}{requirement}

【润色要点】
1. 语言规范:使用公文规范用语,避免口语化、网络用语
2. 结构优化:调整段落层次,确保逻辑清晰
3. 格式规范:符合公文格式要求(标题、称谓、正文、落款)
4. 用词精准:使用专业、准确的词汇
5. 语气恰当:根据文档类型调整语气

【原文】
{text}

【输出格式】
【润色后文本】
(完整润色后的内容)

【修改说明】
1. 结构调整:...
2. 用词优化:...
3. 格式规范:...

【优化建议】
(如有进一步优化建议)
"""
        
        result_text = self._call_api(prompt, temperature=0.4, max_tokens=3000)
        
        # 解析返回结果
        polished_text = result_text
        modifications = ""
        suggestions = ""
        
        # 简单解析各部分
        if "【润色后文本】" in result_text:
            parts = result_text.split("【润色后文本】")
            if len(parts) > 1:
                polished_text = parts[1].split("【修改说明】")[0].strip()
            
            if "【修改说明】" in result_text:
                mod_part = result_text.split("【修改说明】")[1]
                modifications = mod_part.split("【优化建议】")[0].strip() if "【优化建议】" in mod_part else mod_part.strip()
            
            if "【优化建议】" in result_text:
                suggestions = result_text.split("【优化建议】")[1].strip()
        
        return {
            "polished_text": polished_text,
            "modifications": modifications,
            "suggestions": suggestions,
            "original_length": len(text),
            "polished_length": len(polished_text)
        }
    
    def extract_key_points(self, text: str, format_type: str = "json") -> Union[Dict, str]:
        """
        提取关键点(增强版)
        
        Args:
            text: 文档内容
            format_type: 输出格式("json"、"markdown"、"text")
            
        Returns:
            Dict或str: 结构化的关键点信息
        """
        prompt = f"""
【任务】请从以下文档中提取关键信息点。

【提取维度】
1. 核心主题:文档的核心议题(一句话概括)
2. 关键数据:所有重要数字、百分比、金额、时间等
3. 主要措施:文档提出的主要行动方案或措施
4. 时间节点:重要的时间节点和期限
5. 责任主体:涉及的责任单位或个人
6. 问题挑战:文档中提到的问题或挑战
7. 预期效果:预期达成的效果或目标

【输出要求】
- 使用{format_type.upper()}格式输出
- 确保信息准确,直接引用原文关键表述
- 如某维度没有相关信息,标注"无"

【文档内容】
{text[:4000]}

【输出】
"""
        
        result = self._call_api(prompt, temperature=0.2, max_tokens=2000)
        
        # 如果要求JSON格式,尝试解析
        if format_type == "json":
            try:
                # 尝试提取JSON部分
                json_match = re.search(r'\{.*\}', result, re.DOTALL)
                if json_match:
                    return json.loads(json_match.group())
                else:
                    return {"error": "无法解析为JSON", "raw_result": result}
            except:
                return {"error": "JSON解析失败", "raw_result": result}
        
        return result
    
    def compare_documents(self, doc1: str, doc2: str, aspect: str = "全面") -> Dict[str, Any]:
        """
        文档对比分析(新增功能)
        
        Args:
            doc1: 文档1
            doc2: 文档2
            aspect: 对比维度("全面"、"差异"、"优劣"、"版本对比")
            
        Returns:
            Dict: 对比分析结果
        """
        prompt = f"""
【任务】请对比分析以下两份文档。

【对比维度】{aspect}

【文档A】
{doc1[:2000]}

【文档B】
{doc2[:2000]}

【分析要求】
1. 核心差异:两份文档的主要不同点
2. 共同点:共有的内容或观点
3. 优势对比:各自的优势和不足
4. 适用场景:各自更适合的使用场景
5. 优化建议:如何结合两者优点

【输出格式】结构化分析,分点陈述。
"""
        
        analysis = self._call_api(prompt, temperature=0.4, max_tokens=2500)
        
        return {
            "analysis": analysis,
            "doc1_length": len(doc1),
            "doc2_length": len(doc2),
            "aspect": aspect
        }
    
    def generate_outline(self, topic: str, doc_type: str, depth: str = "详细") -> Dict[str, Any]:
        """
        生成文档大纲(新增功能)
        
        Args:
            topic: 文档主题
            doc_type: 文档类型("工作报告"、"策划方案"、"调研报告"、"总结"等)
            depth: 大纲深度("简要"、"详细"、"完整")
            
        Returns:
            Dict: 结构化的大纲
        """
        prompt = f"""
【任务】请为"{topic}"生成一份{doc_type}的大纲。

【大纲深度】{depth}

【要求】
1. 结构完整,符合{doc_type}的标准格式
2. 层级清晰,使用层级编号(一、1. (1) 等)
3. 每个部分给出简要的内容提示
4. 考虑实际可操作性

【输出格式】
一、标题
  1. 小节标题
     - 内容要点:...
     - 关键数据:...
  2. ...

二、标题
  ...
"""
        
        outline = self._call_api(prompt, temperature=0.5, max_tokens=2500)
        
        # 估算章节数量
        sections = outline.count("\n一、") + outline.count("\n二、") + outline.count("\n三、")
        
        return {
            "outline": outline,
            "topic": topic,
            "doc_type": doc_type,
            "sections_count": sections
        }
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取使用统计"""
        return {
            "total_requests": self.total_requests,
            "total_tokens": self.total_tokens,
            "processed_documents": self.processed_docs,
            "estimated_cost": f"¥{self.total_tokens * 0.0000002:.4f}",
            "avg_tokens_per_request": self.total_tokens // max(self.total_requests, 1)
        }


# 使用示例和测试
def example_usage():
    """演示如何使用DeepSeek文档处理器"""
    
    # 替换为你的API密钥
    API_KEY = "your-deepseek-api-key-here"
    
    # 初始化处理器
    processor = DeepSeekDocumentProcessor(API_KEY, model="deepseek-chat")
    
    # 测试文本
    sample_text = """
    关于推进校园文化建设的实施方案
    
    为深入贯彻党的教育方针,全面落实立德树人根本任务,进一步加强校园文化建设,营造积极向上、格调高雅的校园文化氛围,特制定本实施方案。
    
    一、指导思想
    以***思想为指导,坚持社会主义办学方向,以培育和践行社会主义核心价值观为引领,以提升师生文化素养为目标,全面推进校园文化建设。
    
    二、主要目标
    1. 到2025年底,建成3-5个校级文化品牌项目。
    2. 每年举办至少10场高水平文化讲座。
    3. 学生社团参与率达到85%以上。
    4. 建设5个传统文化传承基地。
    
    三、重点任务
    (一)实施文化阵地提升工程
    投入200万元改造大学生活动中心,新建文化展厅300平方米。
    
    (二)开展品牌文化活动
    持续打造"校园文化艺术节"、"书香校园"读书月等品牌活动。
    
    (三)推进传统文化传承
    开设书法、国画、戏曲等传统文化课程,年参与学生不少于1000人次。
    
    四、保障措施
    1. 组织保障:成立校园文化建设领导小组。
    2. 经费保障:每年安排专项经费100万元。
    3. 考核保障:将文化建设纳入部门年度考核。
    """
    
    print("=" * 60)
    print("DeepSeek文档处理器功能演示")
    print("=" * 60)
    
    # 1. 文档摘要
    print("\n📝 1. 文档摘要")
    print("-" * 40)
    summary_result = processor.summarize_long_document(
        sample_text, 
        max_length=200,
        style="结构化",
        extract_quotes=True
    )
    print(f"摘要字数:{summary_result['word_count']}字")
    print(f"摘要内容:\n{summary_result['summary'][:300]}...")
    
    # 2. 公文润色
    print("\n✍️ 2. 公文润色")
    print("-" * 40)
    polished = processor.polish_official_document(
        sample_text,
        style="正式",
        doc_type="通知"
    )
    print(f"原文长度:{polished['original_length']}字")
    print(f"润色后长度:{polished['polished_length']}字")
    print(f"修改说明:\n{polished['modifications'][:200]}...")
    
    # 3. 关键点提取
    print("\n🔍 3. 关键点提取")
    print("-" * 40)
    key_points = processor.extract_key_points(sample_text, format_type="json")
    if isinstance(key_points, dict):
        for key, value in key_points.items():
            print(f"{key}: {value}")
    
    # 4. 生成大纲
    print("\n📋 4. 生成文档大纲")
    print("-" * 40)
    outline = processor.generate_outline(
        topic="高校校园文化建设总结报告",
        doc_type="工作总结",
        depth="详细"
    )
    print(f"大纲章节数:{outline['sections_count']}")
    print(f"大纲内容预览:\n{outline['outline'][:400]}...")
    
    # 5. 使用统计
    print("\n📊 5. 使用统计")
    print("-" * 40)
    stats = processor.get_statistics()
    for key, value in stats.items():
        print(f"{key}: {value}")
    
    print("\n✅ 演示完成!")


# 批量处理示例
def batch_process_documents():
    """批量处理文档的示例"""
    
    API_KEY = "your-deepseek-api-key-here"
    processor = DeepSeekDocumentProcessor(API_KEY)
    
    documents = [
        {"title": "文件1", "content": "..."},
        {"title": "文件2", "content": "..."},
        # ... 更多文档
    ]
    
    results = []
    for doc in documents:
        print(f"正在处理:{doc['title']}")
        summary = processor.summarize_long_document(doc['content'], max_length=200)
        results.append({
            "title": doc['title'],
            "summary": summary['summary']
        })
    
    # 保存结果
    with open("batch_summaries.json", "w", encoding="utf-8") as f:
        json.dump(results, f, ensure_ascii=False, indent=2)
    
    return results


if __name__ == "__main__":
    # 运行示例
    # example_usage()
    
    # 如需批量处理,取消注释下面代码
    batch_process_documents()

运行结果:

(ai_env) $ python3 deepdeek_document_processor.py
正在处理:文件1
正在处理:文件2
(ai_env) $ 

更多推荐