
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,而第二階段從未被嘗試。
這就是重試沒有用的原因。已刪除的集合在兩次嘗試之間不會有任何變化,所以重試只是再跑一次前提永遠為假的呼叫。這個狀態看起來像暫時的,因為 DELETING 和 DELETE_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": []}原本處於 DELETING 的 GXPMI2WL6Q 沒有任何介入就自己完成了。它的集合同樣已經不存在,所以它究竟有沒有可能遇到相同的失敗,這次工作階段並未證實。
拆除之後留下了兩個 IAM 服務角色,兩者都是 AmazonBedrockExecutionRoleForKnowledgeBase_<suffix> 的形式,結尾是主控台指定的隨機字串。刪除知識庫並不會移除主控台為它建立的執行角色。
依相依順序刪除:先知識庫,再 OpenSearch,最後 S3
這次事件是以下這條通則的一個案例:**先刪除依賴別人的資源,再刪除被它依賴的資源。**Bedrock 知識庫建立在兩個它並不擁有的東西之上,而且需要其中一個還活著,才能完成自己的刪除。
- 先刪知識庫,包含它的資料來源。這是唯一帶有活躍相依關係的步驟:第一階段會伸手進向量存放區,所以集合必須還在。
- **接著是 OpenSearch Serverless。**刪除集合,以及與它一起建立的安全、網路與資料存取政策。Bedrock 不會替你移除這些,文件也明白寫出這一點。集合同時也是花錢的部分,不論查詢量多少都按 OCU 小時計費。
- **最後才是 S3。**儲存貯體只有在匯入時才會被讀取,所以在拆除階段不會擋住任何事。把它放到最後,是因為它是你來源文件的副本;萬一後來覺得拆得太早,重新匯入是最便宜的復原手段。
主控台不會強制執行以上任何一點,當你要刪除某個知識庫仍指向的集合時,它也不會提出警告。原因就在前面引用的文件裡:Bedrock 把向量存放區視為你的東西,從不刪除它,因此也從不把它當作知識庫生命週期的一部分。這個設計本身合理,只是順序也就完全交給你自己掌握了。
總結
兩個知識庫卡在 DELETE_UNSUCCESSFUL,是因為它們的 OpenSearch Serverless 集合先被刪除,留下 dataDeletionPolicy: DELETE 的資料來源不斷嘗試從一個已不存在的存放區清除向量。在每個資料來源上設定 dataDeletionPolicy: RETAIN 跳過了那個步驟,兩個刪除也就都完成了。
有三點值得記住:
- **
DELETE_UNSUCCESSFUL是終點,不是暫時狀態。**與其重試,不如先讀GetKnowledgeBase的failureReasons,並在動 IAM 之前確認向量存放區是否還存在。 - **
UpdateDataSource會替換整個資源。**請重送既有的chunkingConfiguration,並在執行依賴它的刪除之前,確認你想改的欄位真的改到了。 - **依相依順序拆除。**先知識庫,再 OpenSearch Serverless,最後 S3。沒有任何機制會強制這件事,而把前兩步顛倒過來,就是前面描述的那個失敗。


