白色卡片上的 Amazon Bedrock 圖示,藍綠色圓角方塊中有一個白色線條繪製的大腦,由六邊形輪廓與末端帶小圓點的電路線構成,旁邊是深藍色的 Amazon Bedrock 字樣

Bedrock 知識庫刪不掉 — 先刪 OpenSearch 集合就會卡在 DELETE_UNSUCCESSFUL

因為先刪除了 OpenSearch Serverless 集合,兩個 Amazon Bedrock 知識庫卡在 DELETE_UNSUCCESSFUL。本文說明成因,以及把 dataDeletionPolicy 改成 RETAIN 的解法。

本頁目錄

引言

我在個人 AWS 帳戶裡清理舊的 Amazon Bedrock 資源時,有兩個知識庫怎麼樣都刪不掉。兩者都停在 DELETE_UNSUCCESSFUL,主控台只顯示這個狀態卻不說原因,再按一次刪除也只是第三次得到同樣的結果。麻煩的地方在於,成因早已發生:這兩個知識庫背後的 OpenSearch Serverless 集合已經先被刪掉了,而每個資料來源都設定成在刪除時要從那些集合清除自己的向量。無論執行幾次,刪除都不可能完成。

本文整理了如何從 CLI 診斷出這個狀態、為什麼少了向量存放區會讓刪除永久卡住、dataDeletionPolicy: RETAIN 這個解法、造成第二次失敗的 UpdateDataSource 文件已載明的陷阱,以及可以避開這一切的拆除順序。

主控台沒有說明的部分

執行 ListKnowledgeBases 就能立刻看出問題的樣貌。ap-northeast-1 有三個知識庫,其中兩個卡住了:

終端機視窗
aws bedrock-agent list-knowledge-bases --region ap-northeast-1 --output table
knowledgeBaseId name status
ZZ01BJIIZ3 knowledge-base-quick-start-handson-classic DELETE_UNSUCCESSFUL
PUVPB8DGEL internal-assistant-knowledge-base-test DELETE_UNSUCCESSFUL
GXPMI2WL6Q knowledge-base-rag-handson DELETING

原因藏在更深一層,在列表檢視不會帶出的 failureReasons 陣列裡。GetKnowledgeBase 會回傳它:

終端機視窗
aws bedrock-agent get-knowledge-base \
--region ap-northeast-1 --knowledge-base-id ZZ01BJIIZ3
"failureReasons": [
"Unable to delete data from vector store for data source with ID JLLYIBTATA. Check your vector store configurations and permissions and retry your request. If the issue persists, consider updating the dataDeletionPolicy of the data source to RETAIN and retry your request.",
"Unable to delete data from vector store for data source with ID JLLYIBTATA. Check your vector store configurations and permissions and retry your request. If the issue persists, consider updating the dataDeletionPolicy of the data source to RETAIN and retry your request."
]

同一句話出現兩次,每次失敗的嘗試各一筆。另一個知識庫也針對自己的資料來源 ID 0NRPHQMCCN 回傳了完全相同的訊息。這段錯誤在最後一個子句裡點名了自己的解法,但如果把「檢查你的權限」當成真正的建議來讀,就很容易略過它。

向量存放區真的連得上嗎

兩個知識庫都指向 OpenSearch Serverless 集合。這兩個集合都不存在:

終端機視窗
aws opensearchserverless batch-get-collection --region ap-northeast-1 \
--ids rkulz4az4wngr17bmm67 6uu4dp3q3f2qqjkd2iqk
{
"collectionDetails": [],
"collectionErrorDetails": [
{ "id": "rkulz4az4wngr17bmm67", "errorMessage": "The specified Collection is not found.", "errorCode": "NOT_FOUND" },
{ "id": "6uu4dp3q3f2qqjkd2iqk", "errorMessage": "The specified Collection is not found.", "errorCode": "NOT_FOUND" }
]
}

ListCollections 的結果一致,回傳 "collectionSummaries": []這個帳戶裡已經沒有任何 OpenSearch Serverless 集合,但仍有兩個知識庫持有指向它們的 ARN。

這就排除了把錯誤讀成權限問題的可能。一個沒有集合存取權的角色,和一個根本不存在的集合,會產生聽起來很像的失敗,但其中只有一種能靠修改 IAM 解決。

為什麼少了集合就會讓刪除卡住

刪除知識庫分成兩個階段,而只有第二個階段算是帳面作業。

第一階段是資料平面的操作。當資料來源帶著 dataDeletionPolicy: DELETE 時,Bedrock 會連往向量存放區,刪除該資料來源匯入的向量。第二階段才是按下刪除的人所想像的控制平面操作:移除知識庫與資料來源的紀錄本身。

