之前尝试体验了
Coze
,发现体验感真的很好,0代码就能创建属于自己的Agent,在该项目中,我尝试着搭建并接入了Coze工作流,它的主要工作就是当用户上传简历图片,帮用户分析出简历的优缺点并给出建议和简历评分,让用户能够一目了然的了解到自己的不足,并按照建议完善自己的简历
可以看到具体效果,上传后,会给出具体的建议,优缺点、评分 现在我们就来说一下我们是怎么具体实现的:
一、整体架构:智能招聘应用全景图
先看项目核心路由配置(App.jsx):
javascript
function App() {
return (
<Suspense fallback={<Loading type='ball' className='fixed-loading' />}>
<Routes>
<Route path='/' element={<MainLayout />}>
<Route path='/' element={<Navigate to='/home' />} />
<Route path='/home' element={<Home />} />
{/* 其他路由... */}
</Route>
<Route path='/' element={<Blanklayout />}>
{/* 详情页和简历分析页 */}
<Route path='/detail/:id' element={<Detail />} />
<Route path='/coze' element={<Coze />} />
</Route>
</Routes>
</Suspense>
)
}
应用亮点:
- 瀑布流职位展示(Home页面)渲染招聘信息
- 职位详情页(Detail页面)通过点击不同的招聘页给用户不同的详情页
- AI简历分析(Coze页面)当我们点击AI简历分析的图片,会给用户跳转到AI简历分析的区域
二、职位详情页:不只是展示信息
1. 动态路由与数据获取
通过URL参数获取职位ID,从全局状态中匹配数据:
javascript
const Detail = () => {
const { id } = useParams()
const { jobs } = useJobsStore()
const job = jobs.find(job => job.id === id)
// 设置页面标题
useTitle(`${job.company.name}-${job.title.name} - 职位详情`)
return (/* ... */)
}
2. 精心设计的UI布局
使用CSS Modules实现响应式布局(Detail.module.css):
css
/* 底部固定按钮 */
.detailBotton {
position: fixed;
bottom: -31px;
height: 140px;
width: 100%;
background: white;
}
.detailBotton button {
width: 70%;
height: 50%;
background: #58B282;
border-radius: 40px;
}
3. AI入口:简历分析的关键跳转
在职位描述区域添加AI图标,点击跳转到简历分析页:
ini
<div className={styles.detailBodyFooterAI}>
<img
src={AIPNG}
alt="AI分析简历"
onClick={() => navigate('/coze')}
/>
</div>
考虑到用户点击招聘信息,肯定是有想投递简历的想法,但是用户可能对自己的简历是否还需要优化是不清楚的这个设计让用户在查看职位要求后,能立即进行简历匹配度分析。

三、Coze工作流搭建
主要有四个节点: 输入节点
、OCR 节点多模态模型节点(提取简历中的信息)
、分析节点使用 LLM 节点(对简历进行分析,给出优缺点、建议、打分)
、输出节点

prompt:
OCR多模态大模型
text
系统提示词
你是一个专业的 OCR 引擎,擅长从图像中精准提取文本内容,尤其是简历类文档。你的任务是:
1. 仔细识别图像中的所有文字内容
2. 保持原文的段落、列表和格式结构
3. 按照指定字段结构化输出信息
4. 如果某字段未找到,填写为"未提供"
输出格式必须为 JSON,字段如下:
{
"name": "",
"phone": "",联系方式,手机号码或者邮箱地址
"education": "", //教育经历 是相关学历,毕业哪所学校,是大专还是本科还是硕士多段经历用换行分隔
"word_experience": "", // 每段经历包含公司、职位、时间、职责
"project_experience": "", // 每个项目包含名称、时间、角色、描述
"skill": "", // 列出技能,用逗号分隔
"evaluate": "" // 一些品质的修饰词,自我评价 或"个人总结"或者 "是一个什么样的人"等类似字段
}
请只输出 JSON,不要包含任何额外说明。
用户提示词:
请从以下简历图片中提取信息,并按指定 JSON 格式输出:
{{Image}}] <!-- 这里是图像输入变量 -->
注意:
- 保持时间、职位、公司等关键信息完整
- 工作经历和项目经验请按时间倒序排列
- 如果信息模糊或看不清,请标注"[模糊]"
- 不要进行分析或评价,只做提取
分析节点
json
系统提示词:
你是一位资深的人力资源专家,拥有多年招聘和简历筛选的经验。你的任务是根据提供的简历信息,进行全面而专业的评估,并给出具体的优缺点分析和改进建议。你的回答应该专业、有建设性,并且易于理解。
按照如下示例格式输出
{
"strengths": ["亮点1", "亮点2", "亮点3"], //一定要帮我总结出该简历的亮点或者突出点
"weaknesses": ["问题1", "问题2", "问题3"],//给出所存在的一些问题或者不足点
"suggestions": "",//根据你认为所存在问题或不足点给出具体的修改建议
"score": "",//给该简历进行一个1-10分的评分,要客观可靠
}
注意:输出结果数组里面不要有换行符,这是必须遵循的,还有这些数据一定不能为空
用户提示词
请基于以下简历信息进行评估:
姓名:{{name}}
联系方式:{{phone}}
教育背景:{{education}}
工作经历:{{word_experience}}
项目经验:{{project_experience}}
技能:{{skill}}
自我评价:{{evaluate}}
请从以下几个方面进行评估:
1. ✅ 优点:列出3个亮点
2. ❌ 缺点:指出3个问题(如格式混乱、缺乏量化成果、关键词缺失等)
3. 🛠 修改建议:给出具体的优化建议(如调整结构、补充数据、使用动词开头等)
4. ⭐ 综合评分:满分10分,打几分?
要求:语言简洁、专业、有建设性。
注意:输出结果数组里面不要有换行符,这是必须遵循的,还有这些数据一定不能为空
这样设置prompt可以让每个大模型各司其职,干自己最擅长的事情,保证给用户的体验是最佳的
四、核心亮点:AI简历分析实现
1. 整体流程

