기준 코드: api/main.py, src/state/slices/url_exchanger.py
- Base URL:
http://localhost:8000 - Content-Type:
application/json - 인증: 없음
- CORS: 모든 Origin 허용
- 자동 문서:
GET /docsGET /openapi.json
- 요청 본문은 정의된 필드만 허용한다.
- 정의되지 않은 필드를 보내면
422 Unprocessable Entity가 반환된다. - 응답의 선택 필드는 값이 없으면
null로 반환된다. /query는 내부적으로query기본값을user_input과 동일하게 사용한다./query는 내부적으로 검색 개수 기본값을5로 사용한다.
서버 상태 확인용 엔드포인트다.
- Body 없음
200 OK
{
"status": "ok"
}curl -s http://localhost:8000/health자연어 채용 검색 요청을 받아 엔티티 추출, 정규화, URL 생성, 크롤링, 검색, 응답 생성을 수행한다.
Content-Type: application/json| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
user_input |
string |
Y | 사용자의 자연어 검색 문장 |
{
"user_input": "서울 AI 엔지니어 신입 고졸 채용공고 찾아줘."
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
user_input |
string |
Y | 원본 사용자 입력 |
query |
string |
Y | 실제 검색 질의 |
status |
string |
Y | complete 또는 incomplete |
message |
string | null |
N | 추가 안내 문구 |
entities |
object | null |
N | 원본 엔티티 추출 결과 |
entities.지역 |
string |
N | 추출된 지역 |
entities.직무 |
string |
N | 추출된 직무 |
entities.경력 |
string |
N | 추출된 경력 |
entities.학력 |
string |
N | 추출된 학력 |
지역 |
string | null |
N | 상태에 저장된 지역 값 |
직무 |
string | null |
N | 상태에 저장된 직무 값 |
경력 |
string | null |
N | 상태에 저장된 경력 값 |
학력 |
string | null |
N | 상태에 저장된 학력 값 |
missing_fields |
string[] | null |
N | 누락된 필수 슬롯 목록 |
normalized_entities |
object | null |
N | 정규화된 엔티티 |
normalized_entities.지역 |
string | null |
N | 정규화된 지역 |
normalized_entities.직무 |
string | null |
N | 정규화된 직무 |
normalized_entities.경력 |
string | null |
N | 정규화된 경력 |
normalized_entities.학력 |
string | null |
N | 정규화된 학력 |
url |
string | null |
N | 생성된 사람인 검색 URL |
crawled_count |
integer | null |
N | 수집한 공고 수 |
job_info_list |
string[] | null |
N | 파싱된 전체 공고 텍스트 목록 |
retrieved_job_info_list |
string[] | null |
N | 검색 상위 공고 텍스트 목록 |
retrieved_scores |
number[] | null |
N | 검색 점수 목록 |
user_response |
string | null |
N | 최종 사용자 응답 문장 |
status |
설명 |
|---|---|
incomplete |
필수 슬롯(지역, 직무, 경력, 학력)이 부족해서 검색을 중단한 상태 |
complete |
검색과 응답 생성까지 완료한 상태 |
200 OK
{
"user_input": "백엔드 신입 채용공고 찾아줘",
"query": "백엔드 신입 채용공고 찾아줘",
"status": "incomplete",
"message": "지역, 학력 정보를 알려주세요.",
"entities": {
"지역": "",
"직무": "백엔드",
"경력": "신입",
"학력": ""
},
"지역": "",
"직무": "백엔드",
"경력": "신입",
"학력": "",
"missing_fields": [
"지역",
"학력"
],
"normalized_entities": {
"지역": null,
"직무": "백엔드/서버개발",
"경력": "신입",
"학력": null
},
"url": null,
"crawled_count": null,
"job_info_list": null,
"retrieved_job_info_list": null,
"retrieved_scores": null,
"user_response": null
}200 OK
{
"user_input": "서울 AI 엔지니어 신입 고졸 채용공고 찾아줘.",
"query": "서울 AI 엔지니어 신입 고졸 채용공고 찾아줘.",
"status": "complete",
"message": null,
"entities": {
"지역": "서울",
"직무": "AI 엔지니어",
"경력": "신입",
"학력": "고졸"
},
"지역": "서울",
"직무": "AI 엔지니어",
"경력": "신입",
"학력": "고졸",
"missing_fields": null,
"normalized_entities": {
"지역": "서울",
"직무": "인공지능/머신러닝",
"경력": "신입",
"학력": "고등학교졸업이상"
},
"url": "https://www.saramin.co.kr/zf_user/search?...",
"crawled_count": 12,
"job_info_list": [
"********** ... 전체 공고 텍스트 ..."
],
"retrieved_job_info_list": [
"********** ... 상위 공고 텍스트 ..."
],
"retrieved_scores": [
0.91,
0.87,
0.82,
0.79,
0.75
],
"user_response": "서울 지역 신입 AI 엔지니어 채용공고를 우선순위로 정리하면 다음과 같습니다..."
}422 Unprocessable Entity
{
"detail": [
{
"loc": [
"body",
"user_input"
],
"msg": "Field required",
"type": "missing"
}
]
}curl -sS -X POST http://localhost:8000/query \
-H "Content-Type: application/json" \
-d '{"user_input":"서울 AI 엔지니어 신입 고졸 채용공고 찾아줘."}'검색 작업을 비동기로 접수한다. 요청은 즉시 큐에 적재되고 job_id를 반환한다.
Content-Type: application/json| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
user_input |
string |
Y | 사용자의 자연어 검색 문장 |
202 Accepted
{
"job_id": "abc123",
"jobId": "abc123",
"status": "queued",
"step": "queued",
"step_label": "대기열 처리 중",
"message": null,
"result": null
}jobId는 기존 클라이언트 호환용 필드다.
422 Unprocessable Entity
{
"detail": [
{
"loc": ["body", "user_input"],
"msg": "Field required",
"type": "missing"
}
]
}curl -sS -X POST http://localhost:8000/query/jobs \
-H "Content-Type: application/json" \
-d '{"user_input":"서울 백엔드 신입 대졸 채용공고 찾아줘"}'비동기 검색 작업 상태를 조회한다.
queued -> running -> done | failed
| 필드 | 타입 | 설명 |
|---|---|---|
job_id |
string |
작업 ID(기본 키) |
jobId |
string |
레거시 호환 키(값 동일) |
status |
string |
queued / running / done / failed |
step |
string | null |
진행 단계(queued, analyzing, collecting, parsing, ranking, writing) |
step_label |
string | null |
단계 라벨 |
message |
string | null |
실패 또는 안내 메시지 |
result |
object | null |
done일 때 최종 검색 결과 |
200 OK
{
"job_id": "abc123",
"jobId": "abc123",
"status": "running",
"step": "collecting",
"step_label": "공고 수집 중",
"message": null,
"result": null
}200 OK
{
"job_id": "abc123",
"jobId": "abc123",
"status": "done",
"step": null,
"step_label": null,
"message": null,
"result": {
"user_input": "서울 백엔드 신입 대졸 채용공고 찾아줘",
"query": "서울 백엔드 신입 대졸 채용공고 찾아줘",
"status": "complete",
"message": null
}
}200 OK
{
"job_id": "abc123",
"jobId": "abc123",
"status": "failed",
"step": null,
"step_label": null,
"message": "job failed"
}404 Not Found
{
"message": "job not found"
}curl -sS http://localhost:8000/query/jobs/abc123| 경로 | 설명 |
|---|---|
GET /docs |
Swagger UI |
GET /openapi.json |
OpenAPI JSON |