第一階段需要一個活著的集合。集合不在了就沒有可連接的對象,呼叫失敗,資源落在 DELETE_UNSUCCESSFUL,而第二階段從未被嘗試。

停在階段 1 的知識庫刪除DeleteKnowledgeBase 請求分成兩個階段。階段 1 的清除向量向右指向一個以虛線繪製、標記為 NOT_FOUND 的 OpenSearch Serverless 集合,該箭頭標示為失敗。虛線繼續往下連到階段 2 的刪除中繼資料,但它以灰色呈現並標示為未執行。最終狀態為 DELETE_UNSUCCESSFUL。DeleteKnowledgeBase1階段 1・清除向量資料平面。連往向量存放區,刪除先前匯入的向量。失敗OpenSearch Serverless集合NOT_FOUND未執行2階段 2・刪除中繼資料控制平面。移除知識庫與資料來源的紀錄。最終狀態DELETE_UNSUCCESSFUL
刪除停在第一階段。集合不在了就沒有可清除的對象,第二階段原本要移除的中繼資料因此留了下來。

這就是重試沒有用的原因。已刪除的集合在兩次嘗試之間不會有任何變化,所以重試只是再跑一次前提永遠為假的呼叫。這個狀態看起來像暫時的,因為 DELETINGDELETE_UNSUCCESSFUL 並列在同一個 status 欄位裡,但前者是過程,後者是終點。

兩個資料來源都印證了這個政策:

終端機視窗
aws bedrock-agent get-data-source --region ap-northeast-1 \
--knowledge-base-id ZZ01BJIIZ3 --data-source-id JLLYIBTATA
{ "dataDeletionPolicy": "DELETE", "status": "DELETE_UNSUCCESSFUL" }

DELETE 是主控台快速入門流程產生的預設值,所以透過精靈點一點建立出來的知識庫,會在沒有人選過的情況下帶著這個設定。

解法:把 dataDeletionPolicy 設成 RETAIN

RETAIN 會告訴 Bedrock 把已匯入的資料留在原處,於是跳過第一階段,讓第二階段得以執行。直接從錯誤訊息提出這個做法的是智能體,核准執行拆除的是我。每個知識庫的順序是:更新、刪除資料來源、刪除知識庫。

終端機視窗
aws bedrock-agent update-data-source \
--region ap-northeast-1 \
--knowledge-base-id PUVPB8DGEL --data-source-id 0NRPHQMCCN \
--name knowledge-base-quick-start-6vf5c-data-source \
--data-source-configuration '{"type":"S3","s3Configuration":{"bucketArn":"arn:aws:s3:::internal-assistant-docs"}}' \
--vector-ingestion-configuration '{"chunkingConfiguration":{"chunkingStrategy":"HIERARCHICAL","hierarchicalChunkingConfiguration":{"levelConfigurations":[{"maxTokens":1500},{"maxTokens":512}],"overlapTokens":60}}}' \
--data-deletion-policy RETAIN
aws bedrock-agent delete-data-source --region ap-northeast-1 \
--knowledge-base-id PUVPB8DGEL --data-source-id 0NRPHQMCCN
aws bedrock-agent delete-knowledge-base --region ap-northeast-1 \
--knowledge-base-id PUVPB8DGEL

這裡值得把 RETAIN 究竟放棄了什麼講清楚,因為它聽起來像是會遺失資料,但並不會。根據 AWS 文件,DELETE 是「在你刪除資料來源時刪除所有資料,但不會刪除向量存放區本身」,而且還明確寫著**「如果你刪除資料來源或知識庫,向量存放區本身不會被刪除」**。RETAIN 唯一留下的,是存放區裡面的向量。當那個存放區早已被銷毀,也就沒有什麼會被遺留。

陷阱:UpdateDataSource 是 PUT,不是 PATCH

第一次嘗試失敗了,而且是在智能體先處理的那個知識庫上失敗的。原因是省略了 --vector-ingestion-configuration 參數,背後是一個看起來很合理的假設:沒有指定的欄位就是不變的欄位。

aws: [ERROR]: An error occurred (ValidationException) when calling the UpdateDataSource operation: vectorIngestionConfiguration.chunkingConfiguration cannot be updated once created.

這個 API 是 PUT /knowledgebases/{knowledgeBaseId}/datasources/{dataSourceId},所以省略的欄位是你想清空的欄位,而不是你想維持原狀的欄位。參考文件在請求語法上方的提示框中就這麼說:「資料來源連接器建立後就不能變更 chunkingConfiguration。請指定既有的 chunkingConfiguration。」讀出資源,改掉那一個欄位,再把完整內容送回去。

