็†ฑ้–€ๅˆ†้กž
 ่ผ‰ๅ…ฅไธญ…
็›ฎ้Œ„

๐Ÿค– ๅœฐ็ซฏ AI ้€ฒ้šŽๆ‡‰็”จ:ไฝฟ็”จ Ollama ่ˆ‡ Python ๅปบ็ซ‹็งๆœ‰ๆŠ€่ก“ๆ–‡ไปถๅŠฉๆ‰‹

    ๐Ÿ ๐Ÿค– ๅœฐ็ซฏ AI ้€ฒ้šŽๆ‡‰็”จ:ไฝฟ็”จ Ollama ่ˆ‡ Python ๅปบ็ซ‹็งๆœ‰ๆŠ€่ก“ๆ–‡ไปถๅŠฉๆ‰‹

    ๆŠŠ「ๅ…ฌๅธๅ…ง้ƒจ SOP、็ถญ้‹็ญ†่จ˜、Runbook、ๆ•…้šœๆŽ’ๆŸฅๆ‰‹ๅ†Š」ไธŸ็ตฆ้›ฒ็ซฏ AI ไพ†ๅ•็ญ”,ๆœ€ๅคง็š„็—›้ปž้€šๅธธไธๆ˜ฏๆ•ˆๆžœ,่€Œๆ˜ฏ่ณ‡ๆ–™ๅค–ๆต้ขจ้šช่ˆ‡ๅˆ่ฆๅ•้กŒ

    ้€™็ฏ‡่ฆๅš็š„ๆ˜ฏไธ€ๅ€‹「ๅœฐ็ซฏ็งๆœ‰ๅŒ–」็š„ๆŠ€่ก“ๆ–‡ไปถๅŠฉๆ‰‹:

    • LLM ๅœจๅœฐ็ซฏ่ท‘(Ollama)
    • ๆ–‡ไปถๅ‘้‡ๅŒ–(embeddings)ๅพŒๅญ˜้€ฒ SQLite(ไธ็”จ้กๅค–ๆžถๅ‘้‡่ณ‡ๆ–™ๅบซไนŸ่ƒฝ่ท‘)
    • ๆŸฅ่ฉขๆ™‚ๅ…ˆๆชข็ดข็›ธ้—œ็‰‡ๆฎต,ๅ†ไบค็ตฆๆจกๅž‹ๆ•ด็†(RAG)
    • ็ญ”ๆกˆ้™„ไธŠ「ๅผ•็”จ็‰‡ๆฎตไพ†ๆบ」,ๆ–นไพฟไฝ ๅ›ž้ ญๆ ธๅฐ

    ๐Ÿ“Œ ็›ฎ้Œ„


    1. ๆ•ด้ซ”ๆžถๆง‹(RAG)

    RAG(Retrieval-Augmented Generation)็š„้‡้ปž:ๅ…ˆๆ‰พ่ณ‡ๆ–™,ๅ†ๅซๆจกๅž‹ๅ›ž็ญ”,้ฟๅ…ๆจกๅž‹ๆ†‘ๅฐ่ฑกไบ‚่ฃœ。

    ไฝฟ็”จ่€…ๅ•้กŒ
       │
       ├─(1) ๅ‘้‡ๅŒ–(embedding)
       │
       ├─(2) SQLite ๅ– Top-K ็›ธไผผ็‰‡ๆฎต(cosine similarity)
       │
       └─(3) ๆŠŠ「็‰‡ๆฎต + ๅ•้กŒ」ไธŸ็ตฆ LLM ็”Ÿๆˆ็ญ”ๆกˆ
               └─(4) ็ญ”ๆกˆ้™„ไธŠไพ†ๆบ(ๆช”ๅ/ๆฎต่ฝ)

    ไฝ ๆœƒๅŒๆ™‚่ท‘ๅ…ฉ็จฎๆจกๅž‹:

    • ่Šๅคฉ/็”Ÿๆˆๆจกๅž‹:่ฒ ่ฒฌ「ๆ•ด็†ๆˆๅฏ่ฎ€็ญ”ๆกˆ」
    • Embedding ๆจกๅž‹:่ฒ ่ฒฌๆŠŠๆ–‡ๅญ—่ฎŠๆˆๅ‘้‡,ๆ‹ฟไพ†ๅš็›ธไผผๅบฆๆชข็ดข

    2. ๅฎ‰่ฃ Ollama ่ˆ‡ๆจกๅž‹ๆบ–ๅ‚™

    2.1 Linux ๅฎ‰่ฃ Ollama

    curl -fsSL https://ollama.com/install.sh | sh

    ่‹ฅไฝ ๅธŒๆœ›ๅฎƒไปฅ systemd ๆœๅ‹™ๅฝขๅผ้•ท้ง(ไผบๆœๅ™จ็’ฐๅขƒๅพˆๅธธ่ฆ‹),ๅฏไปฅ็”จๅฎ˜ๆ–นๆ–‡ไปถ็š„ๆ–นๅผๅปบ็ซ‹ไธฆๅ•Ÿ็”จๆœๅ‹™(ๆˆ–็›ดๆŽฅไฝฟ็”จๅฎ‰่ฃๅพŒ้™„ๅธถ็š„ๆœๅ‹™)。้œ€่ฆ่ชฟๆ•ด็’ฐๅขƒ่ฎŠๆ•ธๆ™‚,ๅฏ็”จ systemctl edit ๅš override。

    2.2 ไธ‹่ผ‰ๆจกๅž‹(ๅปบ่ญฐไธ€ๅ€‹่Šๅคฉๆจกๅž‹ + ไธ€ๅ€‹ embeddings ๆจกๅž‹)

    # ่Šๅคฉๆจกๅž‹(ๆ“‡ไธ€)
    ollama pull gemma3
    # ๆˆ–
    ollama pull llama3.2
    
    # Embeddings ๆจกๅž‹(ๆ“‡ไธ€)
    ollama pull embeddinggemma
    # ๆˆ–
    ollama pull all-minilm

    ๅฐๆ้†’:embedding ๆจกๅž‹้€šๅธธๆฏ”่Šๅคฉๆจกๅž‹่ผ•้‡;ไฝ ไนŸๅฏไปฅไพ็กฌ้ซ”่ณ‡ๆบ่ชฟๆ•ด้ธๆ“‡(CPU-only ไนŸ่ƒฝ่ท‘,ๅชๆ˜ฏ้€Ÿๅบฆๆœƒๆฏ”่ผƒๆ…ข)。


    3. Ollama API ๅฟซ้€Ÿๆธฌ่ฉฆ

    Ollama ็š„ API ้ ่จญๅœจๆœฌๆฉŸๆไพ›ๆœๅ‹™(base URL:http://localhost:11434/api),ไฝ ๅฏไปฅ็”จ curl ๅ…ˆ้ฉ—่ญ‰。
    (REST API ้ ่จญๆ˜ฏไธฒๆต่ผธๅ‡บ,ๆƒณไธ€ๆฌกๆ‹ฟๅฎŒๆ•ด็ตๆžœๅฏไปฅๅŠ  "stream": false

    3.1 ๆ–‡ๅญ—็”Ÿๆˆ(/api/generate)

    curl http://localhost:11434/api/generate -d '{
      "model": "gemma3",
      "prompt": "่ซ‹็”จไธ‰้ปžๅˆ—ๅ‡บ:RAG ็š„ๆ ธๅฟƒๅƒนๅ€ผๆ˜ฏไป€้บผ?",
      "stream": false
    }'

    3.2 ๅฐ่ฉฑ(/api/chat)

    curl http://localhost:11434/api/chat -d '{
      "model": "gemma3",
      "messages": [
        { "role": "system", "content": "ไฝ ๆ˜ฏๅšด่ฌน็š„ๆŠ€่ก“ๆ–‡ไปถๅŠฉๆ‰‹,ๅ›ž็ญ”่ฆ้™„ไธŠๅผ•็”จไพ†ๆบ。" },
        { "role": "user", "content": "ไป€้บผๆƒ…ๅขƒ้ฉๅˆ็”จ Active Check?" }
      ],
      "stream": false
    }'

    3.3 Embeddings(/api/embed)

    curl http://localhost:11434/api/embed -d '{
      "model": "embeddinggemma",
      "input": "Zabbix Proxy ๅฏไปฅ็ทฉ่ก่ณ‡ๆ–™ไธฆ้™ไฝŽ Server ๅฃ“ๅŠ›",
      "truncate": true
    }'

    4. Python ๅฐˆๆกˆๅˆๅง‹ๅŒ–

    ้€™่ฃก็”จๆœ€ๅฐ‘ไพ่ณด:requests + sqlite3(ๆจ™ๆบ–ๅบซ)ๅฐฑ่ƒฝๅฎŒๆˆ。

    mkdir private-docs-assistant && cd private-docs-assistant
    python -m venv .venv
    source .venv/bin/activate
    
    pip install -U pip
    pip install requests

    ๅปบ่ญฐๅฐˆๆกˆ็ตๆง‹:

    private-docs-assistant/
      docs/                  # ไฝ ็š„็งๆœ‰ๆ–‡ไปถ(md/txt/html ้ƒฝๅฏๅ…ˆๆ”พ้€™)
      assistant.py           # ไธป็จ‹ๅผ(ๅซ ingest + ask)
      kb.sqlite3             # SQLite ็Ÿฅ่ญ˜ๅบซ(่‡ชๅ‹•็”ข็”Ÿ)
    

    5. ๅฏฆไฝœ:็งๆœ‰ๆŠ€่ก“ๆ–‡ไปถๅŠฉๆ‰‹(SQLite ๅ‘้‡ๆชข็ดข + ๅ•็ญ”)

    ้€™ๆ”ฏ่…ณๆœฌๆไพ›ๅ…ฉๅ€‹ๆŒ‡ไปค:

    • python assistant.py ingest ./docs:ๆŠŠ่ณ‡ๆ–™ๅˆ‡็‰‡ + embeddings + ๅญ˜ SQLite
    • python assistant.py ask "ไฝ ็š„ๅ•้กŒ":ๆชข็ดข Top-K ็‰‡ๆฎต + LLM ็”Ÿๆˆ็ญ”ๆกˆ(้™„ไพ†ๆบ)
    #!/usr/bin/env python3
    # assistant.py
    import argparse
    import json
    import math
    import os
    import re
    import sqlite3
    from dataclasses import dataclass
    from pathlib import Path
    from typing import List, Tuple
    
    import requests
    
    OLLAMA_BASE = os.environ.get("OLLAMA_BASE", "http://localhost:11434/api")
    CHAT_MODEL = os.environ.get("OLLAMA_CHAT_MODEL", "gemma3")
    EMBED_MODEL = os.environ.get("OLLAMA_EMBED_MODEL", "embeddinggemma")
    DB_PATH = os.environ.get("KB_DB", "kb.sqlite3")
    
    # --- ๆ–‡ๅญ—่™•็†:็ฐกๅ–ฎๅˆ‡็‰‡(ๅฏไพไฝ ๆ–‡ไปถๅž‹ๆ…‹ๅ†ๅŠ ๅผท) ---
    def read_text_file(path: Path) -> str:
        text = path.read_text(encoding="utf-8", errors="ignore")
        # ็ฒ—็•ฅๆธ…็†:ๅคš็ฉบ็™ฝ็ธฎๆธ›
        text = re.sub(r"[ \t]+", " ", text)
        text = re.sub(r"\n{3,}", "\n\n", text)
        return text.strip()
    
    def chunk_text(text: str, chunk_size: int = 900, overlap: int = 150) -> List[str]:
        if not text:
            return []
        chunks = []
        i = 0
        n = len(text)
        while i < n:
            j = min(n, i + chunk_size)
            chunk = text[i:j].strip()
            if chunk:
                chunks.append(chunk)
            i = j - overlap
            if i < 0:
                i = 0
            if j == n:
                break
        return chunks
    
    # --- Ollama API ---
    def ollama_embed(texts: List[str]) -> List[List[float]]:
        # /api/embed ๆ”ฏๆด input ็‚บๅญ—ไธฒๆˆ–ๅญ—ไธฒ้™ฃๅˆ—
        r = requests.post(
            f"{OLLAMA_BASE}/embed",
            json={"model": EMBED_MODEL, "input": texts, "truncate": True},
            timeout=300,
        )
        r.raise_for_status()
        data = r.json()
        return data["embeddings"]
    
    def ollama_chat(system: str, user: str) -> str:
        payload = {
            "model": CHAT_MODEL,
            "messages": [
                {"role": "system", "content": system},
                {"role": "user", "content": user},
            ],
            "stream": False,
        }
        r = requests.post(f"{OLLAMA_BASE}/chat", json=payload, timeout=300)
        r.raise_for_status()
        data = r.json()
        return data["message"]["content"]
    
    # --- ๅ‘้‡้‹็ฎ— ---
    def cosine_sim(a: List[float], b: List[float]) -> float:
        dot = sum(x * y for x, y in zip(a, b))
        na = math.sqrt(sum(x * x for x in a))
        nb = math.sqrt(sum(y * y for y in b))
        if na == 0 or nb == 0:
            return 0.0
        return dot / (na * nb)
    
    # --- SQLite KB ---
    def init_db(conn: sqlite3.Connection) -> None:
        conn.execute("""
        CREATE TABLE IF NOT EXISTS chunks (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          path TEXT NOT NULL,
          chunk_index INTEGER NOT NULL,
          content TEXT NOT NULL,
          embedding TEXT NOT NULL
        )
        """)
        conn.execute("CREATE INDEX IF NOT EXISTS idx_chunks_path ON chunks(path)")
        conn.commit()
    
    def save_chunks(conn: sqlite3.Connection, path: str, chunks: List[str], embeds: List[List[float]]) -> None:
        conn.execute("DELETE FROM chunks WHERE path = ?", (path,))
        rows = [
            (path, i, chunks[i], json.dumps(embeds[i], ensure_ascii=False))
            for i in range(len(chunks))
        ]
        conn.executemany(
            "INSERT INTO chunks(path, chunk_index, content, embedding) VALUES (?, ?, ?, ?)",
            rows,
        )
        conn.commit()
    
    def load_all(conn: sqlite3.Connection) -> List[Tuple[str, int, str, List[float]]]:
        cur = conn.execute("SELECT path, chunk_index, content, embedding FROM chunks")
        out = []
        for path, idx, content, emb_json in cur.fetchall():
            out.append((path, idx, content, json.loads(emb_json)))
        return out
    
    @dataclass
    class Hit:
        score: float
        path: str
        chunk_index: int
        content: str
    
    def search(conn: sqlite3.Connection, query: str, top_k: int = 5) -> List[Hit]:
        q_emb = ollama_embed([query])[0]
        items = load_all(conn)
    
        scored = []
        for path, idx, content, emb in items:
            s = cosine_sim(q_emb, emb)
            scored.append(Hit(score=s, path=path, chunk_index=idx, content=content))
    
        scored.sort(key=lambda x: x.score, reverse=True)
        return scored[:top_k]
    
    # --- CLI ---
    def cmd_ingest(args) -> None:
        docs_dir = Path(args.dir).resolve()
        assert docs_dir.exists(), f"docs dir not found: {docs_dir}"
    
        conn = sqlite3.connect(DB_PATH)
        init_db(conn)
    
        files = []
        for ext in ("*.md", "*.txt", "*.log", "*.html"):
            files.extend(docs_dir.rglob(ext))
    
        if not files:
            print("ๆ‰พไธๅˆฐๅฏๅŒฏๅ…ฅ็š„ๆช”ๆกˆ(md/txt/log/html)。")
            return
    
        for fp in sorted(files):
            text = read_text_file(fp)
            chunks = chunk_text(text, chunk_size=args.chunk_size, overlap=args.overlap)
    
            if not chunks:
                continue
    
            embeds = ollama_embed(chunks)
            rel_path = str(fp.relative_to(docs_dir))
            save_chunks(conn, rel_path, chunks, embeds)
            print(f"[OK] {rel_path}  chunks={len(chunks)}")
    
        print("ๅฎŒๆˆ:็Ÿฅ่ญ˜ๅบซๅทฒๆ›ดๆ–ฐ。")
    
    def cmd_ask(args) -> None:
        conn = sqlite3.connect(DB_PATH)
        init_db(conn)
    
        hits = search(conn, args.question, top_k=args.top_k)
    
        if not hits:
            print("ๆ‰พไธๅˆฐ็›ธ้—œ็‰‡ๆฎต,่ซ‹็ขบ่ชๅทฒๅŸท่กŒ ingest,ๆˆ–่ชฟๆ•ดๅ•้กŒๆ่ฟฐ。")
            return
    
        context_lines = []
        for i, h in enumerate(hits, 1):
            context_lines.append(
                f"[{i}] {h.path}#{h.chunk_index} (score={h.score:.3f})\n{h.content}\n"
            )
        context = "\n---\n".join(context_lines)
    
        system = (
            "ไฝ ๆ˜ฏ『็งๆœ‰ๆŠ€่ก“ๆ–‡ไปถๅŠฉๆ‰‹』,ๅช่ƒฝๆ นๆ“šไฝฟ็”จ่€…ๆไพ›็š„【ๅผ•็”จ็‰‡ๆฎต】ๅ›ž็ญ”。"
            "่‹ฅ็‰‡ๆฎตไธ่ถณไปฅๅพ—ๅ‡บ็ต่ซ–,่ซ‹็›ดๆŽฅ่ชช『ๆ–‡ไปถ็‰‡ๆฎตไธ่ถณ,ๅปบ่ญฐ่ฃœๅ……:...』,ไธ่ฆ่‡ช่กŒ็ทจ้€ 。"
            "ๅ›ž็ญ”ๆ ผๅผ่ฆๆฑ‚:\n"
            "1) ๅ…ˆ็ตฆ็ต่ซ–(ๆขๅˆ—)\n"
            "2) ๅ†็ตฆๆ“ไฝœๆญฅ้ฉŸ(่‹ฅ้ฉ็”จ)\n"
            "3) ๆœ€ๅพŒๅˆ—ๅ‡บไฝ ๅผ•็”จ็š„็‰‡ๆฎต็ทจ่™Ÿ(ไพ‹ๅฆ‚:ๅผ•็”จ:[1][3])\n"
        )
    
        user = (
            f"【ๅ•้กŒ】\n{args.question}\n\n"
            f"【ๅผ•็”จ็‰‡ๆฎต】\n{context}\n\n"
            "่ซ‹้–‹ๅง‹ๅ›ž็ญ”。"
        )
    
        ans = ollama_chat(system, user)
        print(ans)
    
    def main():
        p = argparse.ArgumentParser(description="Private Tech Docs Assistant (Ollama + SQLite)")
        sub = p.add_subparsers(dest="cmd", required=True)
    
        p_ing = sub.add_parser("ingest", help="ingest docs into sqlite kb")
        p_ing.add_argument("dir", help="docs folder, e.g. ./docs")
        p_ing.add_argument("--chunk-size", type=int, default=900)
        p_ing.add_argument("--overlap", type=int, default=150)
        p_ing.set_defaults(func=cmd_ingest)
    
        p_ask = sub.add_parser("ask", help="ask a question with retrieval")
        p_ask.add_argument("question", help="your question")
        p_ask.add_argument("--top-k", type=int, default=5)
        p_ask.set_defaults(func=cmd_ask)
    
        args = p.parse_args()
        args.func(args)
    
    if __name__ == "__main__":
        main()

    5.1 ไฝฟ็”จๆ–นๅผ

    # 1) ๅ…ˆๅŒฏๅ…ฅไฝ ็š„ๆ–‡ไปถ
    python assistant.py ingest ./docs
    
    # 2) ้–‹ๅง‹ๅ•ๅ•้กŒ
    python assistant.py ask "่ซ‹ๆ•ด็†้€™ไปฝ Runbook ่ฃก,ๆœๅ‹™็„กๆณ•ๅ•Ÿๅ‹•ๆ™‚็š„ๆŽ’ๆŸฅ้ †ๅบ"

    6. ๅฏฆๅ‹™่ชฟๆ ก:ๆบ–็ขบๅบฆ、ๅฎ‰ๅ…จๆ€ง、ๆ•ˆ่ƒฝ

    6.1 ๆบ–็ขบๅบฆ:Top-K、ๅˆ‡็‰‡ๅคงๅฐ、ไปฅๅŠ「ๅ›ž็ญ”่ฆๅ‰‡」

    • Top-K:5 ้€šๅธธๅค ็”จ;่‹ฅๆ–‡ไปถๅพˆๅคง、็ญ”ๆกˆๅฎนๆ˜“ๆผๆฎต่ฝ,ๅฏ่ชฟๅˆฐ 8~12。
    • chunk size:900 ๅญ—ๅ…ƒๅทฆๅณๆ˜ฏๅธธ่ฆ‹ๆŠ˜่กท;ๅคชๅฐๆœƒ็ขŽ็‰‡ๅŒ–、ๅคชๅคงๆœƒๆทท้›œไธๅŒไธป้กŒ。
    • ๅ›ž็ญ”่ฆๅ‰‡(system prompt):ไธ€ๅฎš่ฆๆ˜Ž็ขบ่ฆๆฑ‚「ๅช่ƒฝๆ นๆ“šๅผ•็”จ็‰‡ๆฎต」,ไธ่ถณๅฐฑ่ชชไธ่ถณ。

    6.2 ๅฎ‰ๅ…จๆ€ง:ไธ่ฆ้šจไพฟๆŠŠ Ollama API ็›ดๆŽฅๅฐๅค–

    Ollama ้ ่จญๅชๅœจๆœฌๆฉŸๆไพ› API(ๆœฌ็ฏ‡ไนŸไปฅ localhost ็‚บๅ‰ๆ)。ๅฆ‚ๆžœไฝ ็œŸ็š„้œ€่ฆ่ทจๆฉŸๅ™จๅ‘ผๅซ,ๅปบ่ญฐๅ„ชๅ…ˆ็”จ:

    • SSH Tunnel(ๆœ€็œไบ‹)
    • ๆˆ–ๅๅ‘ไปฃ็†ๅŠ ไธŠๅญ˜ๅ–ๆŽง็ฎก(ไพ‹ๅฆ‚ Basic Auth / IP allowlist / mTLS)

    ่‹ฅไฝ ๆ˜ฏไปฅ systemd ๆ–นๅผ่ท‘ Ollama,ไนŸๅฏไปฅ็”จ service override ่จญๅฎš็’ฐๅขƒ่ฎŠๆ•ธ(ไพ‹ๅฆ‚ OLLAMA_HOST)。่จญๅฎš็’ฐๅขƒ่ฎŠๆ•ธ็š„ๆ–นๅผๅฏๅƒ่€ƒๅฎ˜ๆ–น FAQ ็š„็ฏ„ไพ‹。

    6.3 ๆ•ˆ่ƒฝ:ๆจกๅž‹ๅธธ้ง่ˆ‡ๅฟซๅ–

    • ๆœฌ็ฏ‡็”จ /api/chat ่ˆ‡ /api/embed,้ƒฝๅฏ้€้Ž keep_alive ่ฎ“ๆจกๅž‹ๅธธ้ง,ๆธ›ๅฐ‘ๅ่ฆ†่ผ‰ๅ…ฅๆˆๆœฌ。
    • ๆ–‡ไปถๅŒฏๅ…ฅ(ingest)ๆ˜ฏ้›ข็ทšไฝœๆฅญ,ๅปบ่ญฐๆŽ’็จ‹ๆ™šไธŠ่ท‘;็™ฝๅคฉๅชๅš ask。

    7. ็ถญ้‹ๅปบ่ญฐ:ๆ›ดๆ–ฐ、ๅ‚™ไปฝ、ๆฌŠ้™้š”้›ข

    7.1 ๆ›ดๆ–ฐ Ollama

    curl -fsSL https://ollama.com/install.sh | sh

    7.2 ๅ‚™ไปฝ็Ÿฅ่ญ˜ๅบซ

    cp kb.sqlite3 kb.sqlite3.bak

    7.3 ๆฌŠ้™้š”้›ข

    • ๆŠŠ docs/ ่ˆ‡ kb.sqlite3 ๆ”พๅœจๅชๆœ‰็ฎก็†่€…ๅฏ่ฎ€็š„่ทฏๅพ‘。
    • ่‹ฅๆ˜ฏๅคšไบบไฝฟ็”จ,ๅปบ่ญฐๆŠŠ Assistant ๅŒ…ๆˆๅ…ง็ถฒๆœๅ‹™,ๅ†็”จๅธณ่™ŸๆฌŠ้™ๅšๆŽง็ฎก(้ฟๅ…ๆฏๅ€‹ไบบ็›ดๆŽฅ่ฎ€ๅˆฐๆ‰€ๆœ‰ๆ–‡ไปถ)。

    FAQ

    Q1:็‚บไป€้บผ embeddings ไธ็›ดๆŽฅ็”จ่Šๅคฉๆจกๅž‹ๅš?

    ๅ› ็‚บ embeddings ๆ˜ฏ「็‚บๆชข็ดข่€Œ็”Ÿ」:ๅ‘้‡ๅ“่ณชๆ›ด็ฉฉ、้€Ÿๅบฆๆ›ดๅฟซ、ๆˆๆœฌๆ›ดไฝŽ。่Šๅคฉๆจกๅž‹ไธป่ฆ่ฒ ่ฒฌๆ•ด็†่ชžๅฅ่ˆ‡่ผธๅ‡บ็ญ”ๆกˆ。

    Q2:SQLite ็œŸ็š„ๅค ็”จๅ—Ž?

    ๅฐๅˆฐไธญๅž‹(ๅนพๅƒๅˆฐๅนพ่ฌๅ€‹ chunks)้€šๅธธๆฒ’ๅ•้กŒ。่‹ฅไฝ ไธŠๅ‡ๅˆฐๅ่ฌ็ดšไปฅไธŠ,ๆˆ–ๅคšไบบไฝต็™ผๆŸฅ่ฉข,ๅฐฑๅปบ่ญฐๆ›ๆˆๅฐˆ็”จๅ‘้‡่ณ‡ๆ–™ๅบซๆˆ–่‡ณๅฐ‘ๆŠŠๆชข็ดขๅฑคๅšๆœๅ‹™ๅŒ–。

    Q3:ๆ€Ž้บผ่ฎ“็ญ”ๆกˆๆ›ด「ๅƒๆŠ€่ก“ๆ–‡ไปถ」่€Œไธๆ˜ฏ่Šๅคฉ?

    ๆŠŠ system prompt ๅฏซๅพ—ๆ›ด็กฌไธ€้ปž:่ฆๆฑ‚「ๆขๅˆ—、ๆญฅ้ฉŸ、ๆŒ‡ไปค、้ขจ้šช、ๅ›žๅพฉๆ–นๅผ」,ไธฆๅผทๅˆถ้™„ไธŠๅผ•็”จ็‰‡ๆฎต็ทจ่™Ÿ。


    ๐Ÿ’ฌ ็•™่จ€่Š่Šไฝ ็š„ๆ–‡ไปถ้กžๅž‹

    ไฝ ็š„ๆ–‡ไปถไธป่ฆๆ˜ฏ SOP / Runbook / Markdown ็ญ†่จ˜ / Wiki / HTML ๆ‰‹ๅ†Š?
    ไฝ ๅธŒๆœ›ๅ›ž็ญ”「ๆ›ดๅšด่ฌน」้‚„ๆ˜ฏ「ๆ›ดๅƒๅ”ไฝœๅŒไบ‹」?ๆˆ‘ๅฏไปฅไพไฝ ็š„ๅ…งๅฎนๅž‹ๆ…‹,ๅนซไฝ ๆŠŠๅˆ‡็‰‡่ฆๅ‰‡、Top-K ่ˆ‡ๆ็คบ่ฉž่ชฟๆˆๆ›ดๆบ–。

    ๐Ÿ”— ๅˆ†ไบซ้€™็ฏ‡ LINE Facebook X

    ๆฒ’ๆœ‰็•™่จ€:

    ๅผต่ฒผ็•™่จ€

    ๅญ—็ดš