ป้อนประวัติการสนทนาของ Copilot Chat และ Claude Code ลงใน ChromaDB และค้นหา "ตัวตนในอดีต" ของคุณ

GitHub Copilot Claude Code ChromaDB Ollama RAG AIアシスタント Python MCP

🔗 สารบัญซีรีส์: บทความนี้เป็น ฉบับการใช้งาน (2) ของซีรีส์ บันทึกการปฏิบัติงานของผู้ช่วย AI - บันทึกการปฏิบัติสำหรับการเพิ่มรหัส Copilot / Claude ในฐานะคู่หูของคุณ

สิ่งที่คุณสามารถเรียนรู้ได้จากบทความนี้

  • ตำแหน่งและโครงสร้าง ของบันทึกการสนทนา (JSONL) ที่ถูกบันทึกโดยอัตโนมัติโดย VSCode Copilot Chat และ Claude Code
  • ความแตกต่างในรูปแบบ JSONL แต่ละรูปแบบและ การออกแบบให้รองรับด้วยอินเทอร์เฟซทั่วไป
  • วิธีค้นหา “อดีตที่ผ่านมา” ในภาษาธรรมชาติโดยการใช้เวกเตอร์ด้วย ChromaDB + Ollama
  • ขั้นตอนในการส่งโดยอัตโนมัติเมื่อสิ้นสุดเซสชันโดยใช้ Stop hook ของ Claude Code
  • เอฟเฟกต์และประเด็นที่ควรทราบหลังจากสะสมเซสชันหลายสิบครั้ง

กลุ่มเป้าหมาย

  • ผู้ที่ต้องการ ใช้การสนทนากับผู้ช่วย AI เป็นความทรงจำถาวร
  • ผู้ที่อาศัยบันทึกการค้นหาทุกครั้งเพื่อถามว่า “ตอนนั้นแก้ปัญหายังไง
  • ผู้ที่ต้องการเพิ่ม ฟังก์ชันนำเข้าบันทึกการสนทนา ให้กับ RAG ของตนเอง
  • ผู้ที่ใช้ VSCode Copilot Chat / Claude Code หรือทั้งสองอย่าง

สภาพแวดล้อมการทำงาน

รายการเวอร์ชั่น
ระบบปฏิบัติการวินโดวส์ 11
หลาม3.13 (venv)
ChromaDBโหมดถาวร (PersistentClient)
การฝังโอลมะ nomic-embed-text (768 มิติ)
VSCode Copilot Chatบันทึกการถอดเสียง JSONL อัตโนมัติไปที่ workspaceStorage
รหัสคลอดบันทึกเซสชัน JSONL โดยอัตโนมัติไปที่ ~/.claude/projects/

1. บทนำ — “อ

ะไรคือวิธีแก้ไขปัญหานั้น”ช่วงเวลาเช่นนี้กลายเป็นเรื่องปกติมากขึ้นเมื่อคุณทำงานร่วมกับผู้ช่วย AI ทุกวัน

วิธีแก้ปัญหาการเข้ารหัสอักขระของ PowerShell ที่ Copilot สอนฉันตอนนั้นคืออะไร

สัปดาห์ที่แล้ว ฉันได้พูดคุยกับ Claude Code และตัดสินใจเกี่ยวกับ “การออกแบบบายพาสการรับรองความถูกต้องโดยใช้โปรไฟล์ dev” ข้อสรุปคืออะไร

ฉันรู้สึกเหมือนฉันกำลังจะก้าวเข้าสู่กับดักที่ฉันเหยียบเมื่อเดือนที่แล้วอีกครั้ง…

ควรบันทึกการสนทนาไว้ที่ใดที่หนึ่งเป็นไฟล์ JSONL แต่ชื่อไฟล์คือ UUID และเนื้อหาเป็น JSON หลายแสนบรรทัด เป็นการยากที่จะค้นหาโดยใช้ grep และความปรารถนาเดิมคือ “ดึงวิธีแก้ปัญหาในอดีตโดยใช้ภาษาธรรมชาติ”

วันหนึ่งฉันก็ตระหนักได้

**บันทึกการสนทนาเป็น “เนื้อหาที่ดีที่สุดของ RAG” ที่สร้างขึ้นทุกวันไม่ใช่หรือ? **