這個失敗安靜得很花時間。更新指令以非零狀態結束,但後面兩個刪除指令照樣執行,而且都回報 DELETING,讀起來像成功。大約四分鐘後,知識庫帶著新的時間戳記回到了 DELETE_UNSUCCESSFUL,因為政策仍然是 DELETE,所以它經歷了和先前一模一樣的第一階段失敗。把既有的階層式分塊設定一起帶上重新送出更新後,回傳了 "dataDeletionPolicy": "RETAIN",刪除這才完成。

**前提條件失敗並不會阻止後續的指令執行。**請在送出刪除之前確認政策確實已經是 RETAIN,而不是去看刪除指令自己的結束碼。

驗證

兩個知識庫都消失了,連同從第一次列表以來就一直在刪除中的第三個:

終端機視窗
aws bedrock-agent list-knowledge-bases --region ap-northeast-1 --output json
{
"knowledgeBaseSummaries": []
}

原本處於 DELETINGGXPMI2WL6Q 沒有任何介入就自己完成了。它的集合同樣已經不存在,所以它究竟有沒有可能遇到相同的失敗,這次工作階段並未證實。

拆除之後留下了兩個 IAM 服務角色,兩者都是 AmazonBedrockExecutionRoleForKnowledgeBase_<suffix> 的形式,結尾是主控台指定的隨機字串。刪除知識庫並不會移除主控台為它建立的執行角色。

依相依順序刪除:先知識庫,再 OpenSearch,最後 S3

這次事件是以下這條通則的一個案例:**先刪除依賴別人的資源,再刪除被它依賴的資源。**Bedrock 知識庫建立在兩個它並不擁有的東西之上,而且需要其中一個還活著,才能完成自己的刪除。

知識庫的刪除順序兩個並排的欄位。左邊是錯誤的順序:先刪除 OpenSearch Serverless 集合,接著的知識庫刪除因為階段 1 沒有可清除的對象而停在 DELETE_UNSUCCESSFUL。右邊是正確的順序:先是知識庫與其資料來源,再來是 OpenSearch Serverless 集合與存取政策,最後是 S3 儲存貯體,每個步驟都順利完成。錯誤的順序1OpenSearch Serverless先刪除集合2知識庫DELETE_UNSUCCESSFUL階段 1 沒有可清除的對象,刪除永遠無法完成。重試只會得到相同的失敗。正確的順序1知識庫連同資料來源一起刪除2OpenSearch Serverless集合與相關存取政策3S3 儲存貯體來源文件每個步驟都能完成。Bedrock 不會替你刪除向量存放區或儲存貯體。
這裡唯一需要別的資源還活著才能乾淨刪除的,就是知識庫。先移除集合正是讓它被卡住的原因。
  1. 先刪知識庫,包含它的資料來源。這是唯一帶有活躍相依關係的步驟:第一階段會伸手進向量存放區,所以集合必須還在。
  2. **接著是 OpenSearch Serverless。**刪除集合,以及與它一起建立的安全、網路與資料存取政策。Bedrock 不會替你移除這些,文件也明白寫出這一點。集合同時也是花錢的部分,不論查詢量多少都按 OCU 小時計費。
  3. **最後才是 S3。**儲存貯體只有在匯入時才會被讀取,所以在拆除階段不會擋住任何事。把它放到最後,是因為它是你來源文件的副本;萬一後來覺得拆得太早,重新匯入是最便宜的復原手段。

主控台不會強制執行以上任何一點,當你要刪除某個知識庫仍指向的集合時,它也不會提出警告。原因就在前面引用的文件裡:Bedrock 把向量存放區視為你的東西,從不刪除它,因此也從不把它當作知識庫生命週期的一部分。這個設計本身合理,只是順序也就完全交給你自己掌握了。

總結

兩個知識庫卡在 DELETE_UNSUCCESSFUL,是因為它們的 OpenSearch Serverless 集合先被刪除,留下 dataDeletionPolicy: DELETE 的資料來源不斷嘗試從一個已不存在的存放區清除向量。在每個資料來源上設定 dataDeletionPolicy: RETAIN 跳過了那個步驟,兩個刪除也就都完成了。

有三點值得記住:

  • **DELETE_UNSUCCESSFUL 是終點,不是暫時狀態。**與其重試,不如先讀 GetKnowledgeBasefailureReasons,並在動 IAM 之前確認向量存放區是否還存在。
  • **UpdateDataSource 會替換整個資源。**請重送既有的 chunkingConfiguration,並在執行依賴它的刪除之前,確認你想改的欄位真的改到了。
  • **依相依順序拆除。**先知識庫,再 OpenSearch Serverless,最後 S3。沒有任何機制會強制這件事,而把前兩步顛倒過來,就是前面描述的那個失敗。

參考連結

分享這篇文章