# Octocode 0.17.1: Local Embeddings ด้วย Ollama, vLLM และ OpenAI-Compatible Server ใด ๆ

> Octocode 0.17.1 index โค้ดของคุณด้วย local embedding provider — ชี้ไปที่ OpenAI-compatible server ใด ๆ (Ollama, vLLM, LM Studio) แล้วมันจะ auto-detect dimension ของโมเดล ทั้งหมดบนฮาร์ดแวร์ของคุณเอง

[0.15.0 ทำให้ Octocode เป็น local-first โดยค่าเริ่มต้น](/blog/octocode-0-15-0-local-first-hybrid-search): ไม่ต้องใช้ API key, embedding รันบนเครื่องของคุณเองผ่าน `fastembed` clone repo, รัน `octocode index`, ได้ผลลัพธ์ ไม่มีอะไรออกจาก laptop ของคุณ

`fastembed` รันโมเดลจำนวนหยิบมือที่มันบันเดิลมา บน CPU ของคุณ แบบ in-process เยี่ยมสำหรับการเริ่มต้น — แต่ดีน้อยลงเมื่อคุณต้องการ embedding model ที่ใหญ่ขึ้นหรือใหม่ขึ้น, GPU, หรือ server เดียวที่ทั้งทีมใช้ร่วมกัน `local` provider ถูกเพิ่มมาเพื่อสิ่งนี้โดยเฉพาะ: ชี้ Octocode ไปที่ **OpenAI-compatible embedding server ใด ๆ** — Ollama, LM Studio, vLLM, llama.cpp, LocalAI, text-embeddings-inference — แล้ว index ด้วยโมเดลใดก็ตามที่มัน host อยู่

**0.17.1 คือ release ที่ทำให้สิ่งนั้นทำงานได้ end to end** ตอนนี้ provider detect embedding dimension ของโมเดลคุณโดยอัตโนมัติ ซึ่งเป็นชิ้นส่วนที่การ index ต้องใช้เพื่อสร้าง vector store เลือกโมเดล, เลือกฮาร์ดแวร์ แล้วโค้ดของคุณยังคงไม่เคยออกจาก network ของคุณ

โพสต์นี้ครอบคลุม local provider พร้อมกับการเปลี่ยนแปลงอื่น ๆ ตั้งแต่ 0.16.0 ([June round-up](/blog/release-round-june-2026) อัปเดตให้คุณถึงตรงนั้นแล้ว): read-only MCP mode และ structural search ที่แม่นยำระดับ AST จาก 0.16.1

---

## Bring Your Own Embedding Server

config สองบรรทัด:

```toml
[embedding]
code_model = "local:nomic-embed-text"
text_model = "local:nomic-embed-text"
```

prefix `local:` บอก Octocode ให้ส่ง embedding request ไปยัง server ที่พูดภาษา OpenAI `/v1/embeddings` API โดยค่าเริ่มต้นมันชี้ไปที่ `http://localhost:11434/v1/embeddings` — port ของ Ollama — ดังนั้นถ้า Ollama รันอยู่แล้ว ก็ไม่มีอะไรต้อง set up เพิ่ม:

```bash
ollama pull nomic-embed-text
octocode index
```

ชี้ไปที่อื่นก็แค่ environment variable เดียว:

```bash
# vLLM, LM Studio, llama.cpp server, LocalAI, text-embeddings-inference —
# anything that exposes POST /v1/embeddings
export LOCAL_EMBED_API_URL="http://gpu-box.internal:8000/v1/embeddings"

# Optional — sent as `Authorization: Bearer <key>` if your server wants one
export LOCAL_EMBED_API_KEY="..."
```

นั่นคือ setup ทั้งหมด ไม่มี SDK, ไม่มี glue เฉพาะ provider

### ไม่มี dimension ให้ตั้งค่า

embedding model ต่างกันสร้าง vector ที่มีความกว้างต่างกัน — 384, 768, 1024 — และ vector store ต้องรู้ความกว้างนั้นล่วงหน้าเพื่อสร้าง index ของมัน OpenAI-compatible server ไม่ได้ประกาศมันไว้ที่ไหน ดังนั้น Octocode หาให้คุณเอง: ครั้งแรกที่มันสร้าง provider สำหรับโมเดลของคุณ มันส่ง probe request เล็ก ๆ หนึ่งครั้ง, อ่านความกว้างของ vector ตรงจาก response, และ cache ไว้สำหรับการรันที่เหลือ จากนั้น index ถูกสร้างรอบ dimension นั้น

ผลลัพธ์ในทางปฏิบัติ: **โมเดลใดก็ตามที่ server ของคุณ serve ได้ก็ทำงานได้เลย** ไม่มีอะไรต้อง look up หรือ set แบบต่อโมเดล สลับ `nomic-embed-text` เป็น code model ที่ใหญ่ขึ้น แล้ว Octocode ปรับเข้ากับความกว้างใหม่ในการ index ครั้งถัดไป — ข้อกำหนดเดียวคือการ re-index เพราะ vector จากโมเดลต่างกันเปรียบเทียบกันไม่ได้

