# 策展 · X (Twitter) 🔥

> 📖 本站完整內容索引（documentation index）：[llms.txt](/llms.txt)

> 作者：CocoIndex (@cocoindex_io) · 平台：X (Twitter) · 日期：2026-04-23

> 原始來源：https://x.com/cocoindex_io/status/2046967320950808648

## 中文摘要

# CocoIndex V1 - 專為長週期 Agent 設計的增量引擎

CocoIndex V1 現已正式發布。這是我們對增量資料管道（incremental data pipelines）撰寫方式的根本性重構——這一切源於過去一年我們觀察到開發者真正想用 CocoIndex 做什麼。CocoIndex V1 是專為 AI 工程師與 Agent 開發者打造的工具，適用於建構 Agent 所依賴的程式碼智慧、context、RAG、記憶與知識圖譜。點擊此處閱讀我們在超過 50 個版本更新中所投入的重大努力。

## 那麼，CocoIndex 究竟是什麼？

CocoIndex 是一個增量 context 引擎，能持續將程式碼庫、會議記錄、收件匣、Slack、PDF 與影片轉化為即時、持續更新的 context，讓你的 AI Agent 與 LLM 應用程式能有效進行推理，且僅需極少的增量處理。你可以在 10 分鐘內準備好生產級的 AI Agent，並獲得可靠、持續更新的資料——不再有過時的批次處理，也不再有 context 斷層。

## 你能用 CocoIndex 建構什麼？

殺手級範例：CocoIndex-code，它能透過任何處理邏輯，為你提供具備增量處理能力的最新程式碼庫索引。

## 為什麼我們如此執著於重寫它？

Jeff Dean 在 GTC 上說得很好：Agent 的執行速度比人類快約 50 倍，但它們所依賴的工具卻是為人類速度所設計的。

當人類在早上閱讀輸出時，隔夜的批次重建（Batch-rebuild-overnight）是可以接受的。但當 Agent 在撰寫程式碼、做出決策並每秒更新 50 次自己的 context 時，這就完全行不通了。過時的 context 就是一個 Bug。隔夜處理是錯誤的時間單位。

CocoIndex 是專為長週期（long-horizon）Agent 設計的增量引擎。來源變更 → 衍生資料隨之更新——無論是區塊（chunks）、嵌入（embeddings）、知識圖譜，還是你建構的任何內容。無需完整重建，無需手動比對差異，也不用擔心「我是否已經對這個區塊進行過嵌入」的瑣事。

## V1 的思維模型 - 想像一下 React，但用於資料處理

CocoIndex 一直是一個狀態驅動（state-driven）的框架。你不需要撰寫「計算此增量並應用它」的程式碼；你只需描述目標狀態應如何作為來源的函數呈現，引擎就會自動處理轉換過程。如果你使用過 React、試算表或 SQL 物化視圖（materialized views），你已經熟悉這種模式：

- React：將 UI 宣告為狀態的函數 → React 重新渲染變更的部分。
- 試算表：宣告公式 → 當輸入變更時，儲存格自動重新計算。
- CocoIndex：將目標狀態宣告為來源的函數 → 引擎同步變更的部分。

V1 的新之處在於你宣告的方式。整個管道現在就是純粹的非同步 Python。函數呼叫其他函數，迴圈就是迴圈，if 語句就是 if 語句。在幕後，CocoIndex 會追蹤你宣告的每一個目標狀態以及每一個經過記憶化（memoized）的中間值，因此下一次執行時只會處理變更的部分。

V1 特意設計為非侵入式。你可以從一個簡單的 `@coco.fn` 裝飾器開始，隨著管道擴展，再逐步啟用引擎的更多功能。沒有所謂「必須先設定框架」的步驟，也不需要在獲得價值前撰寫冗長的儀式性程式碼——當你真正需要時，再開啟增量開關即可。

## 什麼是增量引擎，為什麼為生產環境建構它很困難？

簡單來說，增量引擎只做一件事：
保持衍生資料與原始資料同步——同時不重複執行已經完成的工作。

這聽起來很直觀，但當你考慮到各種限制時，情況就不同了。

![](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/1776905817633-iaHGgLM8JbAAA7tB8jpg.jpg)

你的來源資料並非靜態的。它在不斷變化：
檔案被編輯、資料列被更新、事件亂序到達、API 回傳新的快照。

同時，你的處理邏輯也不是靜態的。
你會重構函數、調整解析方式、修復 Bug、變更 Schema。

一個真正正確的增量系統必須處理這兩者——資料變更與程式碼變更——而無需退回到完整重新計算。

這就是問題變得複雜的地方。

Notion 最近發表了他們的工程文章，探討了在維護內部資料管道時，針對簡單資料轉換（例如不含分群等）進行增量處理的冰山一角，以支援即時 Agent。

## V1 能達到的應用場景

V1 使其成為適合 Agent 時代工作負載的正確形態：同樣具備增量、狀態驅動的保證，但現在足夠靈活，能涵蓋 Agent 實際產生的管道形態——實體解析、分群、多階段縮減、租戶拓撲、超出嵌入範圍的條件式目標等等。範例庫中的每一個模式都是長週期 Agent 可能會自行執行的任務，並讓其輸出成為下一個 Agent 的新鮮來源資料——無需人類隨時監控作業。

