添加AI 优化接口

This commit is contained in:
zk
2026-04-08 17:31:47 +08:00
parent 3cf4ebaa78
commit a565da0ae6
4 changed files with 101 additions and 2 deletions
+40 -1
View File
@@ -9,7 +9,7 @@ from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from app.ai.models import LLM
from app.ai.resume_diagnoser.prompts import DIAGNOSE_MODULE_PROMPT, SUMMARY_PROMPT
from app.ai.resume_diagnoser.prompts import DIAGNOSE_MODULE_PROMPT, SUMMARY_PROMPT, POLISH_PROMPT
from app.core.logger import log
@@ -62,6 +62,45 @@ async def generate_summary(grade: str, urgent_total: int, important_total: int,
return "简历诊断已完成,请查看各模块的详细诊断结果。"
_polish_chain = (
ChatPromptTemplate.from_messages([("system", POLISH_PROMPT), ("human", "请开始优化。")])
| LLM.CLAUDE_SONNET_4.create(temperature=0.3)
| StrOutputParser()
)
async def polish_content(module_type: str, reference_content: list[dict] | str | None,
user_content: list[str], is_summary: bool) -> list[str]:
"""润色用户编辑后的文本"""
ref_text = ""
if reference_content:
if isinstance(reference_content, list):
ref_text = "\n".join(
item.get("text", "") if isinstance(item, dict) else str(item)
for item in reference_content
)
else:
ref_text = str(reference_content)
if not ref_text:
ref_text = ""
inp = {
"module_type": module_type,
"reference_content": ref_text,
"user_content": "\n".join(user_content),
"summary_constraint": "- 注意:此模块只能输出一个段落,数组只能有一个元素" if is_summary else "",
}
try:
raw = await _polish_chain.ainvoke(inp)
result = _parse_json(raw)
if isinstance(result, list):
return [str(item) for item in result]
return [str(result)]
except Exception as e:
log.warning(f"AI润色失败: {e}")
return user_content
async def _safe_invoke(task: dict) -> dict:
"""单条记录诊断,失败返回空结果"""
raw = ""
+23
View File
@@ -77,3 +77,26 @@ SUMMARY_PROMPT = """你是一位资深简历顾问。请根据以下简历诊断
4. 一句鼓励或行动建议
直接输出评价文本,不要输出JSON或其他格式标记。控制在300字以内。"""
POLISH_PROMPT = """你是一位资深简历顾问。请对用户提供的简历描述文本进行润色优化,让语言更精练、更专业。
## 模块类型
{module_type}
## AI 之前的优化版本(仅供参考)
{reference_content}
## 用户提交的文本(以此为主进行优化)
{user_content}
## 优化要求
- 以用户提交的文本为主体进行润色,AI之前的版本仅作参考
- 让语言更精练、更专业,去除冗余表达
- 尽量使用数据量化成果
- 保持原意不变,不凭空捏造内容
- 输出为 JSON 数组格式,每个元素是一个段落的纯文本
{summary_constraint}
## 输出格式
严格输出 JSON 数组,不要输出其他内容:
["优化后的段落1", "优化后的段落2"]"""
+23 -1
View File
@@ -3,7 +3,7 @@
from fastapi import APIRouter
from pydantic import BaseModel, Field
from app.ai.resume_diagnoser.diagnoser import diagnose_all, generate_summary
from app.ai.resume_diagnoser.diagnoser import diagnose_all, generate_summary, polish_content
from app.core.context import RequestContext
from app.core.database import get_db
from app.services.resume_diagnose_service import ResumeDiagnoseService, aggregate_results
@@ -83,3 +83,25 @@ async def feedback_issue(issue_id: int, param: FeedbackParam):
async for session in get_db():
service = ResumeDiagnoseService(session)
await service.update_feedback(issue_id, user_id, param.user_feedback)
class PolishParam(BaseModel):
content: list[str] = Field(..., description="用户编辑后的文本段落数组")
@router.post("/issue/{issue_id}/polish", summary="AI润色用户编辑的文本")
async def polish_issue_content(issue_id: int, param: PolishParam):
"""基于诊断问题上下文,AI润色用户编辑后的文本"""
user_id = RequestContext.user_id.get()
async for session in get_db():
service = ResumeDiagnoseService(session)
ctx = await service.get_issue_for_polish(issue_id, user_id)
result = await polish_content(
module_type=ctx["module_label"],
reference_content=ctx["optimized_content"],
user_content=param.content,
is_summary=ctx["is_summary"],
)
return {"content": result}
+15
View File
@@ -160,6 +160,21 @@ class ResumeDiagnoseService:
issue.user_feedback = user_feedback
await self.session.flush()
async def get_issue_for_polish(self, issue_id: int, user_id: int) -> dict:
"""获取 issue 润色所需的上下文信息"""
result = await self.session.execute(
select(ResumeDiagnosisIssue).where(
ResumeDiagnosisIssue.id == issue_id, ResumeDiagnosisIssue.user_id == user_id))
issue = result.scalar_one_or_none()
if issue is None:
raise ValueError("诊断问题不存在")
return {
"module_type": issue.module_type,
"module_label": _MODULE_LABELS.get(issue.module_type, issue.module_type),
"optimized_content": issue.optimized_content,
"is_summary": issue.module_type == "summary",
}
# ===== 工具函数 =====