### `fastembed` vs. `local` — เลือกอันไหน?

ทั้งคู่เป็น local ความต่างคือใครเป็นคนรันโมเดล

|          | `fastembed:`                              | `local:`                                               |
| -------- | ----------------------------------------- | ------------------------------------------------------ |
| Runs     | In-process (ONNX, บน CPU ของคุณ)          | server แยกที่คุณจัดการเอง                              |
| Models   | ชุดที่ Octocode คัดมาบันเดิลให้           | อะไรก็ได้ที่ server ของคุณ host ได้                    |
| Hardware | CPU ของเครื่องนี้                         | ที่ไหนก็ตามที่ server อยู่ — GPU, เครื่องที่ใช้ร่วมกัน |
| Setup    | ศูนย์ — โมเดลดาวน์โหลดในการใช้งานครั้งแรก | คุณรัน Ollama/vLLM/etc. เอง                            |

หยิบ `fastembed` มาใช้เมื่อคุณต้องการ zero-setup และค่าเริ่มต้นที่แน่น หยิบ `local` มาใช้เมื่อคุณโตเกินมันไปแล้ว:

- **โมเดลที่ `fastembed` ไม่ได้บันเดิลมา** — code embedding model ที่ใหม่กว่า, ใหญ่กว่า, หรือ tune เฉพาะ domain ถ้า server ของคุณ serve มันได้ Octocode ก็ index ด้วยมันได้
- **ฮาร์ดแวร์จริง** การ embed monorepo ขนาดใหญ่บน CPU ของ laptop นั้นช้า ชี้ `LOCAL_EMBED_API_URL` ไปที่ GPU server แล้วการ embedding จะรันที่นั่นแทนที่จะเป็นบน laptop ของคุณ
- **server เดียวสำหรับทั้งทีม** รัน Ollama หรือ vLLM instance เดียว แล้ว Octocode ของ developer ทุกคนชี้ไปที่มัน vector สอดคล้องกัน มีที่เดียวให้ upgrade โมเดล

และคุณสมบัติที่ไม่เปลี่ยนระหว่างทั้งสอง: มันคือ **code search แบบ self-hosted และ private — โค้ดของคุณอยู่ภายใน network ของคุณ** การรับประกันเดียวกับที่ 0.15.0 ส่งมอบ ตอนนี้โดยไม่ถูกจำกัดไว้ที่โมเดลที่บันเดิลมาหรือ CPU ของ laptop ของคุณ

---

## Read-Only MCP Mode

โดยค่าเริ่มต้น เมื่อ AI agent เชื่อมต่อกับ MCP server ของ Octocode ตอนนี้ server **serve การค้นหาบน index ที่มีอยู่ของคุณและไม่แตะต้องมันเลย** ไม่มี background indexer, ไม่มี file watcher, ไม่มีการ re-index แบบเซอร์ไพรส์ที่เริ่มขึ้นทันทีที่ assistant ของคุณเชื่อมต่อ

นี่คือ toggle `mcp_index` และ `false` คือค่าเริ่มต้น:

```toml
[index]
# false (default): MCP serves search, view_signatures, and structural_search
#   over the EXISTING index, read-only. No background indexing or file watcher.
# true: MCP keeps the index fresh in-process with a background indexer + watcher.
mcp_index = false
```

ทำไมถึงตั้งค่าเริ่มต้นเป็น read-only? การ index และการ serve เป็นงานคนละอย่าง คุณ index ใน CI, บน `git` hook, หรือด้วยมือ — อย่างตั้งใจ เมื่อโค้ดเปลี่ยน งานของ MCP server คือตอบคำถามของ agent อย่างรวดเร็วและคาดเดาได้ ไม่ใช่การ spin up file watcher แล้ว re-embed repo ของคุณเพราะ editor ไปแตะไฟล์ Read-only หมายถึงการใช้ resource ตอน idle ที่ต่ำลง, ไม่มี contention, และไม่มีงานที่ไม่คาดคิดในจังหวะที่ tool เชื่อมต่อ

คำสั่ง CLI `index` ไม่ได้รับผลกระทบ — `octocode index` ยัง index เหมือนเดิม `mcp_index` แค่ gate indexer _in-process_ ที่ MCP server จะรันมิฉะนั้น

มีรายละเอียดเล็ก ๆ สำหรับ read-only mode ด้วย: ถ้า semantic search คืนค่ามาว่าง (เพราะ index ล้าสมัยหรือยังไม่ได้สร้าง) Octocode จะแนบข้อความ nudge บรรทัดเดียวที่ชี้นำ agent ไปทาง `structural_search` และ `view_signatures` แทนที่จะปล่อยให้มัน retry semantic search ลงในความว่างเปล่า