![](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/1776905817874-iaHGgLc90agAE6VUsjpg.jpg)

![](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/1776905817621-ediaHGgLZGgbcAAV2jpg.jpg)

## 開始使用

宣告你的目標中應該包含什麼——CocoIndex 會讓它永遠保持同步，且只重新計算 Δ（增量）。

```bash
pip install -U --pre cocoindex     # v1 處於預覽階段 — 需要加上 --pre 旗標
```

```python
import cocoindex as coco
from cocoindex.connectors import localfs, postgres
from cocoindex.ops.text import RecursiveSplitter

@coco.fn(memo=True)                          # ← 透過 hash(input) + hash(code) 快取
async def index_file(file, table):
    for chunk in RecursiveSplitter().split(await file.read_text()):
        table.declare_row(text=chunk.text, embedding=embed(chunk.text))

@coco.fn
async def main(src):
    table = await postgres.mount_table_target(PG, table_name="docs")
    table.declare_vector_index(column="embedding")
    await coco.mount_each(index_file, localfs.walk_dir(src).items(), table)

coco.App(coco.AppConfig(name="docs"), main, src="./docs").update_blocking()
```

## 為什麼選擇 V1：V0 的瓶頸

V0 是有效的——開發者確實將真實的管道部署到了生產環境——但由於 DSL 優先的設計，四個限制一直存在：

- **兩個世界，一個程式**：FlowBuilder / DataScope / DataSlice 用於拓撲結構，普通 Python 用於葉節點。DSL 世界無法輕易轉換形態，無法將值傳遞給普通 Python 再傳回來。分群、實體解析、跨項目縮減、條件式來源——每一個都卡在這些接縫處。
- **獨立的型別系統**：像資料庫一樣，引擎擁有獨立於 Python 的型別系統，因此你想要使用的每個 Python 型別都需要編寫雙向轉換邏輯。dataclass 和 NDArray 有支援；但 PIL Image 或 pyarrow array 則沒有——如果沒有轉換邏輯，你就無法將其傳遞給函數，且跨越邊界傳遞的資料在進出時都需要進行序列化。
- **Postgres 作為硬性依賴**：引擎使用 Postgres 進行自身的帳務處理，因此 `pip install cocoindex && python script.py` 並不是一個可行的路徑——即使是微小的本地管道，你也必須先架設一個資料庫。
- **靜態拓撲**：`add_source()` 和 `.export()` 在執行前就已宣告，因此多租戶、配置驅動的拓撲以及執行時的目標選擇，都需要在 CocoIndex 周圍建立額外的腳手架，而不是在 CocoIndex 內部直接表達。

修復其中任何一個問題都意味著必須改變設計。

## CocoIndex V1：四個改變你建構能力的轉變

## 1. 流程即執行 — 無需 DSL

V0 需要 FlowBuilder 提供的凍結圖（frozen graph），引擎稍後再進行解釋。在 V1 中，`app_main` 作為根處理元件執行：每一個 `await coco.mount(...)` 都會增加一個子元件，每一個 `declare_*` 都會記錄目標狀態。元件樹是透過執行你的程式碼來建構的。

這解鎖了以下能力：

- **縮減模式**：使用 `coco.map` 進行扇出，然後進行聚合（參見 `multi_codebase_summarization`）。
- **多階段管道**：例如，每會話提取 → 跨會話實體解析 → 知識庫組裝，全部作為普通的函數呼叫。
- **條件式拓撲**：`if config.enable_kafka: await mount_kafka_target(...)`。

除錯就是一般的 Python 除錯：中斷點、逐步執行、列印。中間沒有不透明的圖形解釋器。

## 2. 原生 Python 型別，沒有平行的型別系統

V1 直接使用 Python 的型別系統。Dataclasses、Pydantic、NDArray、dict/list/tuple 依然有效——此外還支援 V0 無法表達的內容：PIL.Image、pyarrow.Table、torch.Tensor 以及任意函式庫類別。

## 3. 嵌入式 LMDB — 無需 Postgres 依賴

引擎的帳務處理從 Postgres 移至單一本地檔案中的 LMDB：無需伺服器、無需遷移、無需連接埠。

## 4. 動態來源與目標

來源/目標是在執行期間透過普通函數呼叫建立的；元件路徑樹會追蹤跨次執行的身份。這實現了：

- 從配置、環境變數或功能旗標進行條件式掛載。
- **每個項目對應目標**：每個租戶對應 Postgres Schema、每個類別對應 Kafka 主題、每個資料集對應 S3 前綴。
- 來自即時註冊表的拓撲——在啟動時查詢活躍租戶，並為每個租戶掛載一個元件；當租戶離開時，CocoIndex 會自動清理其狀態。

## 支持我們

如果你覺得這很有用，在 GitHub 上為 CocoIndex 加星（Star）是幫助我們最直接的方式。這也是其他開發者發現這個專案的方式 :)

## 標籤

Agent, RAG, 記憶系統, 新產品, CocoIndex
