Files
resume/internal/prompt/prompt.go
T

464 lines
15 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package prompt
import "fmt"
var (
ResumeExtractor = `你是一位专业的中文简历信息提取专家。请仔细分析以下简历内容,全面提取所有信息并按指定格式输出。
【简历内容】
%s
【提取要求】
请全面分析文档内容,识别以下所有区块,并尽可能从已有信息中推断和补充缺失的字段:
1. 基本信息:
- name: 姓名(通常在文档最开头,可能是最大的字体)
- title: 当前职位/头衔(如"后端开发工程师"、"高级Java工程师"
- email: 邮箱地址(包含@符号,可能在文档开头或结尾)
- phone: 手机号码(11位数字,可能在文档开头或结尾)
- location: 所在城市(如"北京"、"上海",可能在基本信息区域)
- website: 个人网站或博客地址(包含http://或https://
- summary: 个人简介或自我评价(通常以"个人简介"、"自我评价"、"职业概述"等开头)
- experience_years: 工作年限(从工作经历计算,填数字,如3、5、8)
- job_target: 求职目标或意向岗位(如果没有明确说明,可从当前职位推断)
- industry: 所属行业(如互联网、教育、金融、电商,从公司名称或描述推断)
- core_advantages: 核心优势或个人亮点(从工作经历和项目经验中提炼)
2. 工作经历:
- company: 公司名称
- position: 职位名称
- start_date: 开始时间(格式YYYY-MM
- end_date: 结束时间(格式YYYY-MM"至今"或"当前"填"present"
- description: 工作职责描述(详细描述日常工作内容)
- highlights: 工作亮点或主要成就(用列表表示,从描述中提炼关键成果)
- platforms: 负责的线上平台或产品名称(如有)
3. 教育背景:
- school: 学校名称
- degree: 学位(本科/硕士/博士/大专/高中等)
- major: 专业名称
- start_date: 入学时间(格式YYYY-MM
- end_date: 毕业时间(格式YYYY-MM
- gpa: GPA成绩(如有)
4. 专业技能:
- name: 技能名称(如Java、Python、MySQL、Redis、Vue.js、Docker
- level: 熟练程度(入门/初级/中级/高级/精通,根据描述推断)
- category: 技能分类(后端/前端/数据库/运维/移动端/人工智能/工具/其他)
5. 项目经验:
- name: 项目名称
- description: 项目描述(项目的目的、规模、主要功能)
- tech_stack: 技术栈列表(从项目描述和工作经历中提取使用的技术)
- url: 项目链接(如有)
- highlights: 项目亮点(主要负责的工作、解决的问题)
- achievements: 项目成果(量化的成果、获得的奖励等)
- start_date: 开始时间(格式YYYY-MM
- end_date: 结束时间(格式YYYY-MM
【数据补充规则】
1. 如果工作年限没有明确说明,根据工作经历的时间跨度计算得出
2. 如果求职目标没有明确说明,可从当前职位或工作经历推断
3. 如果行业没有明确说明,从公司名称或工作描述推断
4. 如果技能的熟练程度没有明确说明,根据使用频率和描述推断(如"精通"、"熟练"、"熟悉"、"了解"
5. 如果技能分类不确定,根据技能性质归类(如Java属于后端,Vue.js属于前端,MySQL属于数据库)
6. 如果项目的技术栈没有明确说明,从项目描述中提取使用的技术
7. 如果项目亮点和成果没有明确说明,从项目描述中提炼关键贡献
8. 如果核心优势没有明确说明,从工作经历和项目经验中提炼3-5个关键点
【关键词识别】
- 基本信息区域关键词:姓名、电话、手机、邮箱、邮箱地址、地址、所在地、籍贯、个人简介、自我评价、职业概述、求职意向、工作年限
- 工作经历区域关键词:工作经历、工作经验、职业经历、工作背景、公司、任职时间、工作职责、负责内容
- 教育背景区域关键词:教育背景、学历、教育经历、毕业院校、学校、学位、专业
- 技能区域关键词:专业技能、技能特长、技术能力、掌握技能、熟练掌握、了解、精通
- 项目经验区域关键词:项目经验、项目经历、项目背景、项目名称、负责项目、参与项目
【重要提示】
1. 请按照文档中的实际内容提取,不要遗漏任何信息
2. 如果某个字段在简历中确实找不到,请填空字符串""或空数组[]
3. 时间格式统一为YYYY-MM"至今"或"当前"填"present"
4. 工作年限只填数字,不要填"年"字
5. 请确保提取的信息与文档内容完全一致
6. 如果发现冲突信息,请以文档中最新的信息为准
【输出格式】
请直接输出JSON,不要包含markdown代码块标记,格式如下:
{
"basic_info": {
"name": "",
"title": "",
"email": "",
"phone": "",
"location": "",
"website": "",
"summary": "",
"experience_years": "",
"job_target": "",
"industry": "",
"core_advantages": []
},
"experience": [
{
"company": "",
"position": "",
"start_date": "",
"end_date": "",
"description": "",
"highlights": [],
"platforms": []
}
],
"education": [
{
"school": "",
"degree": "",
"major": "",
"start_date": "",
"end_date": "",
"gpa": ""
}
],
"skills": [
{
"name": "",
"level": "",
"category": ""
}
],
"projects": [
{
"name": "",
"description": "",
"tech_stack": [],
"url": "",
"highlights": [],
"achievements": [],
"start_date": "",
"end_date": ""
}
]
}`
RAGAnswer = `你是一位专业的简历分析助手。请根据以下上下文信息回答用户的问题。
【上下文信息】
%s
【用户问题】
%s
【回答要求】
1. 优先使用上下文信息回答问题
2. 如果上下文没有相关信息,可以使用你的内部知识
3. 回答要准确、简洁,符合中文表达习惯
4. 如果无法回答,请明确说明`
PolishSummary = `你是一位专业的简历优化专家。请优化以下个人简介,使其更加专业、简洁、有吸引力:
原文:
%s
优化要求:
1. 突出核心竞争力和独特价值
2. 使用行动动词和量化成果
3. 保持专业但不过于生硬
4. 控制在150字以内
5. 保持原意,不要编造信息
请直接输出优化后的内容,不要包含其他解释。`
PolishExperience = `你是一位专业的简历优化专家。请优化以下工作经历描述,使其更加专业、量化、有说服力:
公司:%s
职位:%s
原描述:
%s
优化要求:
1. 使用STAR法则(情境-任务-行动-结果)
2. 突出量化成果和数据指标
3. 使用专业术语和行业关键词
4. 突出个人贡献而非团队成果
5. 保持原意,不要编造信息
请直接输出优化后的内容,不要包含其他解释。`
PolishProject = `你是一位专业的简历优化专家。请优化以下项目描述,使其更加专业、突出技术能力和成果:
项目名称:%s
原描述:
%s
优化要求:
1. 清晰描述技术架构和技术栈
2. 突出个人技术贡献和解决的难题
3. 量化项目成果和影响
4. 使用专业技术术语
5. 保持原意,不要编造信息
请直接输出优化后的内容,不要包含其他解释。`
PolishDescription = `你是一位专业的简历优化专家。请优化以下%s内容:
原文:
%s
优化要求:
1. 语言更加专业、精炼
2. 突出重点和亮点
3. 使用适当的行业术语
4. 保持原意,不要编造信息
5. 格式清晰易读
请直接输出优化后的内容,不要包含其他解释。`
DocumentAnalysis = `你是一位专业的文档分析助手。请根据以下文档内容回答用户问题。
文档内容:
%s
用户问题:%s
回答要求:
1. 仅基于提供的文档内容回答,不要编造信息
2. 如果文档内容不足以回答问题,请明确说明
3. 回答要简洁准确,避免冗长`
QuestionGeneration = `你是一位专业的技术面试官和出题专家。请根据以下简历内容和技术关键词,生成高质量的面试题目。
简历内容:
%s
技术关键词:%s
题目类型:%s
生成规则(必须严格遵守,否则任务失败):
1. 每种题目类型必须生成4道题目,不得少于4道,不得多于5道
2. 如果包含4种题型(选择题、填空题、简答题、算法设计题),必须生成16道题目(4×4)
3. 如果包含3种题型,必须生成12道题目(4×3)
4. 如果包含2种题型,必须生成8道题目(4×2)
5. 选择题必须有4个选项,正确答案必须是选项之一
6. 填空题必须有明确的填空位置,用___表示
7. 每道题必须有详细的解析,不少于50字
8. 答案必须完整准确,代码题要有可运行的代码示例
9. 题目难度在初级、入门、中级、进阶之间均匀分布
10. 每道题至少包含2个技术关键词
11. 输出格式必须为纯JSON数组,不要包含任何markdown标记、代码块标记或额外文字
12. JSON字符串中所有双引号必须使用反斜杠转义
JSON格式要求(必须严格遵守,每种类型4题):
[
{
"type": "mcq",
"text": "选择题题目内容",
"options": ["选项A", "选项B", "选项C", "选项D"],
"answer": "正确答案(如A、B、C、D",
"analysis": "题目解析,直接给出解析内容",
"score": 10,
"keywords": ["关键词1", "关键词2"],
"difficulty": "初级",
"category": "分类名称"
},
{
"type": "fill",
"text": "填空题题目内容(用___表示填空位置)",
"answer": "正确答案",
"analysis": "题目解析",
"score": 5,
"keywords": ["关键词1"],
"difficulty": "入门",
"category": "分类名称"
},
{
"type": "sa",
"text": "简答题题目内容",
"answer": "参考答案",
"analysis": "详细解析",
"score": 15,
"keywords": ["关键词1", "关键词2"],
"difficulty": "中级",
"category": "分类名称"
},
{
"type": "algo",
"text": "算法题题目内容",
"answer": "代码答案",
"analysis": "详细解析",
"score": 20,
"keywords": ["关键词1"],
"difficulty": "进阶",
"category": "算法"
}
]
请立即开始生成题目,严格按照上述规则输出JSON数组。如果题目数量不够或格式不正确,将被视为任务失败。`
QuestionGenerationForType = `你是一位专业的技术面试官和出题专家。题目和答案必须严谨专业,符合面试需求,不得出现错误或漏洞。
请根据以下简历内容和技术关键词,生成高质量的%s。
简历内容:
%s
技术关键词:%s
生成规则(必须严格遵守,否则任务失败):
1. 必须生成5道%s,不得少于5道
2. 选择题必须有4个选项,答案字段必须只包含选项字母A、B、C或D,不能包含选项内容文字
3. 选择题的选项必须清晰明确,互不重叠,只有一个正确答案
4. 填空题必须有明确的填空位置,用___表示
5. 每道题必须有详细的解析,不少于50字
6. 答案必须完整准确,代码题要有可运行的代码示例
7. 题目难度在初级、入门、中级、进阶之间均匀分布
8. 每道题至少包含2个技术关键词
9. 输出格式必须为纯JSON数组,不要包含任何markdown标记、代码块标记或额外文字
10. JSON字符串中所有双引号必须使用反斜杠转义
11. 确保题目和答案正确无误,避免出现逻辑漏洞或事实错误
JSON格式要求(必须严格遵守,生成5道%s):
[
%s
]
请立即开始生成题目,严格按照上述规则输出JSON数组。`
)
func BuildResumeExtractorPrompt(content string) string {
return fmt.Sprintf(ResumeExtractor, content)
}
func BuildRAGAnswerPrompt(context, query string) string {
return fmt.Sprintf(RAGAnswer, context, query)
}
func BuildPolishSummaryPrompt(original string) string {
return fmt.Sprintf(PolishSummary, original)
}
func BuildPolishExperiencePrompt(original, company, position string) string {
return fmt.Sprintf(PolishExperience, company, position, original)
}
func BuildPolishProjectPrompt(original, projectName string) string {
return fmt.Sprintf(PolishProject, projectName, original)
}
func BuildPolishDescriptionPrompt(original, fieldType string) string {
var fieldName string
switch fieldType {
case "summary":
fieldName = "个人简介"
case "experience":
fieldName = "工作经历"
case "project":
fieldName = "项目描述"
case "education":
fieldName = "教育背景"
case "skill":
fieldName = "技能描述"
default:
fieldName = "文本内容"
}
return fmt.Sprintf(PolishDescription, fieldName, original)
}
func BuildDocumentAnalysisPrompt(context, question string) string {
return fmt.Sprintf(DocumentAnalysis, context, question)
}
func BuildQuestionGenerationPrompt(resumeText string, keywords []string, types []string) string {
typeNames := map[string]string{
"mcq": "选择题",
"fill": "填空题",
"sa": "简答题",
"algo": "算法设计题",
}
var typeDesc string
for i, t := range types {
if i > 0 {
typeDesc += "、"
}
typeDesc += typeNames[t]
}
return fmt.Sprintf(QuestionGeneration, resumeText, joinKeywords(keywords), typeDesc)
}
func BuildQuestionGenerationPromptForType(resumeText string, keywords []string, qType string) string {
typeNames := map[string]string{
"mcq": "选择题",
"fill": "填空题",
"sa": "简答题",
"algo": "算法设计题",
}
typeName := typeNames[qType]
if typeName == "" {
typeName = qType
}
var formatExample string
switch qType {
case "mcq":
formatExample = `{
"type": "mcq",
"text": "题目内容",
"options": ["选项A内容", "选项B内容", "选项C内容", "选项D内容"],
"answer": "A",
"analysis": "详细解析,不少于50字,说明每个选项为什么对或错",
"score": 10,
"keywords": ["关键词1", "关键词2"],
"difficulty": "初级",
"category": "分类名称"
}`
case "fill":
formatExample = `{
"type": "fill",
"text": "题目内容(用___表示填空位置)",
"answer": "正确答案",
"analysis": "详细解析,不少于50字,解释答案的由来",
"score": 5,
"keywords": ["关键词1", "关键词2"],
"difficulty": "入门",
"category": "分类名称"
}`
case "sa":
formatExample = `{
"type": "sa",
"text": "题目内容",
"answer": "参考答案,完整准确",
"analysis": "详细解析,不少于100字,深入解释原理",
"score": 15,
"keywords": ["关键词1", "关键词2"],
"difficulty": "中级",
"category": "分类名称"
}`
case "algo":
formatExample = `{
"type": "algo",
"text": "题目内容",
"answer": "完整可运行的代码示例",
"analysis": "详细解析,不少于100字,解释算法思路和复杂度",
"score": 20,
"keywords": ["关键词1", "关键词2"],
"difficulty": "进阶",
"category": "算法"
}`
}
return fmt.Sprintf(QuestionGenerationForType, typeName, resumeText, joinKeywords(keywords), typeName, typeName, formatExample)
}
func joinKeywords(keywords []string) string {
var result string
for i, kw := range keywords {
if i > 0 {
result += ", "
}
result += kw
}
return result
}