บล็อกทางเทคนิค เอกสารการออกแบบ คำตอบ Stack Overflow มี “ความรู้ของผู้อื่น” มากมาย แต่วิธีแก้ปัญหาเดียวที่คุณจะพบในบริบทของคุณเอง ด้วยคำพูดของคุณเอง และสำหรับปัญหาของคุณเองนั้นอยู่ในบันทึกการสนทนาของคุณเอง หากคุณใส่สิ่งนี้ลงใน RAG คุณสามารถสร้างเครื่องมือค้นหาที่ช่วยให้คุณสามารถค้นหา “ตัวตนในอดีต” ของคุณได้อย่างแท้จริง

บทความนี้จะอธิบายวิธีการสร้างกลไกนี้สำหรับทั้ง Copilot Chat และ Claude Code


2. การถอดเสียงสองประเภท

ขั้นแรก จัดระเบียบว่าแต่ละไฟล์จะบันทึกที่ไหนและในรูปแบบใด

2.1 VSCode Copilot Chat

บันทึกไปที่:

C:\Users\<ผู้ใช้>\AppData\Roaming\Code\User\workspaceStorage\<workspace-hash>\GitHub.copilot-chat\transcripts\<uuid>.jsonl

มีไดเร็กทอรีที่แฮชสำหรับแต่ละพื้นที่ทำงาน (โฟลเดอร์ที่เปิดใน VSCode) และโฟลเดอร์ transcripts/ ถูกขุดในไดเร็กทอรีนั้น และ JSONL ที่มีชื่อ UUID จะถูกซ้อนกัน

โครงสร้าง JSONL (ประยุกต์):

{"type":"user.message","data":{"content":"How to write Virtual Threads in Java 21?"},"timestamp":"..."}
{"type":"assistant.message","data":{"content":"`Thread.ofVirtual().start(() -> { ... })`..."},"timestamp":"..."}
{"type":"assistant.turn_end","data":{...}}

1 แถว = 1 กิจกรรม ข้อความผู้ใช้/ผู้ช่วยสามารถระบุได้ด้วยฟิลด์ type และ data.content มีข้อความเป็นสตริง เรียบง่าย.

2.2 รหัสคลอดด์

บันทึกไปที่:

C:\Users\<ผู้ใช้>\.claude\projects\<project-slug>\<session-id>.jsonl

มีโฟลเดอร์สำหรับแต่ละโปรเจ็กต์ (กระสุนที่แปลงจากเส้นทางแบบเต็มของที่เก็บ) และในโฟลเดอร์นั้นจะมี JSONL พร้อมชื่อ ID เซสชัน

โครงสร้าง JSONL (ประยุกต์):

{"type":"user","message":{"role":"user","content":[{"type":"text","text":"…"}]}}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"…"},{"type":"thinking","thinking":"…"},{"type":"tool_use","name":"Read","input":{...}}]}}
{"type":"queue-operation","operation":"enqueue",...}
{"type":"attachment",...}
{"type":"file-history-snapshot",...}

อันนี้ซับซ้อนนิดหน่อย:

  • type ฟิลด์คือ "user" / "assistant" แต่ เนื้อหาซ้อนอยู่ในอาร์เรย์ของ message.content
  • แต่ละองค์ประกอบของอาร์เรย์เป็น บล็อกเนื้อหา และ type แบ่งออกเป็น "text" / "thinking" / "tool_use" เป็นต้น
  • ข้อความของผู้ใช้มี แท็กอัตโนมัติ เช่น <system-reminder> <ide_opened_file>
  • เหตุการณ์ Meta เช่น queue-operation attachment file-history-snapshot ก็อยู่ใน JSONL เดียวกันเช่นกัน

กล่าวโดยสรุป Copilot Chat เป็นรูปแบบง่ายๆ โดยที่ “1 ข้อความ = 1 ข้อความ” และ Claude Code เป็นรูปแบบที่มีโครงสร้างโดยที่ “อาร์เรย์บล็อกเนื้อหา + เหตุการณ์เมตาผสมกัน” แม้จะเรียกว่า “ประวัติการสนทนา” เดียวกัน แต่รูปแบบก็แตกต่างกัน


3. ความท้าทายและการออกแบบทั่วไป

ฉันต้องการจัดการทั้งสองอย่างในอินเทอร์เฟซเดียว ดังนั้นฉันจึงจัดระเบียบมันแบบนี้

