
"RAG로 특허 기반 기술동향 리포트 생성하기"
지난 글에서는 기업별 특허 포트폴리오 벡터를 만드는 방법을 정리했다. 개별 특허 임베딩을 기업 단위로 평균화하면 기업별 기술 포지션을 표현할 수 있고, 기업 간 기술 유사도를 계산해 경쟁구도를 분석할 수 있었다.
이번 글에서는 검색 기반 분석을 한 단계 더 확장한다.
지금까지는 특허를 벡터화하고, 유사 특허를 찾고, 기술군을 분류하고, 기업별 포트폴리오를 비교하는 방식으로 분석했다. 하지만 실제 기술조사나 기술평가에서는 단순히 유사 특허 목록만 필요한 것이 아니다.
중요한 것은 다음 질문에 답하는 것이다.
이 기술 분야에서 반복적으로 등장하는 문제는 무엇인가?
기업들은 어떤 방식으로 문제를 해결하려고 하는가?
최근 특허들은 어떤 기술 방향으로 발전하고 있는가?
특정 기술군에서 주요 출원인은 누구인가?
이 기술은 사업화 또는 기술평가 관점에서 어떤 의미를 갖는가?
이런 질문에 답하기 위해서는 검색된 특허들을 근거로 기술동향 리포트를 작성해야 한다.
이번 글에서는 이를 위해 RAG 구조를 사용한다.
1. RAG란 무엇인가
RAG는 Retrieval-Augmented Generation의 약자다.
한국어로 풀어 쓰면 검색 증강 생성 정도로 이해할 수 있다.
쉽게 말하면 다음과 같은 구조다.
사용자 질문
↓
관련 문서 검색
↓
검색된 문서를 근거로 제공
↓
LLM이 근거를 바탕으로 답변 생성
즉, LLM이 자기 기억만으로 답변하는 것이 아니라, 먼저 관련 문서를 검색한 뒤 그 문서를 근거로 답변하게 만드는 방식이다.
특허 분석에서 RAG가 중요한 이유는 명확하다.
특허 문서는 전문적이고, 기술적이며, 근거 확인이 중요하다.
LLM이 그냥 “이 기술은 이런 방향입니다”라고 말하면 신뢰하기 어렵다.
하지만 관련 특허의 제목과 초록을 먼저 검색하고, 그 문헌을 근거로 리포트를 작성하게 하면 답변의 근거성을 높일 수 있다.
2. 이번 글에서 구현할 RAG 구조
이번 글에서는 완전한 RAG 시스템을 만들지는 않는다.
LLM API까지 연결하면 난이도가 갑자기 올라가기 때문이다.
따라서 이번 글에서는 초보자도 따라갈 수 있도록 다음 단계까지만 구현한다.
1. 특허 데이터셋 생성
2. 특허 텍스트 임베딩 생성
3. 사용자 질문 입력
4. 질문과 유사한 특허 검색
5. 검색된 특허를 Context로 정리
6. LLM에 넣을 Report Prompt 생성
즉, 이번 글의 목표는 다음과 같다.
사용자의 기술 질문에 대해 관련 특허를 검색하고, 검색된 특허를 바탕으로 기술동향 리포트를 작성할 수 있는 프롬프트를 자동 생성한다.
전체 구조는 다음과 같다.
User Query
↓
Query Embedding
↓
Patent Embedding Search
↓
Top-K Patent Retrieval
↓
Context Construction
↓
Report Prompt Generation
↓
LLM-based Report
이번 글에서는 마지막 LLM 호출은 하지 않고, 바로 이전 단계인 Report Prompt 생성까지 다룬다.
3. 실험용 특허 데이터 만들기
먼저 샘플 특허 데이터를 만든다.
이번에도 Anomaly Detection 관련 특허 데이터를 사용한다.
import pandas as pd
data = [
{
"patent_id": "P001",
"title": "Method for anomaly detection in manufacturing equipment",
"abstract": "A method includes collecting sensor data and detecting abnormal states using a trained machine learning model.",
"applicant": "AlphaTech",
"domain": "Manufacturing"
},
{
"patent_id": "P002",
"title": "System for fault diagnosis of industrial machines",
"abstract": "The invention relates to diagnosing machine faults based on vibration and temperature sensor data.",
"applicant": "AlphaTech",
"domain": "Manufacturing"
},
{
"patent_id": "P003",
"title": "Predictive maintenance method using machine learning",
"abstract": "Provided is a method for predicting equipment failure by analyzing time-series sensor signals.",
"applicant": "BetaSystems",
"domain": "Manufacturing"
},
{
"patent_id": "P004",
"title": "Defect detection method for visual inspection",
"abstract": "A computer vision method detects defects in product images using a neural network.",
"applicant": "VisionAI",
"domain": "Vision Inspection"
},
{
"patent_id": "P005",
"title": "Image-based quality inspection system",
"abstract": "A system identifies defective products by analyzing captured images with a deep learning model.",
"applicant": "VisionAI",
"domain": "Vision Inspection"
},
{
"patent_id": "P006",
"title": "Abnormal transaction detection system",
"abstract": "A system detects abnormal financial transactions using historical transaction patterns and machine learning.",
"applicant": "FinGuard",
"domain": "Finance"
},
{
"patent_id": "P007",
"title": "Medical anomaly detection using patient monitoring data",
"abstract": "A system detects abnormal patient conditions by analyzing physiological time-series signals.",
"applicant": "MediSense",
"domain": "Healthcare"
},
{
"patent_id": "P008",
"title": "Battery fault detection system",
"abstract": "A battery management system detects abnormal voltage and temperature patterns to prevent battery failure.",
"applicant": "EnergyCell",
"domain": "Battery"
},
{
"patent_id": "P009",
"title": "Thermal runaway prediction for battery packs",
"abstract": "A method predicts thermal runaway risk by analyzing temperature, voltage, and current signals of battery cells.",
"applicant": "EnergyCell",
"domain": "Battery"
}
]
df = pd.DataFrame(data)
df.head()
<코드 해설>
import pandas as pd
pandas는 표 형태의 데이터를 다루기 위한 Python 라이브러리다.
엑셀이나 CSV처럼 행과 열로 구성된 데이터를 처리할 때 사용한다.
data = [...]
여기서는 실제 특허 데이터를 불러오기 전에, 실험용 샘플 데이터를 직접 만든다.
각 특허는 patent_id, title, abstract, applicant, domain 정보를 가진다.
df = pd.DataFrame(data)
리스트 형태의 데이터를 pandas DataFrame으로 변환한다.
DataFrame은 Python에서 엑셀 표처럼 데이터를 다룰 수 있게 해주는 구조다.
df.head()
데이터프레임의 앞부분을 확인한다.
데이터가 제대로 만들어졌는지 확인하는 용도다.
4. 분석용 텍스트 만들기
RAG 검색을 위해서는 각 특허를 하나의 분석용 텍스트로 만들어야 한다.
이번에도 Title과 Abstract를 결합한다.
df["analysis_text"] = df["title"] + " " + df["abstract"]
df[["patent_id", "analysis_text"]].head()
<코드 해설>
df["analysis_text"]
DataFrame에 새로운 열을 만든다.
열 이름은 analysis_text다.
df["title"] + " " + df["abstract"]
특허 제목과 초록을 하나로 합친다.
중간의 " "는 제목과 초록 사이에 공백을 넣기 위한 것이다.
즉, 하나의 특허는 다음과 같은 형태의 텍스트가 된다.
Method for anomaly detection in manufacturing equipment
A method includes collecting sensor data and detecting abnormal states...
이 텍스트가 검색의 기본 단위가 된다.
5. Sentence-BERT로 특허 임베딩 만들기
이제 특허 텍스트를 숫자 벡터로 변환한다.
Google Colab에서는 먼저 패키지를 설치해야 한다.
!pip install sentence-transformers
그 다음 모델을 불러온다.
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
특허 텍스트를 임베딩으로 변환한다.
texts = df["analysis_text"].tolist()
patent_embeddings = model.encode(texts)
patent_embeddings.shape
<코드 해설>
!pip install sentence-transformers
Sentence-BERT 모델을 사용하기 위한 라이브러리를 설치한다.
Google Colab에서는 앞에 !를 붙이면 터미널 명령어를 실행할 수 있다.
from sentence_transformers import SentenceTransformer
sentence-transformers 라이브러리에서 SentenceTransformer 클래스를 불러온다.
model = SentenceTransformer("all-MiniLM-L6-v2")
사전학습된 문장 임베딩 모델을 불러온다.
이 모델은 문장을 읽고 그 의미를 숫자 벡터로 변환해준다.
texts = df["analysis_text"].tolist()
analysis_text 열을 Python 리스트로 변환한다.
모델은 텍스트 리스트를 입력으로 받기 때문이다.
patent_embeddings = model.encode(texts)
특허 텍스트들을 임베딩 벡터로 변환한다.
각 특허는 하나의 숫자 벡터가 된다.
patent_embeddings.shape
임베딩 결과의 크기를 확인한다.
예를 들어 결과가 다음과 같다면,
(9, 384)
9개의 특허가 각각 384차원 벡터로 변환되었다는 뜻이다.
6. 사용자 질문 입력하기
RAG에서는 사용자의 질문도 임베딩으로 변환해야 한다.
예를 들어 다음과 같은 질문을 입력한다고 하자.
query = "What are the main technical trends in battery anomaly detection?"
이 질문은 배터리 이상탐지 기술동향을 묻는 질문이다.
질문도 특허와 같은 방식으로 임베딩한다.
query_embedding = model.encode([query])
query_embedding.shape
<코드 해설>
query = "What are the main technical trends in battery anomaly detection?"
사용자가 입력한 질문이다.
여기서는 배터리 이상탐지 기술동향을 묻는 질문을 예시로 사용한다.
model.encode([query])
질문을 임베딩으로 변환한다.
여기서 query를 대괄호 [ ]로 감싼 이유는 모델이 여러 문장을 한 번에 받을 수 있기 때문이다.
query_embedding.shape
질문 임베딩의 크기를 확인한다.
예상 결과는 다음과 같다.
(1, 384)
질문 1개가 384차원 벡터로 변환되었다는 의미다.
7. 질문과 유사한 특허 검색하기
이제 질문 임베딩과 특허 임베딩 간 유사도를 계산한다.
from sklearn.metrics.pairwise import cosine_similarity
similarities = cosine_similarity(query_embedding, patent_embeddings)
similarities
<코드 해설>
from sklearn.metrics.pairwise import cosine_similarity
Cosine Similarity를 계산하기 위한 함수를 불러온다.
cosine_similarity(query_embedding, patent_embeddings)
질문 벡터와 모든 특허 벡터 간 유사도를 계산한다.
질문이 하나이고 특허가 9개라면 결과는 다음과 같은 형태가 된다.
[[0.31, 0.28, 0.34, 0.22, 0.20, 0.18, 0.25, 0.71, 0.78]]
이 값은 질문과 각 특허가 얼마나 의미적으로 가까운지를 나타낸다.
값이 클수록 질문과 관련성이 높은 특허다.
8. Top-K 관련 특허 추출하기
이제 유사도가 높은 특허를 순서대로 가져온다.
import numpy as np
top_k = 3
similarity_scores = similarities[0]
top_indices = np.argsort(similarity_scores)[::-1][:top_k]
top_indices
<코드 해설>
import numpy as np
numpy는 숫자 계산을 위한 Python 라이브러리다.
여기서는 유사도 점수를 정렬하기 위해 사용한다.
top_k = 3
가장 관련성 높은 특허 3개를 가져오겠다는 의미다.
similarity_scores = similarities[0]
similarities는 2차원 배열 형태다.
질문이 하나이기 때문에 첫 번째 행만 가져온다.
np.argsort(similarity_scores)
유사도 점수를 작은 값부터 큰 값 순서로 정렬했을 때의 index를 반환한다.
[::-1]
정렬 순서를 뒤집는다.
즉, 큰 값부터 작은 값 순서가 된다.
[:top_k]
상위 3개만 선택한다.
결과는 예를 들어 다음과 같을 수 있다.
[8, 7, 2]
이는 8번, 7번, 2번 행에 있는 특허가 질문과 가장 관련성이 높다는 의미다.
9. 검색 결과를 표로 정리하기
이제 검색된 특허를 보기 쉽게 정리한다.
retrieved_patents = df.iloc[top_indices].copy()
retrieved_patents["similarity"] = similarity_scores[top_indices]
retrieved_patents[["patent_id", "title", "applicant", "domain", "similarity"]]
<코드 해설>
df.iloc[top_indices]
DataFrame에서 top_indices에 해당하는 행을 가져온다.
즉, 질문과 가장 유사한 특허들을 가져오는 코드다.
.copy()
검색 결과를 별도의 DataFrame으로 복사한다.
원본 df를 건드리지 않기 위해 사용한다.
retrieved_patents["similarity"] = similarity_scores[top_indices]
검색된 특허마다 유사도 점수를 추가한다.
retrieved_patents[["patent_id", "title", "applicant", "domain", "similarity"]]
필요한 열만 선택해서 보기 좋게 출력한다.
예상 결과는 다음과 같은 형태다.
patent_id | title | applicant | domain | similarity
P009 | Thermal runaway prediction for battery packs | EnergyCell | Battery | 0.78
P008 | Battery fault detection system | EnergyCell | Battery | 0.71
P003 | Predictive maintenance method using ML | BetaSystems| Manufacturing | 0.34
이 결과를 보면 질문이 배터리 이상탐지였기 때문에 배터리 관련 특허가 상위에 검색된 것을 확인할 수 있다.
10. 검색된 특허를 Context로 만들기
RAG에서 중요한 것은 검색 결과를 LLM이 읽을 수 있는 Context로 만드는 것이다.
Context는 “답변의 근거가 되는 문서 묶음”이라고 볼 수 있다.
context_blocks = []
for _, row in retrieved_patents.iterrows():
block = f"""
Patent ID: {row['patent_id']}
Title: {row['title']}
Applicant: {row['applicant']}
Domain: {row['domain']}
Abstract: {row['abstract']}
Similarity: {row['similarity']:.3f}
"""
context_blocks.append(block)
context = "\n---\n".join(context_blocks)
print(context)
<코드 해설>
context_blocks = []
검색된 특허 정보를 하나씩 저장할 빈 리스트를 만든다.
for _, row in retrieved_patents.iterrows():
검색된 특허를 한 줄씩 반복해서 읽는다.
row에는 특허 하나의 정보가 들어간다.
block = f""" ... """
특허 하나를 LLM이 읽기 쉬운 텍스트 블록으로 만든다.
{row['patent_id']}
row에서 patent_id 값을 가져와 문자열 안에 넣는다.
f-string 문법을 사용한 것이다.
context_blocks.append(block)
특허 하나의 텍스트 블록을 리스트에 추가한다.
context = "\n---\n".join(context_blocks)
여러 특허 블록을 ---로 구분해서 하나의 긴 Context로 합친다.
이렇게 만들어진 Context는 LLM에게 전달할 근거 문서가 된다.
11. 리포트 생성용 Prompt 만들기
이제 사용자 질문과 검색된 특허 Context를 결합해 리포트 생성용 Prompt를 만든다.
prompt = f"""
You are a technology intelligence analyst.
User Question:
{query}
Retrieved Patent Context:
{context}
Task:
Based only on the retrieved patent context, write a technical trend report.
Report Structure:
1. Key technical problems
2. Main solution approaches
3. Repeated technical patterns
4. Major applicants
5. Technology evaluation implications
6. Limitations of the analysis
Important Rules:
- Do not invent information not supported by the patent context.
- Mention Patent IDs when referring to evidence.
- If the context is insufficient, clearly state the limitation.
"""
print(prompt)
<코드 해설>
prompt = f""" ... """
LLM에게 전달할 명령문을 만든다.
User Question:
{query}
사용자가 입력한 질문을 Prompt 안에 넣는다.
Retrieved Patent Context:
{context}
검색된 특허 문헌 정보를 Prompt 안에 넣는다.
LLM은 이 내용을 근거로 리포트를 작성하게 된다.
Task:
Based only on the retrieved patent context, write a technical trend report.
LLM에게 수행할 작업을 명확히 지시한다.
여기서는 검색된 특허 Context만 근거로 기술동향 리포트를 작성하라고 지시한다.
Report Structure:
1. Key technical problems
...
리포트의 목차를 지정한다.
이렇게 하면 결과물이 일관된 형식으로 나온다.
Important Rules:
- Do not invent information not supported by the patent context.
가장 중요한 부분이다.
LLM이 검색된 특허에 없는 내용을 만들어내지 않도록 제한한다.
이 단계까지 오면 RAG의 기본 구조가 완성된다.
LLM API를 연결하지 않더라도, 이 Prompt를 ChatGPT에 붙여넣으면 검색된 특허 기반 기술동향 리포트를 작성할 수 있다.
12. 생성될 리포트의 형태
위 Prompt를 사용하면 리포트는 대략 다음과 같은 형태로 생성될 수 있다.
1. Key technical problems
검색된 특허들은 배터리 이상상태를 조기에 감지하고, 열폭주 또는 고장 위험을 예측하는 문제를 다룬다. P008은 전압 및 온도 패턴을 활용해 배터리 고장을 감지하는 시스템을 제안하며, P009는 온도, 전압, 전류 신호를 분석해 열폭주 위험을 예측하는 방법을 다룬다.
2. Main solution approaches
주요 접근 방식은 센서 데이터 기반 이상 패턴 분석이다. 배터리 셀의 온도, 전압, 전류 데이터를 활용해 정상 상태와 이상 상태를 구분하고, 고장 또는 열폭주 가능성을 사전에 판단하는 구조가 반복적으로 나타난다.
3. Repeated technical patterns
반복적으로 나타나는 패턴은 다음과 같다.
- 온도·전압·전류 데이터 활용
- 이상 패턴 탐지
- 고장 또는 열폭주 사전 예측
- 배터리 관리 시스템과의 연계
4. Major applicants
검색된 문헌에서는 EnergyCell이 배터리 이상탐지 및 열폭주 예측 관련 특허를 보유한 주요 출원인으로 나타난다.
5. Technology evaluation implications
기술평가 관점에서는 센서 데이터의 신뢰성, 이상상태 판단 알고리즘의 정확도, 실제 배터리 관리 시스템 적용 가능성, 안전성 검증 수준을 확인할 필요가 있다.
6. Limitations of the analysis
본 분석은 검색된 일부 특허 문헌에 기반하므로 전체 배터리 이상탐지 기술동향을 대표한다고 보기 어렵다. 또한 초록 중심 분석이므로 청구항 기반 권리범위 검토는 추가로 필요하다.
이런 식으로 RAG는 검색된 특허를 근거로 리포트 초안을 생성할 수 있다.
13. RAG에서 중요한 것은 검색 품질이다
RAG에서 LLM이 아무리 좋아도 검색 결과가 나쁘면 답변도 나빠진다.
이를 흔히 다음과 같이 표현할 수 있다.
Garbage In, Garbage Out
즉, 잘못된 특허가 Context로 들어가면 LLM은 잘못된 근거를 바탕으로 리포트를 작성할 수 있다.
특허 RAG에서 검색 품질을 높이려면 다음을 고려해야 한다.
검색 품질 개선 방법
1. Title + Abstract뿐 아니라 Claims도 일부 포함한다.
2. Sentence-BERT 모델을 특허 도메인에 맞게 교체한다.
3. 검색 결과를 Cross-Encoder Reranker로 재정렬한다.
4. IPC/CPC 필터를 함께 사용한다.
5. 유사도 점수가 너무 낮은 특허는 제외한다.
6. 검색된 특허의 원문을 사람이 검토한다.
즉, RAG의 핵심은 생성이 아니라 검색이다.
LLM은 리포트를 작성하는 역할을 하지만, 어떤 문헌을 근거로 넣을지는 검색 시스템이 결정한다.
14. 특허 RAG에서 Hallucination을 줄이는 방법
LLM을 사용할 때 가장 큰 문제 중 하나는 Hallucination이다.
Hallucination은 모델이 근거 없는 내용을 그럴듯하게 만들어내는 현상이다.
특허 분석에서는 이 문제가 특히 위험하다.
특허의 기술 내용, 권리범위, 출원인, 효과를 잘못 설명하면 분석 결과의 신뢰도가 떨어진다.
이를 줄이기 위해 Prompt에 다음 규칙을 넣는 것이 좋다.
Hallucination 방지 규칙
1. 검색된 특허 Context에 있는 내용만 사용한다.
2. 추론한 내용은 추론이라고 표시한다.
3. Patent ID를 근거로 함께 제시한다.
4. Context에 없는 내용은 없다고 말한다.
5. 권리범위 판단은 청구항 원문 검토가 필요하다고 명시한다.
특히 아래 문장은 Prompt에 항상 넣는 것이 좋다.
Do not invent information not supported by the patent context.
If the context is insufficient, clearly state the limitation.
AI가 모르는 것을 모른다고 말하게 만드는 것이 중요하다.
15. 이번 실험의 의미
이번 글에서 만든 구조는 아직 완성형 RAG 시스템은 아니다.
하지만 Patent Intelligence Agent의 핵심 구조를 갖추기 시작했다.
지금까지의 분석은 다음과 같았다.
특허 임베딩
↓
유사 특허 검색
↓
기술지도
↓
클러스터링
↓
기업 포트폴리오 분석
이번 글에서는 여기에 리포트 생성 구조가 추가되었다.
사용자 질문
↓
관련 특허 검색
↓
검색된 특허 Context 구성
↓
근거 기반 리포트 Prompt 생성
이 단계부터 Patent Intelligence Agent는 단순 분석 도구를 넘어, 기술조사 리포트를 작성하는 보조도구로 확장된다.
16. 정리
이번 글에서는 RAG를 활용해 특허 기반 기술동향 리포트를 생성하는 기본 구조를 정리했다.
핵심은 다음과 같다.
| 핵심 요약 |
| 1. RAG는 검색된 문서를 근거로 답변을 생성하는 Retrieval-Augmented Generation 구조다. 2. 특허 분석에서 RAG는 관련 특허를 먼저 검색하고, 그 문헌을 근거로 리포트를 작성하게 만드는 방식이다. 3. 이번 글에서는 LLM API 연결 없이, 검색된 특허를 Context로 만들고 리포트 Prompt를 생성하는 단계까지 구현했다. 4. Sentence-BERT를 사용해 사용자 질문과 특허 문헌의 의미적 유사도를 계산했다. 5. 유사도가 높은 특허 Top-K를 검색해 LLM 입력용 Context로 구성했다. 6. Prompt에는 리포트 구조와 Hallucination 방지 규칙을 함께 넣어야 한다. 7. RAG의 성능은 LLM보다 검색 품질에 크게 좌우된다. |
이번 단계까지 오면 Patent Intelligence Agent는 사용자의 질문에 대해 관련 특허를 검색하고, 검색된 문헌을 근거로 기술동향 리포트 초안을 생성할 수 있는 구조를 갖게 된다.
다음 글에서는 지금까지 진행한 전체 프로젝트를 정리하고, Patent Intelligence Agent가 기술평가와 기술금융에서 어떻게 활용될 수 있는지 검토한다. 또한 이 프로젝트를 논문형 연구로 확장하려면 어떤 연구질문과 실험설계가 필요한지도 정리해볼 예정이다.
다음 글 예고
"Patent Intelligence Agent는 기술평가에 쓸 수 있을까?"
다음 글에서는 지금까지 구현한 특허 임베딩, 유사도 검색, 클러스터링, 기업 포트폴리오 분석, RAG 리포트 생성 구조를 종합하고, 기술평가·기술금융·논문 확장 가능성을 정리할 예정이다.
'Project > Patent Intelligent Agent' 카테고리의 다른 글
| Patent Intelligence Agent #10; Patent Intelligence Agent는 기술평가에 쓸 수 있을까? (0) | 2026.06.26 |
|---|---|
| Patent Intelligence Agent #8; 기업별 특허 포트폴리오 벡터 만들기 (0) | 2026.06.23 |
| Patent Intelligence Agent #7 (0) | 2026.06.22 |
| Patent Intelligence Agent #6 (0) | 2026.06.22 |
| Patent Intelligence Agent #5 (0) | 2026.06.16 |