2. 文件上传实现
使用FormData处理图片上传:
javascript
async function uploadImageToCoze(imageFile) {
const formData = new FormData();
formData.append("file", imageFile);
const response = await fetch("https://api.coze.cn/v1/files/upload", {
method: "POST",
headers: { "Authorization": `Bearer ${import.meta.env.VITE_COZE_API_KEY}` },
body: formData,
});
const result = await response.json();
return result.data.id; // 返回文件ID
}
coze上传图片,需要先上传至coze服务器,然后转换成id,之后把id给到工作流完成工作 3. 工作流触发与结果处理
核心函数callCozeWorkflowWithImage
:
javascript
async function callCozeWorkflowWithImage(file_id) {
const workflow_id = import.meta.env.VITE_COZE_WORKFLOW_ID;
// 设置加载状态
setLoading(true);
// 调用Coze工作流API
const response = await fetch("https://api.coze.cn/v1/workflow/run", {
method: "POST",
headers: {
"Authorization": `Bearer ${import.meta.env.VITE_COZE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
workflow_id,
parameters: { input: JSON.stringify({ file_id }) }
}),
});
// 处理返回结果
const result = await response.json();
const parsedResult = JSON.parse(result.data);
// 更新状态
setScore(parsedResult.score);
setStrengths(parsedResult.strengths);
setWeaknesses(parsedResult.weaknesses);
setSuggestions(parsedResult.suggestions);
setLoading(false);
}
4. 用户体验优化
上传和分析过程中的加载状态:
bash
{loading ?
<Loading type='ball' className='fixed-loading' /> :
''
}
由于不是流式输出,所以告诉用户正在生成,毕竟前端以服务用户为主
5. 分析结果展示
清晰分类展示分析结果:
javascript
<div>
<h3>{`✅ 优点:`}</h3>
{strengths.map((item, index) =>
<div key={index}>{`${index + 1}. ${item}`}</div>
)}
<h3>{`❌ 缺点:`}</h3>
{weaknesses.map((item, index) =>
<div key={index}>{`${index + 1}. ${item}`}</div>
)}
<h3>{`建议:`}</h3>
{suggestions.map((item, index) =>
<div key={index}>{`${index + 1}. ${item}`}</div>
)}
<h3>{`⭐ 综合评分:满分10分:`}</h3>
{score}
</div>
五、技术难点与解决方案
1. 异步流程管理
问题:文件上传 → 获取ID → 触发工作流 → 解析结果,这个链式异步操作容易陷入回调地狱。
解决方案:
ini
// 清晰的异步操作链
onChange={async (e) => {
const file = e.target.files[0];
const fileId = await uploadImageToCoze(file);
await callCozeWorkflowWithImage(fileId);
}}
2. 数据格式处理
问题:Coze返回的数据是嵌套的JSON字符串
解决方案:双重解析(在这里我是成功踩坑的,一直拿不到想要的数据)
ini
const result = await response.json(); // 第一层解析
const parsedResult = JSON.parse(result.data); // 第二层解析
3. 加载状态管理
问题:长时间操作需要明确反馈
解决方案:使用React状态控制Loading组件
scss
const [loading, setLoading] = useState(false);
// 操作开始
setLoading(true);
// 操作结束
setLoading(false);
六、设计思考:为什么这样实现?
-
分离关注点原则
- Detail页面专注展示职位信息
- Coze页面专注简历分析功能
- 通过路由进行解耦
-
用户体验优先
- 固定底部投递按钮(适配移动端)
- 分析结果分区块展示(视觉清晰)
- 加载动画缓解等待焦虑
-
安全考虑
- API密钥通过环境变量管理
- 敏感操作有明确状态反馈
总结:我学到了什么?
通过这个项目,我深刻理解了:
- 前后端协作:如何与第三方API(Coze)交互
- 异步流程管理:优雅处理链式异步操作
- 状态驱动UI:React状态管理的实际应用
- 模块化设计:组件与页面的合理划分
- 用户体验优化:加载状态、错误处理等细节
最大的收获是:把AI能力集成到传统招聘场景中,可以创造巨大的用户价值 。一个简单的简历分析功能,能让求职者明确改进方向,大幅提升求职效率! 项目代码已在Github开源:https://github.com/dwk-lzd/dwk_ai/tree/main/Boss/Imitate-Boss