阿里雲 Milvus 知識庫可以把教材、教案、題目與標準答案建成可檢索的題庫助手:學生用自然語言提問即可拿到講解與原文依據,也可以上傳題目圖片,從題庫中找出相似題並結合教材講解。
方案說明
整體鏈路與通過阿里雲Milvus知識庫搭建智能客服問答應用完全一致:控制台定義標籤 → 按標籤大量匯入資料 → 發布版本 → SDK 檢索(可按標籤過濾、可附帶圖片)→ 大模型產生帶來源標註的回答 → Flask 提供問答頁面。工程代碼(kb_client.py、upload.py、app.py、templates/index.html、start.sh)請直接複用該文,本文只說明教育情境需要改動的部分:學科與知識點標籤、圖片資料的處理方式、圖片查詢的能力邊界、以及公式展示。
建議第一版只選擇一個年級、一個學科的 5~20 篇資料,驗證後再擴大範圍。整體耗時約 25~40 分鐘,其中文檔解析耗時取決於資料數量與大小。
前提條件
已建立 Milvus 知識庫並記錄知識庫 ID(形如
kd-803ae9b10cc31)。建立一個全模態知識庫。當前控制台建立知識庫時固定使用全模態(ALL_MODAL)類型,頁面上沒有其他選項,因此無需額外判斷;該屬性建立後不可修改,可在知識庫詳情頁的基本資料中查看資料類型。需要注意的是,結構化類型的知識庫只接受 xlsx、xls、csv、jsonl、faq 五種格式,上傳圖片會直接返回參數錯誤,因此題庫這類含圖資料必須使用全模態知識庫。
已使用主帳號建立 RAM 使用者、勾選使用永久 AccessKey 訪問,並授予系統策略
AliyunMilvusFullAccess。已準備支援 OpenAI
chat/completions協議的大模型地址與 API Key。本地已安裝 Python 3.8 或以上版本,並已按上文教程建好工程目錄。
步驟一:定義年級與知識點標籤
在知識庫詳情頁的基本資料下方單擊標籤 > 管理,添加以下四個標籤(類型均為 string):
標籤名 | 說明 | 樣本值 |
grade | 年級 | 八年級 |
subject | 學科 | 數學、物理 |
knowledgePoint | 知識點 | 二次函數、勾股定理 |
questionType | 資料類型 | 教材、練習題、標準答案 |
標籤值支援中文,可直接使用年級、學科與知識點的中文名稱。
標籤管理對話方塊是整體儲存的。對話方塊開啟後標籤列表為非同步載入,請等到已有標籤全部顯示出來,再添加新標籤並單擊完成;否則可能以"空列表 + 新標籤"整體覆蓋,導致已有標籤定義被清除。
步驟二:準備資料與匯入清單
把資料放進
documents/目錄,支援 PDF、DOCX、Markdown、TXT 與圖片。建議教材、題目、標準答案成套上傳:講解時模型會同時引用教材中的方法、題目原文與答案中的評分要點,回答完整度明顯更高。建立
documents.jsonl,為每篇資料標註年級、學科、知識點與資料類型。{"path": "documents/math-grade8-textbook.pdf", "metadata": {"grade": "八年級", "subject": "數學", "knowledgePoint": "二次函數", "questionType": "教材"}} {"path": "documents/math-quadratic-problem.png", "metadata": {"grade": "八年級", "subject": "數學", "knowledgePoint": "二次函數", "questionType": "練習題"}} {"path": "documents/math-quadratic-answers.docx", "metadata": {"grade": "八年級", "subject": "數學", "knowledgePoint": "二次函數", "questionType": "標準答案"}} {"path": "documents/math-pythagorean-exercise.docx", "metadata": {"grade": "八年級", "subject": "數學", "knowledgePoint": "勾股定理", "questionType": "練習題"}}關於圖片資料,需要瞭解其入庫方式:圖片會先經過文字識別(OCR)轉成文本,再按文本切片建立索引。因此:
圖中文字能否被識別,決定這張圖能否被檢索到。純圖形(沒有文字的幾何圖、函數圖象)幾乎無法被命中,不適合作為獨立資料上傳,建議與含文字的題幹放在同一張圖或同一篇文檔中。
題目圖片應保持清晰、字型大小足夠、盡量使用印刷體。識別結果可能出現偏差(例如把頓號識別成其他符號、把變數
x識別成乘號×),數學符號尤其容易受影響。上傳後建議到資料管理頁單擊查看切片,確認識別出的文本與圖中內容一致,再發布版本。
題目與解析多為短條目,可在知識庫詳情頁的處理策略中單擊建立策略調整切片粒度。最大分段長度的單位是字元(預設 512),建議設定為 580~770 字元(約相當於 384~512 tokens),盡量讓"題幹 + 解析"保持在同一個切片內。
步驟三:配置檢索參數與提示詞
在 config.json 中按教育情境調整 retrieval 與 scenario。
{
"retrieval": {
"page_size": 8,
"candidate_count": 64,
"min_score": 0.2,
"semantic_weight": 0.75,
"enable_query_expansion": true,
"rerank_model_name": "qwen3-rerank",
"tag_filter": {
"relation": "and",
"conditions": [
{"field": "subject", "op": "=", "value": "數學"}
]
}
},
"scenario": {
"title": "教育題庫檢索與講解",
"system_prompt": "你是教學助理。只依據檢索到的教材、題目和標準答案講解;先給思路,再給步驟,最後給答案,並標註[來源N];公式請使用純文字書寫,不要使用 LaTeX 文法;若檢索到的題目與使用者描述不一致,必須明確指出差異,不要直接套用題庫中的答案;資料不足時不要猜測標準答案。",
"image_enabled": true,
"sample_questions": [
"二次函數頂點式如何求最大值?",
"找一道使用勾股定理的例題並講解",
"這道題考查了哪些知識點?"
]
}
}參數說明:
semantic_weight=0.75並啟用qwen3-rerank:學生提問多為自然語言題意描述,語義權重更高有利於相似題匹配。需注意重排分數與向量分數不是同一量綱:最終分數的演算法是
score ≈ (1-semantic_weight) × keywordScore + semantic_weight × semanticScore(另可能疊加 rank feature),未啟用重排時semanticScore是向量相似性,啟用重排後它變成重排模型分數,而min_score始終在這個最終分數上過濾。因此實測同一問題在啟用重排後返回條數由 5 條降為 4 條,是閾值與新量綱共同作用的結果,並不說明重排讓召回變差。沒有跨語料通用的推薦組合:建議先把
min_score設為 0 取回一批結果並人工標註相關性,再按召回與誤召回的分布選閾值;每次切換重排模型、開關重排或調整semantic_weight後都要重新校準。tag_filter固定subject:可有效防止跨學科誤召回。實測在subject=數學過濾下提問物理知識點,返回 0 條,模型會按提示詞回答"資料不足"。op實際只有=、in、not in三個運算子生效。寫成eq、==、equal、like等別名會返回400 Unsupported tag filter operator,導致每次提問都失敗;而≠、>、<、≥、≤、empty、not empty、start with、end with雖然出現在該報錯列出的 "Supported operators" 清單中,實測條件會被靜默忽略、返回未經過濾的全部資料。其中
contains、not contains只是in/not in的別名,並不是字串包含,按字串片段傳值只會返回 0 條。需要按區間篩選時請用
in枚舉取值,需要判斷標籤為空白時請用= "";配置後務必與不加過濾的結果對比總條數,確認過濾生效。system_prompt中建議明確"公式使用純文字":教學類提示詞容易讓模型輸出 LaTeX,而樣本頁面用<pre>純文字展示,公式不會渲染,會顯示為原始的貨幣符號與反斜線。若希望保留 LaTeX,請在頁面中引入 KaTeX 或 MathJax。
步驟四:圖片查詢的用法與能力邊界
app.py 的 /api/ask 接受可選的 image_url 參數,並透傳給 SearchKnowledgeBase 的 image 欄位:
curl -sS http://127.0.0.1:7860/api/ask \
-H 'Content-Type: application/json' \
-d '{"question":"這道題考查了哪些知識點?","image_url":"https://<可公網訪問的圖片地址>"}'圖片對指代不明的提問協助最大。實測同一個問題「這道題考查了哪些知識點?」:不帶圖片時命中的是勾股定理練習(相關度 0.431,並不是想問的題);帶上二次函數題目圖片後,命中的是題庫中的二次函數題目(0.583),可見圖片為檢索提供了關鍵語義。
圖片只參與檢索,不會被送給大模型。 系統的行為是"根據圖片在題庫中找出最相似的題目,然後依據檢索到的資料講解",不是"識別並解答圖片中的題目"。若上傳的是一道題庫中不存在的新題,系統會拿最相似的庫內題目作答,答案可能與圖中題目不同且不易察覺。例如上傳 y=-(x-1)²+4(最大值為 4)時,若題庫中存在 y=-2(x-3)²+5,回答可能給出最大值 5。 因此建議:在頁面上提示"圖片用於尋找題庫中的相似題";在提示詞中要求模型指出檢索結果與使用者描述的差異;因此這項能力應當被稱為「圖片輔助檢索」或「以圖搜題」,不能對外表述為「拍照解題」。若確實需要解答圖中的新題,必須由應用程式層把原圖另外傳給支援多模態輸入的大模型,並要求它同時核對檢索到的資料,而不是只依賴知識庫檢索。
圖片的識別能力有以下邊界,準備題庫素材前需要瞭解:
格式:建議只使用 JPG、JPEG、PNG、GIF。底層檔案識別可能還接受 WebP、TIFF 等格式,但沒有統一的對外約定,不建議依賴。
大小:介面沒有單獨的圖片位元組數或像素硬上限,但實際會受上傳網關、映像解碼、記憶體以及圖文轉換模型服務的共同限制,超大圖仍可能失敗。
識別準確率:手寫體、數學公式、幾何圖形、座標系都沒有承諾的準確率指標。純圖形可能由圖文轉換產生一段描述,但不保證能被檢索命中。本文實測中,
x被識別成×、頓號被識別成「丶」,數學符號尤其需要人工抽查。沒有識別品質閾值:只要圖片能被解碼且流程未報錯,文檔狀態就是處理完成,即使識別出的文本很少或有錯誤;只有解碼失敗或所需模型調用報錯才會顯示處理失敗。因此上傳後必須到資料管理頁抽查切片文本,不能只看狀態。
關於圖片地址,image_url 必須是可公網訪問的地址,服務端會校正:
傳入內容 | 服務端返回 |
內網或本機地址(如 |
|
非圖片資源的連結 |
|
無法解析的網域名稱 |
|
留空 | 退化為普通文字檢索(正常行為) |
最後是回顯原題圖的問題。檢索結果裡有一個 images 欄位,用於返回切片關聯的圖片(服務端會為已持久化的圖片產生短期有效簽名地址)。該欄位本身是已實現的能力,並非預留的空欄位;如果命中了圖片文檔但它仍然返回空,說明這批資料在解析切片階段沒有把圖片 ID 持久化到對應切片,或者簽名關聯沒有建立,屬於需要按具體文檔排查的鏈路問題,沒有任何請求參數可以開啟它。因此不要把「一直為空白」當作產品設計,也不需要為此長期自我維護一份「檔案名稱 → 公網圖片地址」的映射表;在它為空白期間,頁面可以先降級展示識別出的題目文本。
步驟五:上傳、發布與驗證
上傳資料(
MetaFields對整批生效,指令碼會先按標籤分組再分批提交)。python upload.py --manifest documents.jsonl到控制台資料管理頁確認資料狀態為處理完成,並對圖片資料單擊查看切片核對識別文本。
在版本管理頁單擊發布版本,完成三步嚮導後確認新版本狀態為發行。
重要同時最多隻能存在 3 個發行版本。達到上限後發布版本按鈕會置灰,而頁面仍會顯示"當前有 N 條待發布變更",需要先在版本記錄中刪除不再需要的舊版本。版本刪除不可恢複。題庫通常每學期或每單元都會補充資料,建議只保留"目前的版本 + 最近一個歷史版本"。
啟動服務並驗證。
python app.py按以下四條驗收:
頁面能正常開啟(教育情境會額外顯示題目圖片 URL 輸入框),提交問題後同時返回答案與檢索來源。
回答中的
[來源N]能在下方來源區找到對應的資料切片。提問題庫未覆蓋的內容時,回答明確說明資料不足,而不是補寫答案。
補充資料並重新發布版本後,頁面能檢索到新內容。
建議再補一條針對語義召回的驗證:用只出現在資料內容裡、不出現在檔案名稱中的資訊提問(例如題目編號),確認能命中對應資料。這條同樣適用於檢查圖片是否被正確識別入庫。
教育情境注意事項
教材、題目、答案成套上傳,並用
questionType區分,便於按需過濾(例如只給學生檢索"練習題",給教師檢索"標準答案")。按學科建立獨立入口:
tag_filter固定subject後,該入口只能回答該學科的問題,樣本問題也應保持同一學科,否則學生提問其他學科只會得到"資料不足"。答案類資料建議單獨控制訪問:若不希望學生直接拿到標準答案,可在學生入口用
questionType not in ["標準答案"]之類的條件過濾。檢索結果的
images欄位當前取不到圖片地址,頁面展示的是識別後的文本。該欄位本身是已實現的能力,取不到值屬於解析鏈路未把圖片關聯到切片,不需要為此長期自我維護「檔案名稱 → 圖片地址」的映射表:短期內頁面可先降級展示識別文本,需要回顯原題圖時再按documentId關聯匯入清單臨時處理。關鍵結論建議保留人工核對,並提示學生以正式教材與教師講解為準。
常見問題
現象 | 原因與處理 |
提問返回 500,日誌顯示 |
|
加了標籤過濾但結果條數與不加過濾時完全一樣 | 使用了不生效的運算子(如 |
圖片資料上傳後搜不到 | 依次確認:知識庫資料類型是否支援圖片;資料狀態是否為處理完成;查看切片中識別出的文本是否為空白或與圖中不符(純圖形、字型大小過小、手寫體都可能導致識別失敗)。 |
上傳圖片提問,回答的卻是另一道題 | 預期行為。圖片只用於檢索相似題,模型講解的是檢索到的題目,詳見步驟四。 |
提問返回 |
|
頁面上公式顯示成 | 模型輸出了 LaTeX 而頁面按純文字展示。在提示詞中要求使用純文字公式,或在頁面引入公式渲染庫。 |
啟用重排後結果反而變少 | 重排分數與向量分數量綱不同,與 |
按標籤過濾後總是 0 條 | 標籤名拼字與寫入時不一致(介面不會報錯,只返回 0 條)。在知識庫詳情頁 → 標籤 → 管理中核對。 |
上傳返回 | 整批檔案都因同名被去重。修改檔案名稱或先在控制台刪除舊資料。 |
檢索返回 | 尚未發布版本,或指定的版本號碼不存在。 |