Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# TechCase

서비스 링크: [https://techcase.dadamda.site/](https://techcase.dadamda.site/)

TechCase는 기업 기술 블로그를 기반으로, 개발자가 새로운 기술 스택 도입이나 기술적 이슈 해결을 고민할 때 실제 기업 적용 사례를 빠르게 탐색할 수 있도록 돕는 기술 사례 검색 서비스입니다.

기존 기술 블로그 모음 서비스는 여러 글을 한곳에서 볼 수 있다는 장점이 있지만, 검색 품질이 단순 키워드 매칭에 머무르는 경우가 많습니다. 예를 들어 Kafka, Kubernetes, Terraform, Redis, Elasticsearch 같은 기술을 검색하더라도 해당 키워드가 포함된 글만 나열될 뿐, 그 기술이 어떤 문제를 해결하기 위해 도입되었는지, 어떤 아키텍처 안에서 사용되었는지, 실제 서비스 맥락에서 어떤 의미를 가졌는지 파악하기 어렵습니다.
Expand Down
5 changes: 5 additions & 0 deletions apps/backend/app/keywords/dictionaries.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ class KeywordRule:
KeywordRule("Spring Boot", "technology", ("spring boot", "springboot", "스프링 부트")),
KeywordRule("JPA", "technology", ("jpa", "java persistence api")),
KeywordRule("LLM", "technology", ("llm", "large language model", "대규모 언어 모델")),
KeywordRule(
"OpenAI Codex",
"technology",
("openai codex", "codex", "codex cli", "openai codex cli"),
),
KeywordRule(
"RAG",
"architecture",
Expand Down
18 changes: 18 additions & 0 deletions apps/backend/app/search/evaluation/queries.json
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,24 @@
}
]
},
{
"id": "technology-openai-codex",
"query": "codex",
"category": "technology",
"intent": "OpenAI Codex와 Codex CLI를 활용한 AI 코딩 에이전트, 코드 리뷰, 개발 자동화 사례를 찾는다.",
"expectedResults": [
{
"url": "https://techblog.musinsa.com/ai-%EC%8A%A4%ED%8E%98%EC%85%9C%EB%A6%AC%EC%8A%A4%ED%8A%B8%EC%99%80-%EC%9E%90%EB%8F%99%EC%82%AC%EB%83%A5-%ED%95%98%EB%84%A4%EC%8A%A4%EB%A1%9C-%EC%A0%9C%EC%96%B4%ED%95%98%EB%8A%94-ai-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8-6c578f8bd1fb?source=rss----f107b03c406e---4",
"title": "AI 스페셜리스트와 자동사냥 - 하네스로 제어하는 AI 파이프라인",
"relevance": 3
},
{
"url": "https://meetup.nhncloud.com/posts/407",
"title": "2025 프론트엔드 뉴스 한 방에 몰아 보기 : NHN Cloud Meetup",
"relevance": 2
}
]
},
{
"id": "architecture-rag",
"query": "rag",
Expand Down
28 changes: 28 additions & 0 deletions apps/backend/tests/test_search_query_rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from app.search.service import build_search_query, expand_query, matched_rule_keywords


def test_codex_matches_openai_codex_keyword() -> None:
assert matched_rule_keywords("codex") == ["OpenAI Codex"]
assert expand_query("codex") == "codex openai codex"


def test_codex_search_does_not_use_fuzzy_matching() -> None:
query = build_search_query("codex")

assert not contains_key(query, "fuzziness")


def test_generic_code_search_keeps_fuzzy_fallback() -> None:
query = build_search_query("code")

assert contains_key(query, "fuzziness")


def contains_key(value: object, key: str) -> bool:
if isinstance(value, dict):
return key in value or any(contains_key(child, key) for child in value.values())

if isinstance(value, list):
return any(contains_key(child, key) for child in value)

return False