การจำแนกและกำหนดเส้นทางเอกสาร
จัดหมวดหมู่เอกสารตามประเภทและส่งต่อไปยังตัวจัดการตัวแทนเฉพาะทาง
การจำแนกและกำหนดเส้นทางเอกสาร เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดการจำแนกเอกสารจึงสำคัญ
เอเจนต์ปัญญาเอกสารอาจได้รับเอกสารหลายประเภท เช่น ใบแจ้งหนี้ สัญญา รายงาน อีเมล และใบเสร็จ เอกสารแต่ละประเภทต้องใช้ตรรกะการแยกข้อมูลและกฎทางธุรกิจที่แตกต่างกัน
การจำแนกเอกสารจะส่งเอกสารแต่ละฉบับไปยังตัวจัดการที่ถูกต้องก่อนการประมวลผลขั้นถัดไป ทำหน้าที่เป็นตรรกะรับเอกสารเข้าของเอเจนต์
การจำแนกโดยใช้ LLM
ตัวจำแนกที่เรียบง่ายและยืดหยุ่นที่สุดใช้ LLM โดยส่งตัวอย่างข้อความของเอกสาร แล้วขอให้โมเดลระบุประเภทเอกสาร วิธีนี้ทำงานได้ดีเมื่อประเภทเอกสารแตกต่างกันอย่างชัดเจน
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
DOC_TYPES = ['invoice', 'contract', 'report', 'email', 'receipt', 'form', 'letter', 'other']
CLASSIFY_PROMPT = '''Classify this document into one of these types: {types}
Document excerpt (first 1000 characters):
{text}
Respond with ONLY the document type as a single word from the list above.'''
def classify_with_llm(text):
response = client.chat.completions.create(
model='gpt-4o-mini', # cheap and fast for classification
messages=[{
'role': 'user',
'content': CLASSIFY_PROMPT.format(
types=', '.join(DOC_TYPES),
text=text[:1000]
)
}],
max_tokens=10,
temperature=0
)
predicted = response.choices[0].message.content.strip().lower()
return predicted if predicted in DOC_TYPES else 'other'ทางเลือกสำรองสำหรับการจำแนกด้วยกฎ
การจำแนกด้วย LLM แม่นยำ แต่มีค่าใช้จ่ายและเพิ่มเวลาหน่วง สำหรับประเภทเอกสารทั่วไปที่กำหนดไว้อย่างชัดเจน ตัวจำแนกตามกฎคำสำคัญรวดเร็ว ไม่มีค่าใช้จ่าย และอธิบายได้
ใช้กฎเป็นเส้นทางด่วน แล้วใช้ LLM เป็นทางเลือกสำรองสำหรับกรณีที่ไม่ชัดเจน
CLASSIFICATION_RULES = {
'invoice': [
'invoice', 'invoice number', 'bill to', 'amount due',
'total amount', 'tax invoice', 'payment terms'
],
'contract': [
'agreement', 'terms and conditions', 'hereby agrees',
'party a', 'party b', 'whereas', 'obligations'
],
'report': [
'executive summary', 'quarterly report', 'annual report',
'findings', 'recommendations', 'methodology'
],
'email': ['from:', 'to:', 'subject:', 'date:', 'dear ', 'regards,'],
'receipt': ['receipt', 'thank you for your purchase', 'transaction id', 'cashier']
}
def classify_with_rules(text):
text_lower = text.lower()
scores = {}
for doc_type, keywords in CLASSIFICATION_RULES.items():
score = sum(1 for kw in keywords if kw in text_lower)
if score > 0:
scores[doc_type] = score
if not scores:
return None # no match — fall through to LLM
return max(scores, key=scores.get)
if __name__ == '__main__':
demo_text = 'INVOICE\nBill To: Acme Corp\nAmount Due: $500\nPayment Terms: Net 30'
print('Classified as:', classify_with_rules(demo_text))
กลยุทธ์การจำแนกแบบเป็นลำดับชั้น
ผสานการจำแนกตามกฎกับการจำแนกด้วย LLM ในแนวทางแบบเป็นลำดับชั้น โดยใช้กฎที่รวดเร็วก่อน และใช้ LLM เฉพาะเมื่อกฎไม่สามารถสรุปผลได้ วิธีนี้ลดค่าใช้จ่ายในขณะที่ยังคงความแม่นยำสำหรับกรณีขอบ
def classify_document(text):
# Tier 1: rule-based (free, fast)
result = classify_with_rules(text)
if result:
print(f'Rule-based classification: {result}')
return {'type': result, 'method': 'rules', 'confidence': None}
# Tier 2: LLM (accurate, slower)
result = classify_with_llm(text)
print(f'LLM classification: {result}')
return {'type': result, 'method': 'llm', 'confidence': None}ค่าเกณฑ์ความเชื่อมั่น
ผลการจำแนกไม่ได้มีความเชื่อมั่นเท่ากันทั้งหมด สำหรับตัวจำแนก LLM ให้ขอคะแนนความเชื่อมั่นพร้อมกับผลการจำแนก หากความเชื่อมั่นต่ำ ให้ทำเครื่องหมายเอกสารเพื่อให้มนุษย์ตรวจสอบ
import json
CLASSIFY_WITH_CONFIDENCE_PROMPT = '''Classify this document. Return JSON:
{{"type": "invoice", "confidence": 0.95, "reason": "Contains invoice number and payment terms"}}
Valid types: {types}
Document excerpt: {text}
JSON:'''
def classify_with_confidence(text):
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': CLASSIFY_WITH_CONFIDENCE_PROMPT.format(
types=', '.join(DOC_TYPES),
text=text[:1000]
)}],
temperature=0
)
try:
result = json.loads(response.choices[0].message.content)
return result
except json.JSONDecodeError:
return {'type': 'other', 'confidence': 0.0, 'reason': 'Parse error'}
LOW_CONFIDENCE_THRESHOLD = 0.6
def classify_and_check(text):
result = classify_with_confidence(text)
if result['confidence'] < LOW_CONFIDENCE_THRESHOLD:
result['needs_review'] = True
print(f'Low confidence ({result["confidence"]}) — flagging for review')
return resultตัวส่งต่อเอกสาร
เมื่อจำแนกแล้ว ตัวส่งต่อจะส่งเอกสารไปยังตัวจัดการเฉพาะทาง ตัวจัดการแต่ละตัวรู้วิธีแยกฟิลด์เฉพาะที่เกี่ยวข้องกับเอกสารประเภทนั้น
def handle_invoice(text):
# Extract: vendor, invoice number, total, due date
extract_prompt = f'''Extract from this invoice (JSON):
{{"vendor": "", "invoice_number": "", "total": 0, "due_date": "", "line_items": []}}
{text[:2000]}\n\nJSON:'''
return llm_call(extract_prompt)
def handle_contract(text):
# Extract: parties, effective date, term, key obligations
extract_prompt = f'''Extract from this contract (JSON):
{{"parties": [], "effective_date": "", "term_months": 0, "key_obligations": []}}
{text[:2000]}\n\nJSON:'''
return llm_call(extract_prompt)
ROUTERS = {
'invoice': handle_invoice,
'contract': handle_contract,
'report': lambda t: llm_call(f'Summarize this report in 3 bullet points:\n{t[:2000]}'),
'email': lambda t: llm_call(f'Extract: sender, subject, action required from this email:\n{t[:1000]}')
}
def route_document(text):
classification = classify_document(text)
doc_type = classification['type']
handler = ROUTERS.get(doc_type, lambda t: llm_call(f'Describe this document:\n{t[:1000]}'))
return handler(text)การจำแนกประเภทย่อย
ประเภทระดับสูงอย่าง “สัญญา” อาจมีประเภทย่อย เช่น สัญญาจ้างงาน NDA สัญญาบริการ และสัญญาเช่า ตัวจำแนกประเภทย่อยในขั้นที่สองช่วยให้แยกฟิลด์ได้แม่นยำยิ่งขึ้น
CONTRACT_SUBTYPES = {
'employment': ['employment', 'employee', 'employer', 'salary', 'compensation', 'job title'],
'nda': ['non-disclosure', 'confidential', 'nda', 'proprietary information'],
'service': ['service agreement', 'scope of work', 'deliverables', 'milestone'],
'lease': ['lease', 'landlord', 'tenant', 'rent', 'premises', 'square feet']
}
def classify_contract_subtype(text):
text_lower = text.lower()
scores = {
subtype: sum(1 for kw in keywords if kw in text_lower)
for subtype, keywords in CONTRACT_SUBTYPES.items()
}
best = max(scores, key=scores.get)
if scores[best] == 0:
return 'general'
return best
def handle_contract_routed(text):
subtype = classify_contract_subtype(text)
print(f'Contract subtype: {subtype}')
# Route to specialized extractor
if subtype == 'nda':
return extract_nda_fields(text)
elif subtype == 'employment':
return extract_employment_fields(text)
else:
return handle_contract(text)กระบวนการจำแนกแบบกลุ่ม
ในระบบใช้งานจริง เอกสารมาถึงเป็นชุด ให้ประมวลผลอย่างมีประสิทธิภาพโดยจำแนกเอกสารทั้งหมดก่อน จัดกลุ่มตามประเภท แล้วประมวลผลแต่ละกลุ่มแบบขนาน
from concurrent.futures import ThreadPoolExecutor
import time
def classify_batch(documents):
results = []
for doc in documents:
text = extract_text(doc['path']) # PDF, OCR, or plain text
classification = classify_document(text[:1500])
results.append({
'doc_id': doc['id'],
'path': doc['path'],
'type': classification['type'],
'method': classification['method'],
'text': text
})
return results
def process_batch(documents, max_workers=4):
# Step 1: classify all (fast)
classified = classify_batch(documents)
# Step 2: group by type
from collections import defaultdict
by_type = defaultdict(list)
for doc in classified:
by_type[doc['type']].append(doc)
# Step 3: process each group
all_results = {}
for doc_type, docs in by_type.items():
handler = ROUTERS.get(doc_type)
if handler:
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(handler, d['text']): d for d in docs}
for fut, doc in futures.items():
all_results[doc['doc_id']] = fut.result()
return all_resultsการจัดการประเภท “อื่น ๆ” และประเภทที่ไม่รู้จัก
เอกสารที่ถูกจำแนกเป็น “อื่น ๆ” หรือมีความเชื่อมั่นต่ำจำเป็นต้องมีกลยุทธ์สำรอง ตัวเลือกได้แก่ ทำเครื่องหมายเพื่อให้มนุษย์ตรวจสอบ พยายามแยกข้อมูลทั่วไป หรือถามผู้ใช้ว่าเอกสารนั้นเป็นประเภทใด
HUMAN_REVIEW_QUEUE = []
def process_document(doc_path):
text = extract_text(doc_path)
classification = classify_with_confidence(text[:1500])
# High confidence path
if classification['confidence'] >= 0.8 and classification['type'] != 'other':
handler = ROUTERS.get(classification['type'])
return {
'result': handler(text),
'type': classification['type'],
'auto_processed': True
}
# Low confidence or unknown type
HUMAN_REVIEW_QUEUE.append({
'path': doc_path,
'predicted_type': classification['type'],
'confidence': classification['confidence'],
'reason': classification.get('reason', '')
})
print(f'Added to review queue: {doc_path} ({classification["confidence"]:.0%} confident)')
return {'auto_processed': False, 'queued_for_review': True}วงจรป้อนกลับของการจำแนก
เมื่อมนุษย์แก้ไขการจำแนกที่ผิดพลาด ให้บันทึกการแก้ไขนั้น ใช้บันทึกเหล่านี้เพื่อปรับปรุงตัวจำแนกตามกฎ และปรับแต่งหรือใช้พรอมต์แบบตัวอย่างจำนวนน้อยกับตัวจำแนก LLM เมื่อเวลาผ่านไป
correction_log = []
def log_correction(doc_path, predicted_type, correct_type, text_sample):
correction_log.append({
'doc_path': doc_path,
'predicted': predicted_type,
'correct': correct_type,
'text_sample': text_sample[:200]
})
print(f'Logged correction: {predicted_type} -> {correct_type}')
def build_few_shot_examples(n=5):
recent = correction_log[-n:] # use most recent corrections
examples = []
for entry in recent:
examples.append(
f'Text: {entry["text_sample"]}\nCorrect type: {entry["correct"]}'
)
return '\n\n'.join(examples)
def classify_with_few_shot(text):
few_shot = build_few_shot_examples()
prompt = f'''Examples of correct classifications:\n{few_shot}\n\nNow classify:\n{text[:800]}\n\nType:'''
return llm_call(prompt).strip().lower()การแยกข้อมูลแบบมีโครงสร้างหลังการจำแนก
เมื่อระบุประเภทเอกสารได้แล้ว ให้แยกฟิลด์เฉพาะที่สำคัญสำหรับประเภทนั้น ใช้การแยกข้อมูลแบบมีโครงสร้างด้วย LLM ร่วมกับแบบแผนข้อมูล เพื่อให้ได้ผลลัพธ์ที่สม่ำเสมอและแยกวิเคราะห์ได้
import json
class FakeMsg:
def __init__(self, content): self.content = content
class FakeChoice:
def __init__(self, content): self.message = FakeMsg(content)
class FakeResponse:
def __init__(self, content): self.choices = [FakeChoice(content)]
class _Completions:
@staticmethod
def create(model, messages, temperature):
return FakeResponse('{"vendor_name": "Acme", "invoice_number": "123", "total": 100}')
class _Chat:
completions = _Completions()
class FakeClient:
chat = _Chat()
client = FakeClient()
EXTRACTION_SCHEMAS = {
'invoice': '{vendor_name: , invoice_number: , invoice_date: , due_date: , subtotal: 0, tax: 0, total: 0, line_items: []}',
}
def extract_structured_fields(text, doc_type):
schema = EXTRACTION_SCHEMAS.get(doc_type)
if not schema:
return {'error': f'No extraction schema for type: {doc_type}'}
prompt = (f'Extract fields from this {doc_type}. Return JSON matching this schema:\n'
f'{schema}\n\nDocument:\n{text[:2000]}\n\nJSON:')
response = client.chat.completions.create(model='gpt-4o-mini', messages=[{'role': 'user', 'content': prompt}], temperature=0)
try:
return json.loads(response.choices[0].message.content)
except json.JSONDecodeError:
return {'error': 'Could not parse extraction result'}
print(extract_structured_fields('Invoice #123 from Acme for $100', 'invoice'))ตรวจสอบความรู้
ข้อดีของการใช้กลยุทธ์การจำแนกแบบเป็นลำดับชั้น (ใช้กฎก่อนและใช้ LLM เป็นทางเลือกสำรอง) คืออะไร
ทบทวน: การจำแนกและการส่งต่อเอกสาร
การจำแนกเอกสารจะส่งเอกสารขาเข้าไปยังตัวจัดการเฉพาะทาง ใช้แนวทางแบบเป็นลำดับชั้น ได้แก่ กฎคำสำคัญที่รวดเร็วสำหรับประเภททั่วไป การจำแนกด้วย LLM พร้อมคะแนนความเชื่อมั่นสำหรับกรณีขอบ และคิวตรวจสอบโดยมนุษย์สำหรับเอกสารที่มีความเชื่อมั่นต่ำ
เอกสารแต่ละประเภทมีตัวจัดการแยกข้อมูลของตนเอง การจำแนกประเภทย่อย (เช่น NDA กับสัญญาจ้างงาน) ช่วยให้แยกฟิลด์ได้แม่นยำยิ่งขึ้น ให้บันทึกการแก้ไขเพื่อปรับปรุงตัวจำแนกเมื่อเวลาผ่านไปผ่านวงจรป้อนกลับ
คำถามที่พบบ่อย
บทเรียน “การจำแนกและกำหนดเส้นทางเอกสาร” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การจำแนกและกำหนดเส้นทางเอกสาร” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การจำแนกและกำหนดเส้นทางเอกสาร”
จัดหมวดหมู่เอกสารตามประเภทและส่งต่อไปยังตัวจัดการตัวแทนเฉพาะทาง คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การจำแนกและกำหนดเส้นทางเอกสาร” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม
ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การแยกวิเคราะห์ PDF ด้วย PyMuPDF และ pdfplumber
- OCR สำหรับเอกสารสแกน
- ตัวแทนถามตอบจากเอกสารหลายฉบับ
- การจำแนกและกำหนดเส้นทางเอกสาร