ต้องการพฤติกรรม always-fresh แบบเดิม — server ที่รันยาวซึ่งคอยอัปเดตตัวเองให้ทันสมัย? ตั้ง `mcp_index = true` แล้ว background indexer และ watcher จะกลับมา

---

## Structural Search ตอนนี้แม่นยำระดับ AST (0.16.1)

0.16.1 ไม่ได้มีโพสต์ของตัวเอง จึงควรค่าแก่การกล่าวถึง: MCP server ของ Octocode ได้ tool **structural search** ที่จริงจัง แยกจาก semantic search และ grep

semantic search เยี่ยมสำหรับ "payment retry อยู่ที่ไหน?" grep เยี่ยมสำหรับ string ตรงตัว structural search เป็นของคำถามที่อยู่ตรงกลาง — _หา code shape นี้ ไม่ว่าจะ format หรือ naming อย่างไร_ — และสำหรับ symbol:

- **Symbol definition และ reference** พร้อม wildcard support — "`handle_*` ถูก define ที่ไหน และใครเรียกมัน?"
- **Smart และ relaxed matching strategy** เหมือนกับการปรับปรุง structural grep ใน 0.15.0 มัน recover เมื่อ node kind ที่ขอมาผิดสำหรับภาษานั้นแทนที่จะคืนค่าว่าง
- **Metavariable constraint** — narrow match ด้วย regex และ relational filter ไม่ใช่แค่ raw pattern
- **Breadcrumb tracking** เพื่อให้แต่ละ match บอกคุณว่ามันถูก nest อยู่ใน class/function/module ไหน ข้ามภาษา (รวม Swift)
- **Pagination และ request caching** เพื่อให้ agent สามารถ page ผ่าน result set ขนาดใหญ่ได้โดยไม่ต้องรัน scan ใหม่ทั้งหมด

ภายในมันเดินผ่าน tree แบบ gitignore-aware และแบบ parallel ด้วย literal-token prefiltering และ lexical fallback เมื่อ AST path คืนค่าว่าง — เร็วบน repo ใหญ่ และไม่พลาด match อย่างเงียบ ๆ สำหรับ AI agent นั่นคือวิธีที่แม่นยำและนำทางได้ในการหา code structure ที่แน่นอนและ trace symbol

---

## ทั้งหมดที่เหลือ

**`view_signatures` รับไฟล์เดียวเป็น string** Agent (และมนุษย์) สามารถส่งไฟล์เดียวเป็น plain string ได้แทนที่จะ wrap ไว้ใน single-element array น้อย friction ลงสำหรับเคสที่พบบ่อยที่สุด

**Tool definition ไม่ถูก hardcode อีกต่อไป** รายการ tool ของ MCP server ถูก generate ขึ้นแทนที่จะ maintain ด้วยมือ ซึ่งทำให้ schema และ implementation ไม่ drift ออกจากกัน

**การทำความสะอาด dependency และ CI** Rust dependency ถูก bump, release pipeline ย้ายไปใช้ shared reusable workflow ไม่มีการเปลี่ยนพฤติกรรม — แค่ build ที่เรียบร้อยและเชื่อถือได้มากขึ้น

---

## Upgrade

```bash
# Homebrew
brew upgrade muvon/tap/octocode

# Universal installer
curl -fsSL https://raw.githubusercontent.com/Muvon/octocode/master/install.sh | sh

# Cargo
cargo install octocode --version 0.17.1
```

ถ้าคุณพอใจกับ `fastembed` ก็ไม่มีอะไรต้องทำ — config และ index ของคุณยังคงทำงานต่อไป หากต้องการสลับไปใช้ embedding server ของคุณเอง:

1. เริ่ม server ที่พูดภาษา OpenAI embeddings API (เช่น `ollama serve`) และโหลดโมเดล
2. ตั้ง `code_model` / `text_model` เป็น `local:<model>` ใน `config.toml` ชี้ `LOCAL_EMBED_API_URL` ไปที่ server ถ้ามันไม่ได้อยู่บน default port ของ Ollama
3. Re-index — vector เปลี่ยนตามโมเดล: `octocode clear && octocode index`

ต้องการให้ MCP server ของคุณ index ใน background ต่อไปเหมือนเวอร์ชันเก่าทำ? ตั้ง `mcp_index = true` มิฉะนั้น read-only default จะเข้ามาทำงาน — index จาก CLI หรือ CI แล้วปล่อยให้ server serve

---

Octocode เป็น open source (Apache 2.0) ที่ [github.com/Muvon/octocode](https://github.com/Muvon/octocode) มันคือ code-search engine ที่อยู่เบื้องหลัง [Octomind](https://octomind.run) — และตอนนี้คุณสามารถรันทุก embedding ที่มันสร้างขึ้นบนฮาร์ดแวร์ที่คุณควบคุม ด้วยโมเดลใดก็ตามที่คุณเลือก
