jobscout 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -0
- package/bin/cli.mjs +190 -0
- package/chatgpt/GPT-INSTRUCTIONS.md +103 -0
- package/chatgpt/README.md +72 -0
- package/chatgpt/knowledge/job.schema.json +58 -0
- package/chatgpt/knowledge/match.schema.json +48 -0
- package/chatgpt/knowledge/profile.schema.json +121 -0
- package/chatgpt/knowledge/skill-application-assistant.md +38 -0
- package/chatgpt/knowledge/skill-bilingual-normalization.md +46 -0
- package/chatgpt/knowledge/skill-candidate-intake.md +43 -0
- package/chatgpt/knowledge/skill-find-jobs.md +50 -0
- package/chatgpt/knowledge/skill-fit-analyzer.md +37 -0
- package/chatgpt/knowledge/skill-job-collector.md +21 -0
- package/chatgpt/knowledge/skill-job-matcher.md +16 -0
- package/chatgpt/knowledge/skill-job-schema.md +62 -0
- package/chatgpt/knowledge/skill-scoring-rubric.md +108 -0
- package/job-matching-plugin/.claude-plugin/plugin.json +17 -0
- package/job-matching-plugin/.codex-plugin/plugin.json +18 -0
- package/job-matching-plugin/AGENTS.md +55 -0
- package/job-matching-plugin/README.md +84 -0
- package/job-matching-plugin/agents/job-collector.md +40 -0
- package/job-matching-plugin/agents/job-matcher.md +37 -0
- package/job-matching-plugin/commands/find-jobs.md +41 -0
- package/job-matching-plugin/docs/claude-runtime-notes.md +69 -0
- package/job-matching-plugin/schemas/job.schema.json +58 -0
- package/job-matching-plugin/schemas/match.schema.json +48 -0
- package/job-matching-plugin/schemas/profile.schema.json +121 -0
- package/job-matching-plugin/skills/application-assistant/SKILL.md +38 -0
- package/job-matching-plugin/skills/bilingual-normalization/SKILL.md +46 -0
- package/job-matching-plugin/skills/candidate-intake/SKILL.md +43 -0
- package/job-matching-plugin/skills/find-jobs/SKILL.md +50 -0
- package/job-matching-plugin/skills/fit-analyzer/SKILL.md +37 -0
- package/job-matching-plugin/skills/job-collector/SKILL.md +21 -0
- package/job-matching-plugin/skills/job-matcher/SKILL.md +16 -0
- package/job-matching-plugin/skills/job-schema/SKILL.md +62 -0
- package/job-matching-plugin/skills/scoring-rubric/SKILL.md +108 -0
- package/package.json +46 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "profile.schema.json",
|
|
4
|
+
"title": "CandidateProfile",
|
|
5
|
+
"description": "Hồ sơ ứng viên chuẩn hóa từ CV + target. Song ngữ Việt-Anh.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["candidate", "skills", "experience", "seniority", "target"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema_version": { "type": "string", "default": "1.0" },
|
|
10
|
+
"candidate": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"required": ["name"],
|
|
13
|
+
"properties": {
|
|
14
|
+
"name": { "type": "string" },
|
|
15
|
+
"headline": { "type": "string", "description": "Chức danh hiện tại / tự mô tả ngắn" },
|
|
16
|
+
"location": { "type": "string" },
|
|
17
|
+
"summary": { "type": "string" },
|
|
18
|
+
"languages": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"items": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"language": { "type": "string" },
|
|
24
|
+
"level": { "type": "string", "enum": ["basic", "conversational", "professional", "native"] }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"skills": {
|
|
31
|
+
"type": "array",
|
|
32
|
+
"description": "Kỹ năng đã chuẩn hóa (dùng canonical EN name qua bilingual-normalization).",
|
|
33
|
+
"items": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": ["name"],
|
|
36
|
+
"properties": {
|
|
37
|
+
"name": { "type": "string", "description": "Canonical name, ưu tiên EN, vd 'React'" },
|
|
38
|
+
"aliases": { "type": "array", "items": { "type": "string" } },
|
|
39
|
+
"category": { "type": "string", "description": "vd 'frontend', 'backend', 'data', 'soft-skill'" },
|
|
40
|
+
"years": { "type": "number" },
|
|
41
|
+
"level": { "type": "string", "enum": ["beginner", "intermediate", "advanced", "expert"] },
|
|
42
|
+
"evidence": { "type": "string", "description": "Trích từ CV làm bằng chứng" }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"experience": {
|
|
47
|
+
"type": "array",
|
|
48
|
+
"items": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"required": ["title"],
|
|
51
|
+
"properties": {
|
|
52
|
+
"title": { "type": "string" },
|
|
53
|
+
"company": { "type": "string" },
|
|
54
|
+
"start": { "type": "string", "description": "YYYY-MM" },
|
|
55
|
+
"end": { "type": "string", "description": "YYYY-MM hoặc 'present'" },
|
|
56
|
+
"duration_months": { "type": "integer" },
|
|
57
|
+
"domain": { "type": "string", "description": "vd 'fintech', 'e-commerce'" },
|
|
58
|
+
"highlights": { "type": "array", "items": { "type": "string" } }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"education": {
|
|
63
|
+
"type": "array",
|
|
64
|
+
"items": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"properties": {
|
|
67
|
+
"degree": { "type": "string" },
|
|
68
|
+
"field": { "type": "string" },
|
|
69
|
+
"school": { "type": "string" },
|
|
70
|
+
"year": { "type": "string" }
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"total_years": { "type": "number", "description": "Tổng số năm kinh nghiệm liên quan" },
|
|
75
|
+
"seniority": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"enum": ["intern", "junior", "mid", "senior", "lead", "manager", "director"],
|
|
78
|
+
"description": "Suy ra từ total_years + phạm vi trách nhiệm"
|
|
79
|
+
},
|
|
80
|
+
"domains": { "type": "array", "items": { "type": "string" }, "description": "Ngành/lĩnh vực đã làm" },
|
|
81
|
+
"target": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"description": "Mong muốn của ứng viên. priorities dùng để override trọng số scoring.",
|
|
84
|
+
"required": ["desired_roles"],
|
|
85
|
+
"properties": {
|
|
86
|
+
"desired_roles": { "type": "array", "items": { "type": "string" } },
|
|
87
|
+
"desired_level": { "type": "string", "enum": ["intern", "junior", "mid", "senior", "lead", "manager", "director"] },
|
|
88
|
+
"locations": { "type": "array", "items": { "type": "string" } },
|
|
89
|
+
"remote_preference": { "type": "string", "enum": ["onsite", "hybrid", "remote", "any"], "default": "any" },
|
|
90
|
+
"salary": {
|
|
91
|
+
"type": "object",
|
|
92
|
+
"properties": {
|
|
93
|
+
"min": { "type": "number" },
|
|
94
|
+
"target": { "type": "number" },
|
|
95
|
+
"currency": { "type": "string", "enum": ["VND", "USD"], "default": "VND" },
|
|
96
|
+
"period": { "type": "string", "enum": ["month", "year"], "default": "month" }
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"industries": { "type": "array", "items": { "type": "string" } },
|
|
100
|
+
"company_size": { "type": "array", "items": { "type": "string", "enum": ["startup", "sme", "enterprise", "any"] } },
|
|
101
|
+
"dealbreakers": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"description": "Điều kiện loại trừ cứng (hard filter). Vd 'no onsite ngoài HCM', 'không outsource'.",
|
|
104
|
+
"items": { "type": "string" }
|
|
105
|
+
},
|
|
106
|
+
"priorities": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"description": "Trọng số 0-1 ứng viên khai; override default trong scoring-rubric. Tổng nên ~1.",
|
|
109
|
+
"properties": {
|
|
110
|
+
"skills": { "type": "number" },
|
|
111
|
+
"seniority": { "type": "number" },
|
|
112
|
+
"domain": { "type": "number" },
|
|
113
|
+
"location": { "type": "number" },
|
|
114
|
+
"compensation": { "type": "number" },
|
|
115
|
+
"culture": { "type": "number" }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: application-assistant
|
|
3
|
+
description: Tùy chỉnh (tailor) nội dung CV và viết cover letter cho một job cụ thể dựa trên profile và JD. Dùng khi ứng viên đã chọn được job muốn apply và cần chuẩn bị hồ sơ.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Application Assistant — tailor hồ sơ theo job
|
|
7
|
+
|
|
8
|
+
Đầu vào: `profile.json` + 1 job (từ jobs.json hoặc URL/JD dán vào) + (tùy chọn) MatchResult để biết gaps.
|
|
9
|
+
Đầu ra: bản nháp CV bullets đã điều chỉnh và/hoặc cover letter.
|
|
10
|
+
|
|
11
|
+
## Tailor CV bullets
|
|
12
|
+
|
|
13
|
+
- Chọn và viết lại các highlight kinh nghiệm sao cho khớp `must_have_skills` và trách nhiệm chính của JD.
|
|
14
|
+
- Dùng canonical skill name khớp với từ khóa JD (giúp qua ATS).
|
|
15
|
+
- Định lượng thành tích (số liệu) khi CV có dữ liệu; **không bịa** số hay kinh nghiệm không có.
|
|
16
|
+
- Nêu rõ chỗ nào là gap (missing must-have) và cách trình bày trung thực (vd "đang học", kinh nghiệm chuyển giao).
|
|
17
|
+
|
|
18
|
+
## Cover letter & Email ứng tuyển
|
|
19
|
+
|
|
20
|
+
- Áp skill `cover-letter-writing` (nếu có) cho style. Cấu trúc: mở đầu (vì sao công ty/role này), thân (2–3 bằng chứng khớp yêu cầu), kết (call to action).
|
|
21
|
+
- Giọng văn phù hợp ngôn ngữ JD (vi/en/mixed). Ngắn gọn (~250–350 từ).
|
|
22
|
+
- Cá nhân hóa theo company (tránh mẫu chung chung).
|
|
23
|
+
|
|
24
|
+
## Tin nhắn tiếp cận trực tiếp HR (Email / LinkedIn / Zalo)
|
|
25
|
+
|
|
26
|
+
Khi JD có kênh liên hệ trực tiếp và ứng viên muốn chủ động tiếp cận HR:
|
|
27
|
+
|
|
28
|
+
**Mẫu Direct Message / Email ngắn**:
|
|
29
|
+
> "Chào anh/chị [Tên HR/Recruiter], em thấy tin tuyển [Tên vị trí] của [Công ty]. Em có [X năm] kinh nghiệm về [Top 2-3 kỹ năng khớp], từng làm [Dự án/Sản phẩm tiêu biểu]. Em rất quan tâm vị trí này. Em xin gửi kèm CV: [Link CV] để anh/chị tiện xem qua ạ. Cảm ơn anh/chị!"
|
|
30
|
+
|
|
31
|
+
Điều chỉnh giọng văn theo kênh (email trang trọng hơn, LinkedIn/Zalo ngắn gọn hơn).
|
|
32
|
+
|
|
33
|
+
## Ranh giới quan trọng
|
|
34
|
+
|
|
35
|
+
- **Không bịa** bằng cấp, kinh nghiệm, con số. Chỉ diễn đạt lại sự thật trong CV cho hấp dẫn hơn.
|
|
36
|
+
- Đây là bản nháp để ứng viên xem lại và tự chỉnh; nêu rõ điều đó.
|
|
37
|
+
- Không tự gửi email/nộp hồ sơ thay ứng viên.
|
|
38
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bilingual-normalization
|
|
3
|
+
description: Chuẩn hóa kỹ năng, chức danh, địa điểm và lương giữa tiếng Việt và tiếng Anh về dạng canonical, phục vụ so khớp job/CV chính xác. Dùng khi parse CV, chuẩn hóa JD, hoặc so khớp skills/lương trong scoring.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Bilingual Normalization — chuẩn hóa Việt–Anh
|
|
7
|
+
|
|
8
|
+
Mục tiêu: mọi so khớp diễn ra trên **canonical name** thống nhất, tránh trượt vì khác ngôn ngữ/cách viết.
|
|
9
|
+
|
|
10
|
+
## Skills — canonical name
|
|
11
|
+
|
|
12
|
+
- Canonical ưu tiên tên tiếng Anh phổ biến của công nghệ: `React`, `Node.js`, `Java`, `Python`, `Kubernetes`...
|
|
13
|
+
- Gộp biến thể: `ReactJS`/`React.js`/`Reactjs` → `React`; `NodeJS` → `Node.js`; `K8s` → `Kubernetes`; `.NET`/`dotnet` → `.NET`.
|
|
14
|
+
- Chức năng mô tả bằng tiếng Việt → canonical EN:
|
|
15
|
+
- "Lập trình viên" / "Kỹ sư phần mềm" → Software Engineer
|
|
16
|
+
- "Trưởng nhóm" → Lead ; "Quản lý dự án" → Project Manager
|
|
17
|
+
- "Kiểm thử" / "QC" → QA ; "Phân tích nghiệp vụ" → Business Analyst
|
|
18
|
+
- "Khoa học dữ liệu" → Data Science ; "Kỹ sư dữ liệu" → Data Engineer
|
|
19
|
+
- Giữ `aliases[]` trong profile/job để truy vết.
|
|
20
|
+
|
|
21
|
+
## Chức danh & cấp bậc (seniority)
|
|
22
|
+
|
|
23
|
+
- Map cấp bậc VN → thang chuẩn: Fresher→junior, "Chuyên viên"→mid, "Senior/Kỹ sư cao cấp"→senior, "Trưởng nhóm/Team Lead"→lead, "Trưởng phòng"→manager, "Giám đốc"→director.
|
|
24
|
+
- Cẩn thận với "Senior" gắn năm kinh nghiệm khác nhau giữa công ty — ưu tiên `min_years` nếu có.
|
|
25
|
+
|
|
26
|
+
## Địa điểm
|
|
27
|
+
|
|
28
|
+
- Chuẩn hóa: "TP.HCM"/"Sài Gòn"/"HCMC"/"Ho Chi Minh" → "Ho Chi Minh City"; "HN"/"Hà Nội" → "Hanoi"; "ĐN"/"Đà Nẵng" → "Da Nang".
|
|
29
|
+
- Nhận diện remote: "làm việc từ xa"/"remote" → remote; "linh hoạt"/"hybrid" → hybrid.
|
|
30
|
+
|
|
31
|
+
## Lương — giữ nguyên gốc, chỉ quy đổi khi cần so sánh
|
|
32
|
+
|
|
33
|
+
- **Luôn giữ nguyên đơn vị & giá trị gốc** trong `job.salary` (currency đúng như JD). Ví dụ JD ghi "$1000" → lưu USD 1000; ghi "26 triệu" → lưu VND 26,000,000. Không tự đổi khi lưu trữ hay hiển thị.
|
|
34
|
+
- Đơn vị Việt:
|
|
35
|
+
- "15 triệu"/"15tr"/"15M" → 15,000,000 VND.
|
|
36
|
+
- "15-20 triệu"/"15-20M" → min 15tr, max 20tr.
|
|
37
|
+
- "Gross" / "Net" → parse giá trị số bình thường (ghi chú trong description nếu cần).
|
|
38
|
+
- "Thỏa thuận"/"Cạnh tranh"/"Negotiable"/"Deal" → không set số, `negotiable=true`, currency=unknown.
|
|
39
|
+
- USD: "$1500"/"1500 USD" → USD. "Up to $2000"/"Upto $2k" → max=2000, currency=USD.
|
|
40
|
+
- **Chỉ khi cần so sánh** (chấm điểm compensation, so hai job khác đơn vị): quy đổi tạm về VND/tháng bằng tỉ giá cố định **$1 = 26,100 VND**; year→month chia 12. Giá trị quy đổi này chỉ dùng nội bộ lúc tính toán, KHÔNG ghi đè giá trị gốc.
|
|
41
|
+
|
|
42
|
+
## Nguyên tắc
|
|
43
|
+
|
|
44
|
+
- Chỉ map khi chắc chắn; nếu không rõ, giữ nguyên và ghi vào aliases để không mất thông tin.
|
|
45
|
+
- Không "dịch" tên riêng công ty.
|
|
46
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: candidate-intake
|
|
3
|
+
description: Parse CV của ứng viên (PDF/DOCX/text) và thu thập target/mong muốn để tạo profile.json chuẩn. Dùng khi bắt đầu một phiên tìm việc, khi người dùng cung cấp CV mới, hoặc muốn cập nhật mục tiêu nghề nghiệp.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Candidate Intake — tạo profile ứng viên
|
|
7
|
+
|
|
8
|
+
Đầu ra: một file `data/profiles/<slug>.json` tuân theo `./schemas/profile.schema.json`.
|
|
9
|
+
|
|
10
|
+
## Bước 1 — Đọc CV
|
|
11
|
+
|
|
12
|
+
- Trích text từ CV:
|
|
13
|
+
- **PDF** → Claude Code: dùng skill `pdf` (anthropic-skills). Codex/CLI: `pdftotext cv.pdf -` (poppler) hoặc `python -c "import pypdf; ..."`. Không có tool → yêu cầu người dùng dán nội dung CV.
|
|
14
|
+
- **DOCX** → Claude Code: skill `docx`. Codex/CLI: `python -c "import docx; ..."` (python-docx) hoặc unzip đọc `word/document.xml`.
|
|
15
|
+
- **Text/Markdown** → đọc trực tiếp.
|
|
16
|
+
- Trích: thông tin cá nhân tối thiểu (tên, headline, location), kỹ năng, kinh nghiệm (title/công ty/thời gian/highlights), học vấn, ngôn ngữ.
|
|
17
|
+
- Suy `total_years` và `seniority` từ tổng thời gian + phạm vi trách nhiệm.
|
|
18
|
+
|
|
19
|
+
## Bước 2 — Chuẩn hóa (song ngữ)
|
|
20
|
+
|
|
21
|
+
- Áp skill `bilingual-normalization`: đưa skills & chức danh về canonical name, chuẩn hóa location.
|
|
22
|
+
- Với mỗi skill, cố gắng gắn `years`/`level`/`evidence` từ CV (không bịa — thiếu thì để trống).
|
|
23
|
+
|
|
24
|
+
## Bước 3 — Thu thập target
|
|
25
|
+
|
|
26
|
+
Hỏi ứng viên (gộp câu hỏi, đừng hỏi lẻ tẻ). Nếu người dùng đã nêu sẵn trong hội thoại thì dùng luôn, chỉ hỏi phần còn thiếu:
|
|
27
|
+
|
|
28
|
+
1. **Vai trò mong muốn** (desired_roles) + cấp bậc (desired_level).
|
|
29
|
+
2. **Địa điểm** + hình thức (onsite/hybrid/remote/any).
|
|
30
|
+
3. **Lương kỳ vọng** (min & target, VND hay USD, tháng/năm).
|
|
31
|
+
4. **Ngành** ưu tiên + **quy mô công ty**.
|
|
32
|
+
5. **Dealbreakers** — điều tuyệt đối không chấp nhận.
|
|
33
|
+
6. **Ưu tiên** (priorities): cái gì quan trọng nhất? (lương / kỹ năng phù hợp / địa điểm / ngành / văn hóa). Chuyển thành trọng số 0–1 cho `target.priorities` (tổng ~1) — đây là dữ liệu quan trọng cho `scoring-rubric`.
|
|
34
|
+
|
|
35
|
+
## Bước 4 — Ghi file & Xác nhận
|
|
36
|
+
- Ghi `profile.json` đúng schema. Đặt tên slug từ tên ứng viên (không dấu, kebab-case).
|
|
37
|
+
- Tóm tắt lại cho người dùng xác nhận: seniority suy ra, top skills, target, và trọng số priorities. Cho phép chỉnh trước khi sang bước collector.
|
|
38
|
+
|
|
39
|
+
## Nguyên tắc
|
|
40
|
+
|
|
41
|
+
- Không bịa kỹ năng/kinh nghiệm không có trong CV.
|
|
42
|
+
- Nếu CV thiếu năm tháng cụ thể, ước lượng và ghi rõ là ước lượng.
|
|
43
|
+
- Tôn trọng riêng tư: chỉ lưu thông tin cần cho matching; không đưa dữ liệu cá nhân ra ngoài.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: find-jobs
|
|
3
|
+
description: Chạy full pipeline tìm việc song ngữ Việt–Anh — parse CV, thu thập job (web search), chấm điểm, xuất báo cáo fit/gap. Dùng khi người dùng muốn "tìm job cho tôi" từ một CV hoặc profile đã có.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# find-jobs — điều phối full pipeline tìm việc
|
|
7
|
+
|
|
8
|
+
Skill điều phối, chạy tuần tự 4 bước. Đối số là đường dẫn CV (PDF/DOCX/text) hoặc tên
|
|
9
|
+
profile đã có trong `data/profiles/`.
|
|
10
|
+
|
|
11
|
+
Dùng `<run-id>` duy nhất theo mẫu `<candidate-slug>-<YYYYMMDD-HHMMSS>-<suffix>` và giữ nguyên
|
|
12
|
+
ID này xuyên suốt pipeline. Tạo `data/profiles`, `data/jobs`, `data/results` trong thư mục làm việc
|
|
13
|
+
nếu chưa có.
|
|
14
|
+
|
|
15
|
+
> **Yêu cầu (bước 2 — thu thập job):**
|
|
16
|
+
> - **Claude Code**: `WebSearch`/`WebFetch` có sẵn — không cần cấu hình.
|
|
17
|
+
> - **Codex**: cần bật `web_search` bằng `codex --search` hoặc `tools.web_search = true` trong `~/.codex/config.toml`. Nếu chưa bật, dừng ở bước 2 và báo người dùng.
|
|
18
|
+
|
|
19
|
+
## Bước 1 — Intake → profile.json
|
|
20
|
+
Áp skill **`candidate-intake`**.
|
|
21
|
+
- Nếu đối số là file CV → parse và tạo `data/profiles/<slug>.json` theo `schemas/profile.schema.json`.
|
|
22
|
+
- Nếu là tên profile đã tồn tại → dùng lại, hỏi có cập nhật target không.
|
|
23
|
+
- Thu thập/xác nhận target: vai trò, cấp bậc, địa điểm/remote, lương, priorities (→ trọng số), dealbreakers.
|
|
24
|
+
- Tóm tắt cho người dùng xác nhận.
|
|
25
|
+
|
|
26
|
+
## Bước 2 — Collect → data/jobs/<run-id>.json
|
|
27
|
+
Spawn một subagent context riêng và yêu cầu nó áp skill **`job-collector`**; không phụ thuộc custom
|
|
28
|
+
agent cài ngoài plugin.
|
|
29
|
+
- Truyền đường dẫn `profile.json`, `<run-id>` và output `data/jobs/<run-id>.json`.
|
|
30
|
+
- **Nguồn Job Boards**: Quét từ ITviec, TopCV, VietnamWorks, LinkedIn...
|
|
31
|
+
- Giữ job thỏa mãn tiêu chuẩn: chỉ giữ job xem được full JD & còn hạn. Tối đa 20 job hợp lệ.
|
|
32
|
+
|
|
33
|
+
## Bước 3 — Match → data/results/<run-id>.shortlist.json
|
|
34
|
+
Spawn một subagent context riêng và yêu cầu nó áp skill **`job-matcher`** (chấm điểm bulk).
|
|
35
|
+
- Truyền `profile.json` + `data/jobs/<run-id>.json`.
|
|
36
|
+
- Chấm điểm theo skill **`scoring-rubric`**, dùng trọng số từ `target.priorities`.
|
|
37
|
+
|
|
38
|
+
## Bước 4 — Fit report → data/results/<run-id>.fit_report.md
|
|
39
|
+
Áp skill **`fit-analyzer`**.
|
|
40
|
+
- Bảng xếp hạng: **mọi job đều có link nộp CV (url) bấm được**; phân tích chi tiết top 20 (hoặc toàn bộ).
|
|
41
|
+
- Báo đường dẫn file báo cáo cho người dùng.
|
|
42
|
+
|
|
43
|
+
## Sau khi xong
|
|
44
|
+
Đề xuất bước tiếp: tailor hồ sơ cho job top (skill `application-assistant`), hoặc mở rộng
|
|
45
|
+
nguồn (remote quốc tế / thành phố khác).
|
|
46
|
+
|
|
47
|
+
## Nguyên tắc
|
|
48
|
+
- Không bịa dữ liệu job/CV. Thiếu → unknown, hạ confidence.
|
|
49
|
+
- Tôn trọng robots/ToS khi scrape; không vượt anti-bot/CAPTCHA.
|
|
50
|
+
- Không tự nộp hồ sơ thay người dùng.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fit-analyzer
|
|
3
|
+
description: Với các job trong shortlist, giải thích mức độ phù hợp, khoảng cách kỹ năng/kinh nghiệm, rủi ro, và gợi ý cải thiện — dạng báo cáo dễ đọc cho ứng viên. Dùng sau khi job-matcher đã tạo shortlist.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fit Analyzer — báo cáo phù hợp & khoảng cách
|
|
7
|
+
|
|
8
|
+
Đầu vào: `profile.json` + `data/results/<run-id>.shortlist.json` (mảng MatchResult + job tương ứng).
|
|
9
|
+
Đầu ra: `data/results/<run-id>.fit_report.md`.
|
|
10
|
+
|
|
11
|
+
## Phạm vi báo cáo (QUAN TRỌNG)
|
|
12
|
+
|
|
13
|
+
Phân tích chi tiết **TẤT CẢ job trong shortlist**, không rút gọn còn top 3. Nếu shortlist có nhiều hơn **20** job thì phân tích chi tiết 20 job điểm cao nhất và vẫn liệt kê đủ phần còn lại trong bảng xếp hạng. Có thể thêm mục "🏆 Ưu tiên apply ngay" (2–3 job) ở đầu như phần tóm tắt, nhưng **phần thân báo cáo vẫn phải có block chi tiết cho từng job** (không bỏ job nào).
|
|
14
|
+
|
|
15
|
+
## Nội dung báo cáo
|
|
16
|
+
|
|
17
|
+
Với **mỗi** job (theo thứ tự điểm giảm dần), trình bày:
|
|
18
|
+
|
|
19
|
+
1. **Header**: `#N. Title @ Company` — overall_score, recommendation, **link nộp CV (url)**, lương, location/remote, hạn nộp (nếu có).
|
|
20
|
+
- Nếu JD có kênh liên hệ trực tiếp (email, phone, Zalo, form): hiển thị rõ.
|
|
21
|
+
2. **Vì sao hợp** (2–3 gạch đầu dòng): điểm mạnh khớp — matched_skills chính, domain, seniority, lương.
|
|
22
|
+
3. **Khoảng cách** (gaps): missing_must_have + gaps[] kèm severity. Nói rõ cái nào là "học nhanh được" vs "cần thời gian".
|
|
23
|
+
4. **Rủi ro / cần xác minh**:
|
|
24
|
+
- Nếu `confidence` thấp → khuyến nghị đọc kỹ JD gốc; overqualified/underqualified; lương unknown.
|
|
25
|
+
5. **Hành động đề xuất**: Apply qua link / Chuẩn bị hồ sơ. Nếu muốn chủ động liên hệ HR (email/LinkedIn/Zalo), dùng skill `application-assistant` để lấy tin nhắn mẫu.
|
|
26
|
+
|
|
27
|
+
## Tổng quan đầu báo cáo
|
|
28
|
+
|
|
29
|
+
- Bảng xếp hạng: rank | title | company | score | recommendation | lương | location | **link nộp CV**. **MỌI job trong bảng đều phải có link (url) bấm được** — không chỉ các job top. Dùng markdown link (vd `[Nộp CV](url)`).
|
|
30
|
+
- Nhận xét chung: xu hướng thị trường quan sát được, gap lặp lại nhiều lần (gợi ý kỹ năng nên học), có nên nới target không (vd lương kỳ vọng quá cao so với mặt bằng).
|
|
31
|
+
|
|
32
|
+
## Nguyên tắc
|
|
33
|
+
|
|
34
|
+
- Trung thực: nếu match yếu, nói thẳng; đừng thổi phồng.
|
|
35
|
+
- Ưu tiên hành động cụ thể hơn nhận xét chung chung.
|
|
36
|
+
- Song ngữ khi cần (thuật ngữ giữ tiếng Anh, giải thích tiếng Việt).
|
|
37
|
+
- Không tạo kỳ vọng sai về khả năng trúng tuyển.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: job-collector
|
|
3
|
+
description: Thu thập và chuẩn hóa việc làm từ web search. Dùng trong bước collect của pipeline find-jobs sau khi đã có profile ứng viên.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Job Collector
|
|
7
|
+
|
|
8
|
+
Nhận đường dẫn `profile.json`, `run_id` duy nhất và đường dẫn output. Thu thập tối đa 20 job hợp lệ, chuẩn hóa theo `job-schema`, rồi ghi vào `data/jobs/<run_id>.json`.
|
|
9
|
+
|
|
10
|
+
## Nguồn dữ liệu
|
|
11
|
+
|
|
12
|
+
- Job boards: dùng web search/fetch sẵn có của host. Chỉ giữ job đọc được JD và chưa có bằng chứng hết hạn.
|
|
13
|
+
|
|
14
|
+
## Contract
|
|
15
|
+
|
|
16
|
+
1. Đọc profile và sinh query song ngữ từ role, seniority, location và skills.
|
|
17
|
+
2. Khử trùng theo URL chuẩn hóa; ưu tiên nguồn gốc và dữ liệu mới hơn.
|
|
18
|
+
3. Ghi object theo `schemas/job.schema.json`, đặt `extraction_confidence` trung thực.
|
|
19
|
+
4. Trả số lượng thu được, số bị loại và cảnh báo dữ liệu thiếu.
|
|
20
|
+
|
|
21
|
+
Không tự nộp hồ sơ, không vượt CAPTCHA/anti-bot và không ghi đè output của run khác.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: job-matcher
|
|
3
|
+
description: Chấm điểm và xếp hạng danh sách job so với profile ứng viên. Dùng trong bước match của pipeline find-jobs sau khi collector đã tạo jobs JSON.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Job Matcher
|
|
7
|
+
|
|
8
|
+
Nhận `profile.json`, `data/jobs/<run_id>.json` và output `data/results/<run_id>.shortlist.json`.
|
|
9
|
+
|
|
10
|
+
1. Khử trùng job theo `id`, giữ bản có `extraction_confidence` cao hơn.
|
|
11
|
+
2. Áp `scoring-rubric` và `bilingual-normalization` cho từng job.
|
|
12
|
+
3. Chuẩn hóa mọi bộ trọng số, kể cả mặc định, để tổng bằng 1 trước khi tính điểm.
|
|
13
|
+
4. Hard-filter dealbreakers chỉ khi có đủ bằng chứng; thiếu dữ liệu thì hạ confidence.
|
|
14
|
+
5. Ghi mảng `{match, job_ref}` theo `schemas/match.schema.json`, sắp xếp giảm dần và để excluded cuối.
|
|
15
|
+
|
|
16
|
+
Luôn ghi `weights_used`, rationale và các gap; không thổi phồng recommendation.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: job-schema
|
|
3
|
+
description: Schema chuẩn cho một tin tuyển dụng (job) và cách map dữ liệu thô từ search/scrape vào schema đó. Dùng bởi job-collector khi chuẩn hóa JD, và job-matcher khi đọc job.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Job Schema — chuẩn hóa tin tuyển dụng
|
|
7
|
+
|
|
8
|
+
Schema chính: `./schemas/job.schema.json`. Skill này hướng dẫn cách điền cho nhất quán.
|
|
9
|
+
|
|
10
|
+
## Quy tắc bắt buộc
|
|
11
|
+
|
|
12
|
+
- `id`: tạo hash ổn định. Ưu tiên chuẩn hóa URL (bỏ query tracking) rồi hash; nếu không có URL sạch, hash chuỗi `company|title|location` (lowercase, bỏ dấu). Dùng để **khử trùng lặp** giữa các nguồn.
|
|
13
|
+
- `source`: định danh nguồn ngắn gọn: `itviec`, `topcv`, `vietnamworks`, `linkedin`, `careerviet`, `google`, ...
|
|
14
|
+
- `collected_at`: ISO timestamp.
|
|
15
|
+
- `extraction_confidence` (0–1):
|
|
16
|
+
- **Cao** (0.8–1.0): đọc được full JD từ trang tuyển dụng chính thống hoặc link JD mở.
|
|
17
|
+
- **Thấp** (≤0.4): chỉ có snippet rời rạc từ kết quả tìm kiếm không đủ thông tin.
|
|
18
|
+
|
|
19
|
+
## Chuẩn hóa các trường
|
|
20
|
+
|
|
21
|
+
- **skills** (`must_have_skills`, `nice_to_have_skills`): đưa về canonical name qua skill `bilingual-normalization` (vd "ReactJS", "React.js" → "React").
|
|
22
|
+
- **salary**: parse cả tiếng Việt ("15-20 triệu", "thỏa thuận", "Up to $2000", "range 30-50m") → {min, max, currency, period, negotiable}. "Thỏa thuận"/"Negotiable" → currency=unknown, negotiable=true.
|
|
23
|
+
- **remote**: nhận diện "remote", "làm việc từ xa", "hybrid", "onsite", "tại văn phòng".
|
|
24
|
+
- **seniority**: suy từ title/JD ("Junior", "Senior", "Trưởng nhóm"→lead, "Fresher"→junior).
|
|
25
|
+
- **company**: Nếu JD không nêu rõ tên cty (stealth startup, headhunter tuyển hộ) → ghi `Confidential (<lĩnh vực>)` hoặc tên agency (vd `Confidential (Fintech HCM)`).
|
|
26
|
+
- **contact**: Trích xuất kênh liên hệ ứng tuyển nếu JD có:
|
|
27
|
+
- `email`: email nhận CV (vd `hr@company.com`).
|
|
28
|
+
- `phone`: số điện thoại liên hệ.
|
|
29
|
+
- `form_url`: link Google Form / Typeform nộp hồ sơ.
|
|
30
|
+
- `how_to_apply`: tóm tắt ngắn (vd `"Gửi CV qua email hr@..."`, `"Apply qua link"`).
|
|
31
|
+
- **language**: `vi`/`en`/`mixed` tùy JD.
|
|
32
|
+
- **min_years**: parse "2+ năm kinh nghiệm", "at least 3 years".
|
|
33
|
+
|
|
34
|
+
## Nguyên tắc chống bịa
|
|
35
|
+
|
|
36
|
+
- Chỉ điền trường khi có bằng chứng trong dữ liệu nguồn. Không suy đoán lương/quy mô công ty nếu JD không nói → để `unknown`.
|
|
37
|
+
- `url` luôn là link trang tuyển dụng gốc để người dùng bấm vào apply.
|
|
38
|
+
- Rút gọn `description` nếu quá dài (giữ phần requirements + trách nhiệm chính).
|
|
39
|
+
|
|
40
|
+
## Ví dụ tin tuyển dụng chuẩn (Full JD)
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"id": "a1b2c3",
|
|
45
|
+
"title": "Senior Frontend Developer (ReactJS)",
|
|
46
|
+
"company": "ABC Tech",
|
|
47
|
+
"location": "Ho Chi Minh City",
|
|
48
|
+
"remote": "hybrid",
|
|
49
|
+
"url": "https://itviec.com/it-jobs/senior-frontend-abc",
|
|
50
|
+
"source": "itviec",
|
|
51
|
+
"language": "mixed",
|
|
52
|
+
"requirements": {
|
|
53
|
+
"must_have_skills": ["React", "TypeScript"],
|
|
54
|
+
"nice_to_have_skills": ["Next.js"],
|
|
55
|
+
"min_years": 3,
|
|
56
|
+
"seniority": "senior"
|
|
57
|
+
},
|
|
58
|
+
"salary": { "min": 30000000, "max": 45000000, "currency": "VND", "period": "month" },
|
|
59
|
+
"collected_at": "2026-08-25T10:00:00Z",
|
|
60
|
+
"extraction_confidence": 0.9
|
|
61
|
+
}
|
|
62
|
+
```
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scoring-rubric
|
|
3
|
+
description: Công thức chấm điểm mức độ khớp giữa 1 job và profile ứng viên. Dùng bởi job-matcher và bất kỳ nơi nào cần đánh giá độ phù hợp job/CV. Định nghĩa trọng số, cách tính từng chiều, hard filter (dealbreakers), và cách xử lý dữ liệu thiếu.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Scoring Rubric — chấm điểm khớp job ↔ profile
|
|
7
|
+
|
|
8
|
+
Đây là "bộ não" quyết định chất lượng match. Kết quả tuân theo `./schemas/match.schema.json`.
|
|
9
|
+
|
|
10
|
+
## Nguyên tắc
|
|
11
|
+
|
|
12
|
+
1. Điểm mỗi chiều thang **0–100**, độc lập.
|
|
13
|
+
2. `overall_score` = tổng có trọng số của các chiều, **trừ** khi có dealbreaker (→ excluded).
|
|
14
|
+
3. Minh bạch: luôn ghi `weights_used`, `matched_skills`, `missing_must_have`, `rationale`.
|
|
15
|
+
4. Dữ liệu thiếu KHÔNG bị chấm 0 một cách mù quáng — xem mục "Xử lý dữ liệu thiếu".
|
|
16
|
+
|
|
17
|
+
## Bước 0 — Hard filter (dealbreakers)
|
|
18
|
+
|
|
19
|
+
Trước khi chấm điểm, kiểm tra `profile.target.dealbreakers` và các ràng buộc cứng:
|
|
20
|
+
|
|
21
|
+
- Vi phạm bất kỳ dealbreaker → `recommendation = "excluded"`, `overall_score = 0`, ghi vào `dealbreaker_violations`. **Không** tính tiếp.
|
|
22
|
+
- Ví dụ dealbreaker cứng thường gặp: location ngoài vùng chấp nhận (khi remote=onsite), loại hình công ty bị loại (outsource), lương max < salary.min của ứng viên (khi có đủ dữ liệu).
|
|
23
|
+
- Nếu dữ liệu không đủ để khẳng định vi phạm (vd lương "unknown") → KHÔNG loại, hạ `confidence` thay vì exclude.
|
|
24
|
+
|
|
25
|
+
## Trọng số mặc định
|
|
26
|
+
|
|
27
|
+
| Chiều | Mặc định | Ý nghĩa |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| skills | 0.35 | Khớp kỹ năng must-have / nice-to-have |
|
|
30
|
+
| seniority | 0.20 | Cấp bậc & số năm kinh nghiệm |
|
|
31
|
+
| domain | 0.15 | Ngành/lĩnh vực |
|
|
32
|
+
| location | 0.05 | Địa điểm & hình thức remote |
|
|
33
|
+
| compensation | 0.15 | Lương so với kỳ vọng |
|
|
34
|
+
| culture | 0.05 | Quy mô/loại hình công ty, tín hiệu văn hóa |
|
|
35
|
+
|
|
36
|
+
**Bắt buộc chuẩn hóa:** cả bộ trọng số mặc định và bộ `profile.target.priorities` override đều phải
|
|
37
|
+
được chia cho tổng thực tế trước khi tính điểm, để tổng `weights_used` luôn bằng 1. Bộ số mặc định
|
|
38
|
+
trên chủ ý thể hiện tỷ lệ tương đối; không được dùng trực tiếp khi tổng chưa bằng 1. Luôn ghi bộ đã
|
|
39
|
+
chuẩn hóa vào `weights_used`.
|
|
40
|
+
|
|
41
|
+
## Cách tính từng chiều
|
|
42
|
+
|
|
43
|
+
### skills (0–100)
|
|
44
|
+
- Chuẩn hóa mọi skill về canonical name (dùng skill `bilingual-normalization`) trước khi so khớp.
|
|
45
|
+
- `must_cover` = tỉ lệ must-have của job mà profile đáp ứng.
|
|
46
|
+
- `nice_cover` = tỉ lệ nice-to-have đáp ứng.
|
|
47
|
+
- `skills_score = 100 * (0.75 * must_cover + 0.25 * nice_cover)`.
|
|
48
|
+
- Cộng thưởng nhẹ nếu ứng viên có skill level `advanced/expert` cho must-have chính (tối đa +10, cap 100).
|
|
49
|
+
- Nếu job không nêu must-have (`must_have_skills` rỗng) → suy từ title + description; hạ `confidence`.
|
|
50
|
+
- Ghi `matched_skills` và `missing_must_have`.
|
|
51
|
+
|
|
52
|
+
### seniority (0–100)
|
|
53
|
+
- So `profile.seniority` với `job.requirements.seniority` (map thang: intern<junior<mid<senior<lead<manager<director).
|
|
54
|
+
- Khoảng cách 0 bậc → 100; 1 bậc → 75; 2 bậc → 45; ≥3 bậc → 15.
|
|
55
|
+
- **Overqualified** (ứng viên cao hơn job ≥2 bậc) cũng bị trừ (dễ bị loại/chán việc): áp cùng thang khoảng cách.
|
|
56
|
+
- Điều chỉnh bằng `min_years`: nếu `total_years < min_years` → nhân 0.6; nếu thừa nhiều năm → không thưởng.
|
|
57
|
+
- Nếu job seniority = unknown → suy từ min_years/title; hạ confidence.
|
|
58
|
+
|
|
59
|
+
### domain (0–100)
|
|
60
|
+
- Trùng ngành trong `profile.domains`/`target.industries` với `job.industry` → 100.
|
|
61
|
+
- Ngành liền kề/chuyển giao được (adjacent) → 60.
|
|
62
|
+
- Không liên quan → 30 (không phải 0, vì kỹ năng có thể chuyển ngành).
|
|
63
|
+
|
|
64
|
+
### location (0–100)
|
|
65
|
+
- remote=remote và ứng viên chấp nhận remote/any → 100.
|
|
66
|
+
- Job location nằm trong `target.locations` → 100.
|
|
67
|
+
- hybrid + cùng thành phố → 85.
|
|
68
|
+
- onsite khác thành phố nhưng ứng viên để "any" → 60.
|
|
69
|
+
- onsite ngoài vùng chấp nhận (chưa tới mức dealbreaker) → 25.
|
|
70
|
+
|
|
71
|
+
### compensation (0–100)
|
|
72
|
+
- Cần đưa về cùng đơn vị (VND/tháng) — dùng `bilingual-normalization` để quy đổi USD↔VND & year↔month.
|
|
73
|
+
- job_mid = trung bình (min,max). So với `target.salary.target` (hoặc min).
|
|
74
|
+
- job_mid ≥ target → 100; trong khoảng [min, target] → nội suy 70–100; dưới min nhưng ≥ 90% min → 50; thấp hơn → 20.
|
|
75
|
+
- Lương unknown → điểm neutral 60, hạ confidence (KHÔNG chấm 0).
|
|
76
|
+
|
|
77
|
+
### culture (0–100)
|
|
78
|
+
- Khớp `target.company_size` → +40 baseline lên; tín hiệu tích cực trong JD (đãi ngộ, lộ trình, tech stack hiện đại) cộng thêm.
|
|
79
|
+
- Ít dữ liệu → 60 neutral.
|
|
80
|
+
|
|
81
|
+
## Xử lý dữ liệu thiếu
|
|
82
|
+
|
|
83
|
+
- Không bao giờ chấm 0 vì "thiếu thông tin" — dùng điểm **neutral** (55–60) và **giảm `confidence`**.
|
|
84
|
+
- `confidence` tổng của match ≈ trung bình có trọng số của `job.extraction_confidence` và độ đầy đủ dữ liệu các chiều.
|
|
85
|
+
- Match có confidence < 0.4 nên được đánh dấu "cần xác minh JD" trong rationale.
|
|
86
|
+
|
|
87
|
+
## Tổng hợp & khuyến nghị
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
normalized_weight[d] = weight[d] / Σ weight
|
|
91
|
+
overall = Σ (dimension_score[d] * normalized_weight[d]) với d ∈ 6 chiều
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Map sang `recommendation`:
|
|
95
|
+
|
|
96
|
+
| overall | recommendation |
|
|
97
|
+
|---|---|
|
|
98
|
+
| ≥ 80 | strong |
|
|
99
|
+
| 65–79 | good |
|
|
100
|
+
| 50–64 | maybe |
|
|
101
|
+
| < 50 | weak |
|
|
102
|
+
| (dealbreaker) | excluded |
|
|
103
|
+
|
|
104
|
+
## Đầu ra
|
|
105
|
+
|
|
106
|
+
Trả về đúng `./schemas/match.schema.json`: overall_score, recommendation, dimension_scores, weights_used, matched_skills, missing_must_have, gaps[], dealbreaker_violations[], rationale, confidence.
|
|
107
|
+
|
|
108
|
+
`rationale` viết ngắn, cụ thể, song ngữ nếu cần — nêu 1–2 lý do mạnh nhất và 1 gap lớn nhất.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "job-matching",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Tìm và xếp hạng job phù hợp nhất với target + CV của ứng viên. Pipeline: parse CV → thu thập job (chỉ job xem được & còn hạn) → chấm điểm theo rubric → báo cáo fit/gap. Song ngữ Việt-Anh.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Nguyen Trong Hieu",
|
|
7
|
+
"email": "hieutrong512@gmail.com"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"job-matching",
|
|
11
|
+
"recruitment",
|
|
12
|
+
"cv",
|
|
13
|
+
"career",
|
|
14
|
+
"vietnam",
|
|
15
|
+
"ai-agents"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "job-matching",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Tìm và xếp hạng việc làm phù hợp với mục tiêu nghề nghiệp và CV song ngữ Việt–Anh, thu thập job từ web search.",
|
|
5
|
+
"author": {"name": "Nguyen Trong Hieu", "email": "hieutrong512@gmail.com"},
|
|
6
|
+
"keywords": ["jobs", "career", "cv", "vietnam"],
|
|
7
|
+
"skills": "./skills/",
|
|
8
|
+
"interface": {
|
|
9
|
+
"displayName": "JobMatching",
|
|
10
|
+
"shortDescription": "Tìm và xếp hạng việc làm phù hợp từ CV",
|
|
11
|
+
"longDescription": "Pipeline song ngữ Việt–Anh để đọc CV, thu thập việc làm từ web search, chấm điểm và tạo báo cáo mức độ phù hợp.",
|
|
12
|
+
"developerName": "JobMatching",
|
|
13
|
+
"category": "Productivity",
|
|
14
|
+
"capabilities": ["Read", "Write", "Interactive"],
|
|
15
|
+
"defaultPrompt": ["Tìm việc làm phù hợp từ CV này.", "Phân tích CV và tạo danh sách việc làm phù hợp nhất."],
|
|
16
|
+
"brandColor": "#2563EB"
|
|
17
|
+
}
|
|
18
|
+
}
|