ขั้นตอนการประมวลผลทั่วไป

[ไฟล์ JSONL]
   ↓ การแยกวิเคราะห์ (ขึ้นอยู่กับรูปแบบ)
[คู่ข้อความผู้ใช้ / ผู้ช่วย (= รอบ)]
   ↓ การแบ่งส่วน (ทั่วไป)
[id/ข้อความ/ข้อมูลเมตาที่ตั้งค่าไว้สำหรับ ChromaDB]
   ↓ upsert (ทั่วไป)
[คอลเลกชัน ChromaDB]

การออกแบบเป็นเช่นนั้นเฉพาะส่วนที่ขึ้นอยู่กับรูปแบบ (การแยกวิเคราะห์) เท่านั้นที่จะถูกนำไปใช้แยกกัน และทุกอย่างหลังจากการแยกชิ้นส่วนจะได้รับมาตรฐานอย่างสมบูรณ์ โดยเฉพาะ:

  • ingest_conversation.py — Parser สำหรับ Copilot Chat + เรียกกระบวนการป้อนข้อมูลทั่วไป
  • ingest_claude_code.py — Parser สำหรับ Claude Code + เรียกกระบวนการอินพุตทั่วไปแบบเดียวกัน
  • src/db/store.py’s ingest_chunks() — ChromaDB ที่เติมตรรกะที่เรียกโดยทั้งคู่

กฎการแบ่งส่วน

หน่วยการสนทนาตามธรรมชาติคือคู่ “ผู้ใช้ 1 ตา + ผู้ช่วย 1 คำตอบ” สิ่งนี้เรียกว่า turns

ขีดจำกัดสูงสุดของการฝังในครั้งเดียวจะอยู่ที่ MAX_CHUNK_CHARS = 1200 เป็นโซนปลอดภัยสำหรับ nomic-embed-text และเราตัดสินใจรวม 3 รอบเป็น 1 ชิ้น

TURNS_PER_CHUNK = 3
MAX_CHUNK_CHARS = 1200
def turns_to_chunks(turns: list[dict], session_id: str, date_str: str) -> list[dict]:
    chunks = []
    for i in range(0, len(turns), TURNS_PER_CHUNK):
        group = turns[i:i + TURNS_PER_CHUNK]
        lines = []
        for t in group:
            lines.append(f"[user] {t['user']}")
            lines.append(f"[AI] {t['assistant']}")
            lines.append("")
        text = "\n".join(lines)
        if len(text) > MAX_CHUNK_CHARS:
            text = text[:MAX_CHUNK_CHARS]
        chunk_index = i // TURNS_PER_CHUNK
        chunks.append({
            "id": f"{session_id}::chunk_{chunk_index}",
            "text": text,
            "metadata": {
                "source_type": "conversation",
                "source_file": session_id,
                "title": f"Conversation session {date_str} (part {chunk_index + 1})",
                "date": date_str,
                "tags": "conversation,copilot", # or "conversation,claude-code"
                "chunk_index": chunk_index,
            },
        })
    return chunks

มีเพียง tags ของข้อมูลเมตาเท่านั้นที่ถูกแยกความแตกต่างด้วย “copilot” หรือ “claude-code” และที่เหลือก็เหมือนกันโดยสิ้นเชิง ตอนนี้ เมื่อคุณ rag search การสนทนากับ Copilot และ Claude Code จะปรากฏในผลการค้นหาโดยไม่คำนึงถึง


4. รวม Copilot Chat

ตัวแยกวิเคราะห์นี้เป็นแกนหลักของ Copilot Chat (ingest_conversation.py)

