교차 모달 추론 패턴
이미지에 텍스트 주장의 근거를 연결하고 여러 출처의 멀티모달 맥락을 종합합니다.
교차 모달 추론 패턴은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
교차 모달 추론
교차 모달 추론은 에이전트가 서로 일치하거나 모순되거나 서로를 보완할 수 있는 두 가지 이상의 정보 양식 — 텍스트, 이미지, 차트, 표 — 에서 얻은 정보를 조정해야 할 때 발생합니다. 예를 들어 보고서 본문에는 매출이 20% 증가했다고 쓰여 있지만, 첨부된 차트에는 변화가 없는 선이 표시될 수 있습니다.
에이전트는 어느 출처가 올바른지 결정하거나, 불일치를 사람의 검토 대상으로 표시해야 합니다.
텍스트-이미지 근거 연결
텍스트-이미지 근거 연결은 텍스트에 제시된 주장을 함께 제공된 이미지에서 시각적으로 확인할 수 있는지 검증하는 것을 의미합니다. 예를 들어 제품 설명이 제품 사진과 일치합니까? 문서에서 언급한 표가 실제로 이미지에 나타납니까?
import anthropic
import base64
def ground_text_in_image(
text_claim: str,
image_path: str
) -> dict:
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
with open(image_path, 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
prompt = (
f'Text claim: "{text_claim}"\n\n'
'Does the image above support, contradict, or partially support this claim?\n'
'Return JSON: {"verdict": "support|contradict|partial|insufficient_evidence", '
'"confidence": 0.0, "evidence": "..."}'
)
response = client.messages.create(
model='claude-opus-4-5', max_tokens=256,
messages=[{'role': 'user', 'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text': prompt}
]}]
)
import json
return json.loads(response.content[0].text)차트와 텍스트 간 모순 감지
현실에서 흔히 발생하는 상황은 금융 보고서의 본문이 한 가지 내용을 말하지만 문서에 포함된 차트가 다른 내용을 보여 주는 경우입니다. 에이전트는 차트 데이터를 시각적으로 추출하고 텍스트의 수치 주장과 비교할 수 있습니다.
def compare_chart_to_text(
chart_image_path: str,
text_with_claims: str
) -> dict:
import anthropic, base64, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
with open(chart_image_path, 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
prompt = (
'The following text makes claims about data.\n'
f'TEXT: {text_with_claims}\n\n'
'Compare the chart image to the text claims. '
'List any contradictions and agreements. '
'Return JSON: {"agreements": [str], "contradictions": [str], '
'"verdict": "consistent|inconsistent|partial"}'
)
response = client.messages.create(
model='claude-opus-4-5', max_tokens=512,
messages=[{'role': 'user', 'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text': prompt}
]}]
)
return json.loads(response.content[0].text)신호 결합 전략
여러 정보 양식의 신호가 일치하면 신뢰도를 높이십시오. 서로 다르면 다음과 같은 충돌 해결 전략을 적용하십시오. 더 구조화된 출처를 신뢰하고(수치에서는 본문보다 차트를 우선함), 사람의 검토 대상으로 표시하거나, 어느 쪽이 더 신뢰할 수 있는지 LLM이 추론하도록 요청하십시오.
SIGNAL_SOURCES = {
'chart': 0.9, # high trust for quantitative data
'table': 0.85,
'photo': 0.8,
'prose': 0.6, # lower trust — may be imprecise or outdated
'caption': 0.7
}
def combine_signals(signals: list) -> dict:
"""
signals: list of {'source': str, 'claim': str, 'supports': bool}
Returns weighted verdict.
"""
support_weight = 0.0
total_weight = 0.0
for sig in signals:
w = SIGNAL_SOURCES.get(sig['source'], 0.5)
total_weight += w
if sig['supports']:
support_weight += w
confidence = support_weight / total_weight if total_weight > 0 else 0.0
return {
'confidence': round(confidence, 3),
'verdict': 'supported' if confidence >= 0.6 else 'contested',
'needs_review': 0.4 <= confidence < 0.6
}
if __name__ == '__main__':
signals = [
{'source': 'chart', 'claim': 'Revenue grew 20%', 'supports': True},
{'source': 'prose', 'claim': 'Revenue grew 20%', 'supports': False},
]
print(combine_signals(signals))
텍스트-이미지 검증 처리 흐름
제품 검증 처리 흐름은 다음과 같습니다. 제품 설명과 제품 사진이 주어지면 텍스트에 언급된 모든 핵심 속성이 이미지에 보이는지 확인합니다. 일치 항목과 불일치 항목을 구조화된 보고서로 반환합니다.
def verify_product_description(
description: str,
product_image_path: str
) -> dict:
import anthropic, base64, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
with open(product_image_path, 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
prompt = (
f'Product description:\n{description}\n\n'
'For each attribute mentioned in the description (color, shape, material, '
'size, features), check whether it is visible in the product photo.\n'
'Return JSON: {"verified": [{"attribute": str, "status": str}], '
'"unverified": [str], "overall_match": float}\n'
'status: confirmed / contradicted / not_visible\n'
'overall_match: 0.0-1.0'
)
response = client.messages.create(
model='claude-opus-4-5', max_tokens=512,
messages=[{'role': 'user', 'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text': prompt}
]}]
)
return json.loads(response.content[0].text)문서 + 이미지 교차 참조
스캔한 문서를 분석할 때는 OCR 텍스트와 원본 이미지가 모두 존재합니다. 두 가지를 서로 대조하여 추출된 텍스트가 시각적으로 나타난 내용과 일치하는지 확인하십시오. 불일치는 수정이 필요한 OCR 오류를 나타낼 수 있습니다.
def crossref_ocr_with_image(
ocr_text: str,
document_image_path: str
) -> dict:
import anthropic, base64, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
with open(document_image_path, 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
prompt = (
f'The OCR system produced this text from the document image:\n\n'
f'{ocr_text}\n\n'
'Compare the OCR text to what you actually see in the image. '
'Identify any OCR errors, missed text, or hallucinated characters.\n'
'Return JSON: {"ocr_errors": [{"incorrect": str, "correct": str}], '
'"missed_sections": [str], "accuracy_estimate": float}'
)
response = client.messages.create(
model='claude-opus-4-5', max_tokens=512,
messages=[{'role': 'user', 'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text': prompt}
]}]
)
return json.loads(response.content[0].text)다중 소스 추론 에이전트
다중 소스 추론 에이전트는 각 정보 양식에서 체계적으로 증거를 수집하고, 신호를 결합하며, 신뢰도 점수와 함께 최종 결론을 생성합니다. 결론을 뒷받침한 출처와 결론에 반대된 출처를 명시합니다.
def multi_source_reasoning(
claim: str,
evidence_sources: list # list of {'type': 'text'|'image', 'content': str|path}
) -> dict:
import anthropic, base64, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
content_blocks = [
{'type': 'text',
'text': f'Evaluate this claim using ALL sources below:\nClaim: "{claim}"\n'}
]
for i, src in enumerate(evidence_sources):
if src['type'] == 'text':
content_blocks.append(
{'type': 'text', 'text': f'Source {i+1} (text): {src["content"]}'}
)
elif src['type'] == 'image':
with open(src['content'], 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
content_blocks.append(
{'type': 'text', 'text': f'Source {i+1} (image):'}
)
content_blocks.append(
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}}
)
content_blocks.append({'type': 'text', 'text':
'Return JSON: {"verdict": str, "confidence": float, '
'"supporting_sources": [int], "contradicting_sources": [int]}'
})
response = client.messages.create(
model='claude-opus-4-5', max_tokens=512,
messages=[{'role': 'user', 'content': content_blocks}]
)
return json.loads(response.content[0].text)이미지 기반 텍스트 사실 생성
이미지가 있고 이후 텍스트 기반 추론에 사용할 구조화된 사실을 생성해야 하는 경우가 있습니다. 차트와 표에서 정량적 사실을 JSON으로 추출하면 텍스트의 주장과 수학적으로 검증할 수 있습니다.
def extract_facts_from_chart(chart_path: str) -> dict:
import anthropic, base64, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
with open(chart_path, 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
prompt = (
'Extract all quantitative data from this chart. '
'Return JSON with: chart_type, x_axis_label, y_axis_label, '
'and data_points as [{label: str, value: float}].\n'
'Also extract any trend: increasing/decreasing/stable/volatile.'
)
response = client.messages.create(
model='claude-opus-4-5', max_tokens=512,
messages=[{'role': 'user', 'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text': prompt}
]}]
)
return json.loads(response.content[0].text)신뢰도 임계값에 따른 전달
교차 모달 추론 후에는 신뢰도에 따라 결과를 전달하십시오. 높은 신뢰도 → 자동 승인, 중간 신뢰도 → 선택적 검토 대상으로 표시, 낮은 신뢰도 → 사람에게 전달. 신뢰도 점수와 관계없이 신호가 충돌하면 절대 자동 승인하지 마십시오.
def route_cross_modal_result(result: dict) -> str:
confidence = result.get('confidence', 0.0)
has_contradiction = bool(result.get('contradicting_sources'))
if has_contradiction:
return 'ESCALATE'
if confidence >= 0.85:
return 'AUTO_APPROVE'
if confidence >= 0.6:
return 'OPTIONAL_REVIEW'
return 'ESCALATE'
# Example routing table:
# confidence >= 0.85, no contradiction -> AUTO_APPROVE
# confidence 0.6-0.85, no contradiction -> OPTIONAL_REVIEW
# any contradiction, or confidence < 0.6 -> ESCALATE
def handle_routing(claim: str, evidence_sources: list):
result = multi_source_reasoning(claim, evidence_sources)
action = route_cross_modal_result(result)
print(f'Claim: "{claim}"')
print(f'Verdict: {result["verdict"]} (confidence={result["confidence"]:.2f})')
print(f'Action: {action}')
return action, result시각적 증거 부족 처리
이미지의 해상도가 너무 낮거나 흐리거나 일부가 가려져 유용한 증거를 제공하지 못하는 경우가 있습니다. 에이전트는 이를 감지하고 근거 없는 교차 모달 결론을 환각하여 만들어 내는 대신 판단을 보류해야 합니다.
def assess_image_evidence_quality(
image_path: str,
claim: str
) -> dict:
import anthropic, base64, json
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
with open(image_path, 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
prompt = (
f'Claim to verify: "{claim}"\n\n'
'Assess whether this image provides sufficient evidence to evaluate the claim.\n'
'Consider: image quality, relevance, completeness, and readability.\n'
'Return JSON: {"sufficient": bool, "quality_issues": [str], '
'"usable_evidence": str}'
)
response = client.messages.create(
model='claude-opus-4-5', max_tokens=256,
messages=[{'role': 'user', 'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text': prompt}
]}]
)
return json.loads(response.content[0].text)교차 모달 사실 검증기 구축
지금까지의 내용을 결합하면 다음과 같습니다. 보고서(텍스트 + 포함된 이미지)를 받아 텍스트의 모든 정량적 주장을 뒷받침하는 차트 및 표와 대조하여 검증하는 문서 사실 검증기입니다. 구조화된 검증 보고서를 반환합니다.
def fact_check_report(
report_text: str,
image_paths: list
) -> dict:
import re
# Extract numeric claims from text (simple regex pattern)
claim_pattern = r'[A-Z][^.!?]*[0-9][%$][^.!?]*[.!?]'
claims = re.findall(claim_pattern, report_text)
results = []
for claim in claims:
sources = [
{'type': 'text', 'content': report_text},
] + [{'type': 'image', 'content': p} for p in image_paths]
reasoning = multi_source_reasoning(claim, sources)
action = route_cross_modal_result(reasoning)
results.append({
'claim': claim,
'verdict': reasoning['verdict'],
'confidence': reasoning['confidence'],
'action': action
})
total = len(results)
auto_approved = sum(1 for r in results if r['action'] == 'AUTO_APPROVE')
return {
'total_claims': total,
'auto_approved': auto_approved,
'escalated': total - auto_approved,
'details': results
}지식 확인
텍스트와 차트의 신호가 서로 모순될 때, 모범 사례에 따르면 교차 모달 에이전트는 어떻게 해야 합니까?
복습: 교차 모달 추론 패턴
이 수업을 완료했습니다. 핵심 내용은 다음과 같습니다.
- 텍스트-이미지 근거 연결: 텍스트의 주장을 시각적 증거와 대조하여 검증합니다.
- 신호 결합: 가중 신뢰를 적용합니다(수치에서는 차트가 본문보다 우선함). 구조화된 출처가 비구조화된 출처보다 우선합니다.
- 모순 감지: 항상 사람에게 전달하고, 모순을 자동으로 해결하지 않습니다.
- 신뢰도에 따른 전달: 자동 승인(높음) → 선택적 검토(중간) → 사람에게 전달(낮음 또는 모순)
- 증거 부족: 교차 모달 결론을 환각하는 대신 판단을 보류합니다.
다음 과정: MQTT를 사용하여 실제 데이터 스트림을 처리하는 사물 인터넷 및 센서 기반 에이전트입니다.
자주 묻는 질문
“교차 모달 추론 패턴” 강의는 무료인가요?
네 — “교차 모달 추론 패턴” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
“교차 모달 추론 패턴”에서 뭘 배우나요?
이미지에 텍스트 주장의 근거를 연결하고 여러 출처의 멀티모달 맥락을 종합합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Agents을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“교차 모달 추론 패턴” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.