import gradio as gr import fitz # PyMuPDF import openai import re import os # ✅ 使用 Hugging Face Secrets 管理 API 金鑰 openai.api_key = os.environ.get("OPENAI_API_KEY") # --- 清理文字 --- def clean_text(text): text = re.sub(r'^\s*\d+\s*$', '', text, flags=re.MULTILINE) text = re.sub(r'\n\s*\n+', '\n\n', text) text = re.sub(r'[ \t]+', ' ', text) return text.strip() # --- 改進版:區塊式擷取 PDF 文字 + 座標排序 --- def extract_text_from_pdf(file): doc = fitz.open(file.name) text_blocks = [] for page in doc: blocks = page.get_text("blocks") # 回傳每段區塊含座標 blocks = sorted(blocks, key=lambda b: (b[1], b[0])) # 先依 y,再依 x 排序 for b in blocks: text_blocks.append(b[4]) doc.close() return clean_text("\n".join(text_blocks)) # --- GPT 履歷分析(STAR 法則)--- def analyze_resume(resume_text): prompt = f""" 你是一位專業的履歷健檢與職涯輔導顧問,請協助我以下幾件事: 注意:這份履歷是由 PDF 擷取而來,可能因版面問題導致部分文字順序略有錯亂。請你盡量根據語意邏輯判斷內容。 1. 根據下方履歷內容,幫我整理出: - 學歷背景 - 技能與工具 - 工作經歷與專案經歷 2. 對於每一段經歷,請用 STAR 法則整理: - S(情境) - T(任務) - A(行動) - R(成果) 3. 指出這份履歷的優勢,以及可以優化的建議 4. 推薦幾個可能適合的職缺方向(例如:前端工程師、資料分析師、產品實習生等) 這是履歷內容: ------------------------ {resume_text} ------------------------ 請以條列式輸出,分段清楚。 """ response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "你是一位履歷健檢顧問"}, {"role": "user", "content": prompt} ], temperature=0.7, max_tokens=1500 ) content = response['choices'][0]['message']['content'] return content.replace("**", "").replace("* ", "• ").replace("*", "").strip() # --- GPT 自傳撰寫 --- def generate_autobiography(resume_text): prompt = f""" 這是從 PDF 擷取的履歷文字,順序可能略有錯亂。請盡量根據語意整理,幫我撰寫一段約 300 字的個人自傳。口吻自然、自信,強調個人特質、學習歷程與職涯目標,可作為履歷中的「自我介紹」使用: 履歷內容: ------------------------ {resume_text} ------------------------ """ response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "你是一位履歷與自傳輔導顧問"}, {"role": "user", "content": prompt} ], temperature=0.7, max_tokens=800 ) return response['choices'][0]['message']['content'].strip() # --- Gradio UI --- with gr.Blocks(title="求職小幫手 AI") as demo: gr.Markdown("## 🧑‍💼 求職小幫手 AI\n上傳履歷 PDF,我們幫你分析亮點並撰寫個人自傳!") with gr.Row(): pdf_input = gr.File(label="📄 上傳履歷 PDF", file_types=[".pdf"]) extract_btn = gr.Button("⬇️ 擷取與清理內容") resume_textbox = gr.Textbox(label="📄 擷取後的履歷純文字", lines=20, interactive=False) with gr.Row(): analyze_btn = gr.Button("🧠 分析履歷(STAR 法則)") bio_btn = gr.Button("📝 撰寫個人自傳") analysis_output = gr.Textbox(label="✨ GPT 履歷分析結果", lines=25) bio_output = gr.Textbox(label="✍️ GPT 產生的個人自傳", lines=15) extract_btn.click(fn=extract_text_from_pdf, inputs=pdf_input, outputs=resume_textbox) analyze_btn.click(fn=analyze_resume, inputs=resume_textbox, outputs=analysis_output) bio_btn.click(fn=generate_autobiography, inputs=resume_textbox, outputs=bio_output) demo.launch()