def parse_conversation(jsonl_path: Path) -> list[dict]:
    """Extract user/AI message pairs from JSONL"""
    turns = []
    user_msg = None

    with open(jsonl_path, encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            try:
                record = json.loads(line)
            except json.JSONDecodeError:
                continue

            rtype = record.get("type", "")
            timestamp = record.get("timestamp", "")
            if rtype == "user.message":
                content = record["data"].get("content", "").strip()
                if content:
                    user_msg = {"content": content, "timestamp": timestamp}

            elif rtype == "assistant.message":
                content = record["data"].get("content", "").strip()
                if content and user_msg:
                    turns.append({
                        "user": user_msg["content"],
                        "assistant": content,
                        "timestamp": user_msg["timestamp"],
                    })
                    user_msg = None

    return turns

เพียงเลือกโฟลว์ user.message → Assistant.message ตามลำดับและโหลดลงใน turns type ความเรียบง่ายของ parser สามารถใส่ได้ 30 บรรทัด ฉันชื่นชมความซื่อสัตย์ในส่วนของ Copilot Chat

ตรวจจับการถอดเสียงล่าสุดโดยอัตโนมัติได้อย่างง่ายดาย:

TRANSCRIPT_BASE = Path(r"C:\Users\<user>\AppData\Roaming\Code\User\workspaceStorage")
def find_latest_transcript() -> Path:
    """Auto-detect latest transcripts across all workspaces"""
    candidates = []
    if TRANSCRIPT_BASE.exists():
        for jsonl in TRANSCRIPT_BASE.rglob("*.jsonl"):
            if "transcripts" in jsonl.parts:
                candidates.append(jsonl)
    if not candidates:
        raise FileNotFoundError(...)
    return max(candidates, key=lambda p: p.stat().st_mtime)

ค้นหาพื้นที่ทำงานทั้งหมดซ้ำด้วย rglob และส่งคืน JSONL ล่าสุดด้วย mtime ฉันเผยแพร่สิ่งนี้ให้กับผู้ใช้ผ่านคำสั่ง rag conv

# Insert the latest conversation with one command
rag conv

# Input by specifying a specific past session
rag conv "C:\path\to\specific.jsonl"

5. ผสมผสานรหัส Claude — ต่อสู้กับเสียงรบกวน

นี่คือสิ่งที่น่าสนใจเล็กน้อย Claude Code ผสมกับเหตุการณ์เมตามากมายนอกเหนือจากการสนทนา ดังนั้นจึงจำเป็นต้องมีตัวกรอง

5.1 สิ่งของที่ต้องนำออก/ทิ้ง

typeบางสิ่งบางอย่างนำเข้า
userข้อความผู้ใช้✅ อย่างไรก็ตาม เฉพาะบล็อกข้อความเท่านั้นที่ถูกแยกออกจากอาร์เรย์ content
assistantการตอบสนองของ AI✅ ในทำนองเดียวกัน ให้แยกเฉพาะบล็อกข้อความ
queue-operationการดำเนินการคิว (เหตุการณ์การประมวลผลภายใน)
attachmentข้อมูลไฟล์แนบ
file-history-snapshotประวัติไฟล์
ai-titleการกำหนดชื่อเซสชัน
last-promptเมตาดาต้าพร้อมท์สุดท้าย

5.2 กำลังประมวลผลอาร์เรย์บล็อกเนื้อหา

User/AI ทั้งข้อความ message.content เป็นอาร์เรย์และมีประเภทบล็อกผสม

def _extract_text_blocks(content) -> str:
    """Concatenate and return only text block from message.content"""
    if isinstance(content, str):
        return content.strip()
    if not isinstance(content, list):
        return ""
    parts = []
    for block in content:
        if not isinstance(block, dict):
            continue
        if block.get("type") == "text":
            txt = block.get("text", "")
            if isinstance(txt, str) and txt.strip():
                parts.append(txt.strip())
    return "\n\n".join(parts)

บล็อกอื่นที่ไม่ใช่ text (thinking / tool_use / tool_result) จะถูกข้ามไป thinking เป็นการคิดภายในของ AI ดังนั้นจึงเป็นการดีกว่าที่จะไม่รวมไว้ในโฟลว์ของการสนทนา เนื่องจากเสียงรบกวนในการค้นหาจะลดลง และ tool_use เป็น JSON ที่มีโครงสร้าง ดังนั้นจึงไม่เหมาะสำหรับการค้นหาข้อความ

5.3 การลบแท็กที่แทรกอัตโนมัติ

ข้อความของผู้ใช้ผสมกับแท็กที่ Claude Code แทรกโดยอัตโนมัติ

<system-reminder>The TodoWrite tool hasn't been used recently...</system-reminder>
<ide_opened_file>The user opened the file ...</ide_opened_file>
<command-message>...</command-message>

หากคุณป้อน RAG โดยมีจำนวนที่เหลือ เมื่อคุณค้นหา “สิ่งที่พูดในการสนทนานั้น” เนื้อหาแท็ก (เสียงรบกวนทั่วไป) จะถูกโจมตี งั้นฉันจะเอามันออก

NOISE_TAG_RE = re.compile(
    r"<(system-reminder|ide_opened_file|ide_selection|command-message|command-name|command-args|local-command-stdout)>.*?</\1>",
    re.DOTALL,
)

def _strip_noise(text: str) -> str:
    if not text:
        return ""
    cleaned = NOISE_TAG_RE.sub("", text)
    cleaned = re.sub(r"\n{3,}", "\n\n", cleaned) # Clean up empty lines
    return cleaned.strip()

DOTALL ตัดข้ามตัวแบ่งบรรทัดพร้อมกัน เพียงทำเช่นนี้ ฉันก็พบว่ามีความแม่นยำในการค้นหาเพิ่มขึ้น 30%

5.4 ตัวพาร์เซอร์

เมื่อรวมสิ่งเหล่านี้เข้าด้วยกัน parser สำหรับ Claude Code จะมีลักษณะดังนี้:

def parse_conversation(jsonl_path: Path) -> list[dict]:
    turns: list[dict] = []
    pending_user: dict | None = None

    with open(jsonl_path, encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            try:
                record = json.loads(line)
            except json.JSONDecodeError:
                continue

            rtype = record.get("type")
            msg = record.get("message", {}) or {}

            if rtype == "user":
                content = msg.get("content") if isinstance(msg, dict) else None
                text = _strip_noise(_extract_text_blocks(content))
                if text:
                    pending_user = {"content": text, "timestamp": record.get("timestamp", "")}
                    elif rtype == "assistant":
                content = msg.get("content") if isinstance(msg, dict) else None
                text = _extract_text_blocks(content) # AI response does not require denoising
                if text and pending_user:
                    turns.append({
                        "user": pending_user["content"],
                        "assistant": text,
                        "timestamp": pending_user["timestamp"],
                    })
                    pending_user = None

    return turns

มันเป็นตรรกะ “การซ้อนคู่” แบบเดียวกับสำหรับ Copilot แต่ประเด็นสำคัญคือ การแยกบล็อกและการกำจัดสัญญาณรบกวนจะถูกประกบกันในขั้นตอนก่อนหน้า


6. รหัส Claude จะถูกป้อนโดยอัตโนมัติด้วย Stop hook

สำหรับ Copilot Chat นั้น rag conv จะถูกดำเนินการด้วยตนเอง แต่ Claude Code มีกลไกที่เรียกว่า Stop hook คำสั่งใดๆ ก็สามารถดำเนินการได้ทันทีที่เซสชันสิ้นสุดลง ซึ่งจะทำให้คุณสามารถ ทำให้เป็นอัตโนมัติ ได้อย่างเต็มที่

เขียนสิ่งนี้ลงใน `~/.claude/settings.json

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"C:\\Users\\<user>\\git\\my-rag-brain\\scripts\\claude_code_stop_hook.ps1\""
          }
        ]
      }
    ]
  }
}

สคริปต์ PowerShell ที่เรียกว่ามีลักษณะเช่นนี้

# read JSON from stdin, extract transcript_path and start ingest
$stdin = [Console]::In.ReadToEnd()
$payload = $stdin | ConvertFrom-Json
$transcript = $payload.transcript_path

if (-not (Test-Path $transcript)) { return }

# Start in background (don't block Stop hook for long time)
$env:PYTHONIOENCODING = 'utf-8'
Start-Process -FilePath "<venv>\python.exe" `
    -ArgumentList @("<my-rag-brain>\src\pipeline\ingest_claude_code.py", $transcript) `
    -WindowStyle Hidden `
    -RedirectStandardOutput $stdoutLog `
    -RedirectStandardError $stderrLog

สองจุด:

  1. อ่าน transcript_path จาก stdin — Claude Code ส่งให้เราใน JSON
  2. การเริ่มต้นพื้นหลังด้วย Start-Process — เพื่อหลีกเลี่ยงการบล็อก Stop hook เป็นเวลานาน

ตอนนี้ เมื่อคุณปิด Claude Code เซสชันจะถูกแทรกลงใน ChromaDB โดยอัตโนมัติ ไม่มีอะไรที่ต้องทำด้วยตนเอง


7. มีอะไรเปลี่ยนแปลงบ้าง? ความรู้สึกปลอดภัยที่ช่วยให้คุณสามารถค้นหา “ตัวตนในอดีต” ของคุณ

หลังจากผ่านไปหลายสิบครั้ง เหตุการณ์เช่นนี้ก็เริ่มเกิดขึ้น

7.1 “คุณแก้ปัญหานั้นได้อย่างไร” ปัญหาหายไป

เมื่อฉันพบข้อผิดพลาดในการเข้ารหัสอักขระใน PowerShell:

ค้นหาเศษผ้า "อักขระที่อ่านไม่ออกของ PowerShell UTF-8"

จากนั้นโซลูชัน 5 อันดับแรกที่สร้างขึ้นในอดีตเมื่อพูดถึงปัญหาเดียวกันกับ Copilot และ Claude Code จะถูกส่งคืน คุณสามารถจำได้ทันทีว่า “โอ้ ฉันใส่ PYTHONIOENCODING=utf-8 ไว้ในตัวแปรสภาพแวดล้อม”

7.2 ข

้อสรุปของการโต้แย้งถูกทำให้ถาวรในเซสชันที่มีการหารือเกี่ยวกับการตัดสินใจในการออกแบบและนโยบายการดำเนินงาน การเลี้ยวทั้ง 3 ครั้งก่อนและหลังการสรุปจะถูกบันทึกเป็นชิ้นเดียว หลังจากนั้น หากคุณค้นหาว่า ปัจจัยในการตัดสินใจที่อยู่เบื้องหลังการตัดสินใจออกแบบนั้นคืออะไร'' ลำดับการสนทนาทั้งหมดจะปรากฏขึ้น **บริบทของ ทำไมเราถึงทำ” ที่ไม่สามารถเขียนลงในเอกสารการออกแบบได้** มักถูกทิ้งไว้ข้างหลัง

7.3 คุณจะมีโอกาสทำผิดพลาดน้อยลง

กับดักที่ “ตัวตนในอดีต” ของฉันก้าวเข้าไปนั้นถูกซ่อนไว้อย่างลึกลับใกล้กับตัวตนปัจจุบันของฉัน เมื่อคุณค้นหาบันทึกที่ผ่านมาด้วย rag search "<関連キーワード>" ก่อนที่จะเริ่มงานใหม่ คุณมักจะได้รับการเตือนถึง บันทึกที่ถูกลืม

โดยเฉพาะอย่างยิ่งหลังจากติดตั้งการแทรกตะขอหยุดอัตโนมัติของ Claude Code ความทรงจำของฉันก็สะสมโดยที่ฉันไม่รู้ตัว ดังนั้นประสบการณ์การค้นหาของฉันจึงดีขึ้นเรื่อยๆ


8. ข้อควรทราบ/ข้อจำกัด

8.1 ความเสี่ยงจากการปะปนข้อมูลที่เป็นความลับ

การสนทนาอาจรวมถึง ข้อความที่ตัดตอนมาจากโค้ด, คีย์ API, URL และข้อมูลส่วนบุคคล ไม่มีปัญหาตราบใดที่ปิดไปยัง ChromaDB ในเครื่อง แต่จำเป็นอย่างยิ่งที่คุณจะต้องไม่ส่งไดเรกทอรี ChromaDB ไปยังพื้นที่เก็บข้อมูลสาธารณะโดยใช้ Git ฉันมี chroma_db/ ใน .gitignore

8.2 กฎการกำจัดเสียงรบกวนต้องมีการบำรุงรักษา

แท็กการแทรกอัตโนมัติของ Claude Code อาจเพิ่มขึ้นในอนาคต รายการแท็กที่ถูกลบโดย NOISE_TAG_RE ครั้งนี้มาจากช่วงที่ฉันสังเกตเห็น มีค่าใช้จ่ายในการดำเนินการ เพิ่มแท็กใหม่ตามที่ปรากฏ

8.3 การฝังการสนทนาแบบเก่าอาจสูญเสียความแม่นยำหากไม่สร้างใหม่

เมื่อคุณอัปเดตโมเดลการฝังของ Ollama การฝังของก้อนเก่าและการฝังของก้อนใหม่จะอยู่ใน ช่องว่างที่แตกต่างกันเล็กน้อย จำเป็นต้องฝังใหม่ทั้งหมด เพื่อความเข้ากันได้อย่างสมบูรณ์ ซึ่งทำได้โดยใช้ rag bulk เพื่อส่งรายการทั้งหมดอีกครั้ง

8.4 ความแม่นยำในการค้นหาอาจลดลงหากคุณ “ใส่ทุกอย่างลงไป”

ข้อผิดพลาดที่ไม่คาดคิดคือการรวม เซสชันเริ่มต้นที่มีเสียงดังรบกวน และ เซสชันที่จบลงด้วยข้อผิดพลาด จะลดความแม่นยำในการค้นหา source_file ด้วยการกรองด้วยข้อมูลเมตาหรือโดยการแบ่ง source_type ออกเป็นส่วนเล็กๆ คุณสามารถจำกัดการค้นหาของคุณให้แคบลงได้


9. สรุป

  • VSCode Copilot Chat บันทึกประวัติการสนทนาไปที่ workspaceStorage/.../transcripts/*.jsonl โดยอัตโนมัติ และ Claude Code บันทึกประวัติการสนทนาไปที่ ~/.claude/projects/<slug>/<session-id>.jsonl โดยอัตโนมัติ
  • JSONL ทั้งสองมีโครงสร้างที่แตกต่างกัน (Copilot นั้นเรียบง่าย Claude Code มีบล็อกอาร์เรย์ + เหตุการณ์เมตาผสมกัน) แต่สามารถดูดซับได้โดยใช้พาร์เซอร์แยกกัน + การกำหนดมาตรฐานและต่อมา
  • การกำจัดเสียงรบกวน (การลบแท็ก เช่น <system-reminder>) ส่งผลให้ความแม่นยำในการค้นหาแตกต่างกัน 30%
  • ด้าน Claude Code สามารถทำงานอัตโนมัติได้อย่างสมบูรณ์ด้วย Stop hook + การเริ่มต้นพื้นหลัง
  • หลังจากสะสมเซสชันได้หลายสิบเซสชัน คุณจะสามารถค้นหา “ตัวตนในอดีต” ในภาษาธรรมชาติได้ ฉันจำวิธีแก้ปัญหานั้น การตัดสิน และกับดักนั้นได้ทันที
  • การจัดการข้อมูลที่เป็นความลับ การบำรุงรักษากฎการกำจัดสัญญาณรบกวน การสร้างใหม่เมื่ออัปเดตโมเดลการฝัง — แม้ว่าจะมีค่าใช้จ่ายในการดำเนินการ แต่ผลตอบแทนที่ได้รับก็มีจำนวนมากอย่างท่วมท้นบทความที่เกี่ยวข้อง:
  • กลไกในการป้องกันไม่ให้ Copilot ทำผิดพลาดซ้ำสองครั้ง — ออกแบบให้มี “ความทรงจำในการสนทนา” ด้วย RAG + MCP — การใช้งานเซิร์ฟเวอร์ MCP สำหรับ Copilot เพื่อค้นหาอัตโนมัติแบบเรียลไทม์ที่ป้อนประวัติการสนทนาในบทความนี้
  • ฉันใช้ GitHub Copilot เป็นเวลาหนึ่งเดือน และใช้ Claude Code เป็นเวลาสองวัน พาร์ทเนอร์และเจ้าหน้าที่เขียนโค้ดเป็นสองสิ่งที่แตกต่างกัน — ความแตกต่างในบุคลิกของ Copilot และ Claude Code

แม้ว่า AI จะลืมฉันก็จะบันทึกมันไว้ จากนั้นเมื่อจำเป็นให้ “เตือน” จากด้านนี้ นี่คือทัศนคติพื้นฐานของฉันเมื่อทำงานกับ AI

ส่งข้อความได้ตามสบาย

ไม่ว่าจะเป็นการว่าจ้างงาน แนะนำโปรเจกต์ ความคิดเห็น หรือคำถาม ยินดีรับทั้งหมด ฉันหวังเป็นอย่างยิ่งว่าจะได้เชื่อมต่อกับผู้ที่มีอุดมการณ์อันสูงส่งเช่นเดียวกัน ฉันจะมุ่งมั่นท้าทายในสิ่งที่ทุ่มเททั้งชีวิตต่อไป ขอขอบคุณและฝากเนื้อฝากตัวด้วยครับ/ค่ะ