Python 实现智能 PDF 文档助手 AI 小工具
介绍如何使用 Python 结合 OpenAI API 开发一个智能 PDF 文档助手。项目支持 PDF 读取、内容摘要生成、关键词提取及交互问答功能。通过模块化设计(config.py, pdf_reader.py, ai_client.py, main.py),实现了命令行界面的友好交互与流式输出。文章涵盖环境配置、核心代码实现、使用示例及进阶扩展建议,适合希望快速上手 AI 应用开发的开发者参考。

介绍如何使用 Python 结合 OpenAI API 开发一个智能 PDF 文档助手。项目支持 PDF 读取、内容摘要生成、关键词提取及交互问答功能。通过模块化设计(config.py, pdf_reader.py, ai_client.py, main.py),实现了命令行界面的友好交互与流式输出。文章涵盖环境配置、核心代码实现、使用示例及进阶扩展建议,适合希望快速上手 AI 应用开发的开发者参考。

| 功能 | 说明 |
|---|---|
| 📄 多格式支持 | 支持 PDF、TXT 文件读取 |
| 🤖 AI 驱动 | 使用 GPT 模型进行智能分析 |
| ⚡ 快速响应 | 流式输出,实时查看结果 |
| 🎨 彩色输出 | 命令行美化,体验更佳 |
| 📊 进度显示 | 文件读取进度可视化 |
# 检查 Python 版本
import sys
print(f"Python 版本:{sys.version}")
# 推荐版本:Python 3.9 或更高
# 下载地址:https://www.python.org/downloads/
创建 requirements.txt 文件:
openai>=1.0.0
pdfplumber>=0.10.0
python-dotenv>=1.0.0
colorama>=0.4.6
tqdm>=4.65.0
安装命令:
# 创建虚拟环境(推荐)
python -m venv ai_assistant_env
# 激活虚拟环境
# Windows: ai_assistant_env\Scripts\activate
# Mac/Linux: source ai_assistant_env/bin/activate
# 安装依赖
pip install -r requirements.txt
.env 文件配置 API_KEYecho OPENAI_API_KEY=your_api_key_here > .env
echo OPENAI_BASE_URL=https://api.openai.com/v1 >> .env
pdf_ai_assistant/
├── main.py # 主程序入口
├── config.py # 配置文件
├── utils/ # 工具函数
│ ├── pdf_reader.py # PDF 读取
│ ├── ai_client.py # AI 客户端
│ └── output.py # 输出格式化
├── requirements.txt # 依赖列表
├── .env # 环境变量
└── README.md # 项目说明
""" 配置文件 - 管理所有配置项 """
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
class Config:
"""应用配置类"""
# OpenAI 配置
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_BASE_URL = os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")
OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-3.5-turbo")
# 应用配置
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
CHUNK_SIZE = 1000 # 每次处理的字符数
MAX_TOKENS = 2000 # AI 最大响应长度
# 颜色配置
COLORS = {
"header": "\033[95m", # 紫色
"okblue": "\033[94m", # 蓝色
"okgreen": "\033[92m", # 绿色
"warning": "\033[93m", # 黄色
"fail": "\033[91m", # 红色
"endc": "\033[0m", # 结束
}
@classmethod
def color_print(cls, color_type, message):
"""彩色打印"""
color = cls.COLORS.get(color_type, "")
print()
Config.OPENAI_API_KEY:
Config.color_print(, )
exit()
""" PDF 文档读取模块 """
import pdfplumber
from tqdm import tqdm
from config import Config
class PDFReader:
"""PDF 文档读取器"""
def __init__(self, file_path):
self.file_path = file_path
self.content = ""
self.page_count = 0
def validate_file(self):
"""验证文件"""
if not self.file_path.endswith('.pdf'):
raise ValueError("❌ 仅支持 PDF 文件格式")
import os
file_size = os.path.getsize(self.file_path)
if file_size > Config.MAX_FILE_SIZE:
raise ValueError(f"❌ 文件过大,最大支持{Config.MAX_FILE_SIZE//1024//1024}MB")
def read_pdf(self):
"""读取 PDF 内容"""
try:
self.validate_file()
Config.color_print("okblue", f"📖 正在读取文件:{self.file_path}")
with pdfplumber.open(self.file_path) as pdf:
self.page_count = (pdf.pages)
Config.color_print(, )
page tqdm(pdf.pages, desc=, unit=):
text = page.extract_text()
text:
.content += text +
Config.color_print(, )
.content
Exception e:
Config.color_print(, )
():
.content[:] + (.content) > .content
""" OpenAI API 客户端模块 """
from openai import OpenAI
from config import Config
import time
class AIClient:
"""AI 助手客户端"""
def __init__(self):
self.client = OpenAI(
api_key=Config.OPENAI_API_KEY,
base_url=Config.OPENAI_BASE_URL
)
def ask(self, question, context=""):
"""向 AI 提问"""
try:
# 构建消息
messages = [
{"role": "system", "content": "你是一个专业的文档分析助手。"},
{"role": "user", "content": f"文档内容:\n{context}\n\n问题:{question}"}
]
Config.color_print("okblue", "🤖 AI 正在思考...")
# 调用 API
start_time = time.time()
response = self.client.chat.completions.create(
model=Config.OPENAI_MODEL,
messages=messages,
max_tokens=Config.MAX_TOKENS,
stream=True # 启用流式输出
)
# 流式输出
answer = ""
Config.color_print("okgreen", "📝 AI 回答:")
for chunk in response:
if chunk.choices[0].delta.content:
content = chunk.choices[].delta.content
answer += content
(content, end=, flush=)
()
elapsed = time.time() - start_time
Config.color_print(, )
answer
Exception e:
Config.color_print(, )
():
prompt =
.ask(prompt, )
():
prompt =
.ask(prompt, )
""" PDF 智能助手主程序 """
import argparse
import sys
from pdf_reader import PDFReader
from ai_client import AIClient
from config import Config
def print_banner():
"""打印欢迎界面"""
banner = """ ╔═══════════════════════════════════════╗
║ 📚 PDF 智能文档助手 v1.0 📚 ║
║ Powered by OpenAI GPT ║
╚═══════════════════════════════════════╝ """
Config.color_print("header", banner)
def interactive_mode(reader, ai_client):
"""交互模式"""
Config.color_print("okgreen", "\n🎯 进入交互模式(输入'quit'退出)")
context = reader.content[:3000] # 使用前 3000 字作为上下文
while True:
try:
question = input("\n💬 请输入问题:").strip()
if question.lower() in ['quit', 'exit', 'q']:
Config.color_print("warning", "👋 再见!")
break
if not question:
continue
ai_client.ask(question, context)
except KeyboardInterrupt:
Config.color_print("warning", "\n👋 用户取消,再见!")
break
except Exception as e:
Config.color_print("fail", )
():
parser = argparse.ArgumentParser(description=)
parser.add_argument(, =)
parser.add_argument(, action=, =)
parser.add_argument(, action=, =)
parser.add_argument(, metavar=, =)
args = parser.parse_args()
print_banner()
:
reader = PDFReader(args.file)
content = reader.read_pdf()
ai_client = AIClient()
args.summarize:
ai_client.summarize(content)
args.keywords:
ai_client.extract_keywords(content)
args.ask:
ai_client.ask(args.ask, content[:])
:
interactive_mode(reader, ai_client)
Exception e:
Config.color_print(, )
sys.exit()
__name__ == :
main()
python main.py document.pdf --summarize
python main.py document.pdf --keywords
python main.py document.pdf --ask "这篇文章的主要观点是什么?"
python main.py document.pdf
交互模式示例输出:
💬 请输入问题:这篇文章讲了什么?
🤖 AI 正在思考...
📝 AI 回答:这篇文章主要介绍了人工智能的发展历程和应用场景...
⏱️ 耗时:2.35 秒
💬 请输入问题:作者提到了哪些关键技术?
🤖 AI 正在思考...
📝 AI 回答:作者主要提到了以下几项关键技术:
1. 深度学习
2. 自然语言处理
3. 计算机视觉 ...
⏱️ 耗时:1.98 秒
💬 请输入问题:quit
👋 再见!
def batch_process(file_list, func):
"""批量处理多个文件"""
results = []
for file in tqdm(file_list, desc="批量处理"):
try:
reader = PDFReader(file)
content = reader.read_pdf()
result = func(content)
results.append({"file": file, "result": result, "status": "success"})
except Exception as e:
results.append({"file": file, "result": str(e), "status": "failed"})
return results
def export_to_markdown(content, output_file):
"""导出为 Markdown 格式"""
with open(output_file, 'w', encoding='utf-8') as f:
f.write("# 文档摘要\n\n")
f.write(content)
Config.color_print("okgreen", f"✅ 已导出到:{output_file}")
class ConversationMemory:
"""对话记忆管理"""
def __init__(self, max_history=5):
self.history = []
self.max_history = max_history
def add(self, question, answer):
"""添加对话记录"""
self.history.append({"question": question, "answer": answer})
# 保留最近 N 条记录
if len(self.history) > self.max_history:
self.history = self.history[-self.max_history:]
def get_context(self):
"""获取上下文"""
context = ""
for item in self.history:
context += f"Q: {item['question']}\nA: {item['answer']}\n\n"
return context
| 问题 | 解决方案 |
|---|---|
| API 调用超时 | 添加重试机制,设置合理的 timeout |
| 内存占用过高 | 分块处理大文件,使用生成器 |
| 用户体验差 | 添加进度条、彩色输出、友好提示 |
| 代码可维护性差 | 模块化设计,添加类型注解和文档 |
# 1. 使用类型注解
def process_file(file_path: str) -> dict:
"""处理文件并返回结果字典"""
pass
# 2. 添加异常处理
try:
result = risky_operation()
except SpecificError as e:
logger.error(f"操作失败:{e}")
finally:
cleanup()
# 3. 使用日志记录
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# 4. 编写单元测试
import unittest
class TestPDFReader(unittest.TestCase):
def test_validate_file(self):
reader = PDFReader("test.pdf")
# 测试代码...
视频教程
项目灵感
恭喜你!🎉
如果你已经跟随这篇文章完成了项目,那么你已经:
✅ 学会了如何调用 OpenAI API
✅ 掌握了 PDF 文件处理技巧
✅ 了解了命令行工具的开发流程
✅ 获得了一个实用的 AI 小工具
下一步建议:
记住:最好的学习方式就是动手实践!

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online