靈碼企業版的管理員、組織內全域管理員(專屬版)可以為企業的開發人員配置智能問答、行間產生、知識庫上傳時的安全過濾策略。
該功能目前僅支援 Visual Studio Code 和 JetBrains IDE 外掛程式,不適用於 Lingma IDE。
適用版本 | 企業專屬版 |
功能入口
使用靈碼管理員、組織內全域管理員(僅適用於企業專屬版)帳號登入靈碼控制台,在左側導覽列選擇。
根據過濾器應用的情境,在頂部標籤頁選擇智能問答、行間產生或知識庫上傳(僅適用於企業專屬版)。
根據需求開啟相應過濾器的開關,然後配置相關參數。各情境支援的過濾器類型如下:
情境
過濾器類型
說明
智能問答
智能問答前置過濾器
使用靈碼的智能問答功能時,使用者輸入給大模型的內容將通過前置過濾器,大模型輸出的內容將通過後置過濾器。
智能問答後置過濾器
行間產生
行間產生前置過濾器
使用靈碼的行間產生功能時,使用者輸入給大模型的內容將通過前置過濾器,大模型輸出的內容將通過後置過濾器。
行間產生後置過濾器
知識庫上傳
知識庫上傳前置過濾器
上傳至靈碼知識庫的檔案須先通過該過濾器的審核後,方可上傳成功。
重要請確保將開發人員的靈碼升級到 V1.4.0 及以上,配置的過濾器方可生效。
智能問答過濾器、行間產生過濾器啟用或修改後,預計需要 5~10 分鐘才對開發人員使用的靈碼生效。
知識庫上傳過濾器啟用或修改後,立即生效,上傳企業知識庫檔案時會進行過濾。
智能問答、行間產生的前置過濾器配置
方式一:Regex配置
管理員在配置Regex時需要充分驗證,以避免開發人員使用IDE 外掛程式時效能下降或產生其他異常問題。
處理方式:支援通過Regex的方式配置過濾器,且支援 3 種模式。
匹配規則時不處理
匹配到正則後,不做任何處理。
匹配規則時攔截
匹配到正則後,直接攔截請求,阻斷模型請求。
匹配規則時替換內容
匹配到正則後,按照配置替換內容。
訊息通知:支援開啟訊息通知,通過 webhook 的方式,推送到所需要的訊息接收平台。
執行順序:按照配置的排序執行。
正則數量限制:最多可添加10條。
Regex標準:正則配置遵循 ECMAScript 標準,支援
i(不區分大小寫)、g(全域匹配)、s(DOTALL 模式)等常用標誌位。正則配置樣本:
規則名稱
Regex
替換內容
原文
替換後
社會安全號碼
(?<pre>.*)(\d{15})((\d{2})([0-9Xx]))(?<post>.*)
$<pre>***$<post>
社會安全號碼:330204197709022312。
社會安全號碼:***。
郵箱
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
***
我的郵箱是 lin***@aliyunmail.com
我的郵箱是 ***
密碼
(.*password=)([\w\d]+)(.*)
$1***$3
{password=1213213}
{password=***}
方式二:自訂指令碼配置(僅適用於企業專屬版)
企業專屬版中支援通過自訂指令碼的方式進行過濾器配置,以實現對複雜情境下的前置過濾的需求。步驟如下:
步驟一:指令碼開發
目前支援使用 TypeScript 語言進行指令碼開發,可以參考範例進行代碼開發,操作步驟如下:
下載模板程式碼程式庫:單擊倉庫地址:lingma-extension-template,該模板倉庫整合了開發指令碼所需的腳手架,請仔細閱讀
README.md檔案和程式碼範例。實現“前置處理”介面:實現介面
RequestPreHandler,API 可參考自訂指令碼 API,以下為一個樣本片段SensitiveContentFilter.ts的實現。/** * 敏感內容過濾器,通過該過濾器可以實現對發送給模型的資料進行敏感資訊預先處理 */ export const sensitiveContentFilter: RequestPreHandler = { handle: async (request: RawRequest, SDKTool: LingmaSDKTool) => { const dataMap = PayloadUtil.getPayloadData(request.payload); for (const [key, value] of dataMap.entries()) { if (value.includes('password')) { return ResultUtil.buildBlockResult('內容包含password'); } } // 如果需要針對不同的 action 做差異化處理,則參考如下實現 switch (request.action) { case ActionEnum.COMPLETION: // do something break; case ActionEnum.CODE_PROBLEM_SOLVE: // do something break; default: return ResultUtil.buildNoOpsResult(); } return ResultUtil.buildNoOpsResult(); }, };運行調試代碼,通過運行
main方法來測試指令碼是否符合預期,操作步驟如下:步驟一
編輯
src/index.ts檔案,修改main函數,調整實際需要調試代碼,如下樣本:async function main() { const value1 = ['password=123', 'abc']; const value2 = 'hello world'; const dataMap = new Map<PayloadDataKeyEnum, PayloadDataValueType>(); dataMap.set(PayloadDataKeyEnum.SELECTED_CODE, value1); dataMap.set(PayloadDataKeyEnum.USER_INPUT, value2); const mockRequest: RawRequest = { action: ActionEnum.CODE_GENERATE_COMMENT, payload: { associatedContexts: [], data: dataMap, }, requestId: '123', }; const response = await sensitiveContentFilter.handle(mockRequest, SDKTool); console.log(response); }步驟二
在 VS Code 中開啟想要調試的代碼檔案並設定斷點,然後從調試視圖中選擇“啟動程式”並單擊運行按鈕即可。

步驟二:編譯構建
將運行調試完成的 ts 檔案編譯為 js 檔案,如將SensitiveContentFilter.ts檔案編譯為SensitiveContentFilter.js檔案,編譯構建步驟如下:
開啟設定檔
src/build.js,修改entryPoints和outfile兩個配置參數,並在entryPoints參數中指定需要編譯構建的 ts 檔案路徑,在outfile中指定構建後的產物輸出路徑。在程式碼程式庫根目錄下執行命令
node build.js,執行成功後對應的 js 檔案將輸出到outfile指定的產物輸出路徑。
步驟三:本地測試
在指令碼上傳企業配置後台之前,可在本地完成調試,以確保指令碼能夠與靈碼的 IDE 外掛程式整合,並對補全或問答情境的行為進行正確的安全過濾處理。具體調試步驟如下:
將構建好的 js 檔案拷貝到靈碼本機存放區路徑的
/extension/local/script/目錄下。修改
config.json檔案:該檔案所在目錄為靈碼本機存放區路徑的/extension/local/,開啟config.json檔案,並找到contentHandlerScripts,在對應的內容裡增加該指令碼的配置資訊,如果沒有contentHandlerScripts,可以新增一個數群組類型的配置,參考樣本如下:{ "contentHandlerScripts": [ { "identifier": "SensitiveContentFilter", "name": "敏感內容過濾", "version": "1.0.0", "scriptPath": "~/.lingma/extension/local/script/SensitiveContentFilter.js", "state": "enabled", "bizType": "completion" } ] }配置參數說明:
參數
說明
identifier
指令碼 ID,需確保唯一性。
name
指令碼名稱。
version
指令碼的版本號碼,如果修改了指令碼內容,需要升級版本號碼,否則指令碼無法生效。
scriptPath
指令碼存放的路徑,請注意:
指令碼一定要存放在本機存放區路徑的
/extension/local/script/目錄下。指令碼的 js 檔案名稱(如:
SensitiveContentFilter.js)一定要與identifier的值保持一致。
state
指令碼狀態,
enabled表示啟用、disabled表示禁用。bizType
指令碼應用的業務情境,
completion表示行間代碼產生補全、chat表示智能問答。
步驟四:指令碼上傳
經過本地調試並通過驗證後,可進行指令碼上傳,操作步驟如下:
前往靈碼控制台-策略管理,選擇需要開通安全過濾器的情境。
選擇過濾器選項為:自訂指令碼。
將構建後的 js檔案上傳。
上傳後單擊儲存配置,約5分鐘內會下發到外掛程式端生效。
自訂指令碼 API
目前自訂指令碼支援三種處理方式,如下:
阻斷處理:即阻斷後續流程,一旦阻斷,則不會請求大模型進行推理,中斷本次請求。
過濾處理:對發送處理的資料進行了修改(如:混淆、刪除、替換等),然後繼續後續流程。
無處理:對發送的資料沒有做任何處理,原樣返回,然後繼續後續流程。
介面定義
/**
* 靈碼編程助手前置處理介面
*/
export interface RequestPreHandler {
// 處理請求
handle: (request: RawRequest, SDKTool: LingmaSDKTool) => Promise<HandlerResponse>;
}入參定義
/**
* 請求對象定義,請求包括觸發的行為和待發送給 LLM 的未經處理資料
*/
export interface RawRequest {
// 當前請求唯一標識,可用於追蹤請求執行
action: ActionEnum;
// 觸發請求的行為枚舉
payload: ContentPayload;
// 封裝未經處理資料內容的payload
requestId: string;
}
// ContentPayload.data 中 value 類型
export type PayloadDataValueType = string | number | string[];
/**
* 封裝發送給 LLM 的未經處理資料內容
*/
export class ContentPayload {
// 待處理的資料集合,對應的 key 參考 ContextValueKeyEnum 定義
data: Map<PayloadDataKeyEnum, PayloadDataValueType>;
// 與處理關聯的上下文
associatedContexts: ContextItem[];
constructor() {
this.data = new Map<PayloadDataKeyEnum, PayloadDataValueType>();
this.associatedContexts = [];
}
}
/**
* ContentPayload.data 中 key 枚舉
*/
export enum PayloadDataKeyEnum {
// 使用者圈選的程式碼片段
SELECTED_CODE ='lingma:code',
// 使用者輸入的文本
USER_INPUT = 'lingma:text',
// 報錯資訊
ERROR_MESSAGES = 'lingma:error_messages',
// 終端列印的日誌資訊
TERMINAL_CONTENT = 'lingma:terminal_content',
// 代碼補全時,當前游標所在行的前文程式碼片段
PREFIX_CODE = 'lingma:code_prefix',
// 代碼補全時,當前游標所在行的後文程式碼片段
SUFFIX_CODE = 'lingma:code_suffix',
// 相似程式碼片段
SIMILAR_CODE = 'lingma:similar_code',
}
/**
* 觸發請求的行為枚舉
*/
export enum ActionEnum {
// 單元測試
GENERATE_TESTCASE = 'GENERATE_TESTCASE',
// 產生注釋
CODE_GENERATE_COMMENT = 'CODE_GENERATE_COMMENT',
// 代碼解釋
EXPLAIN_CODE = 'EXPLAIN_CODE',
// 代碼最佳化
OPTIMIZE_CODE = 'OPTIMIZE_CODE',
// 自由問答(即在問答輸入框中直接輸入文本的行為)
FREE_INPUT = 'FREE_INPUT',
// 代碼問題快捷修複
CODE_PROBLEM_SOLVE = 'CODE_PROBLEM_SOLVE',
// shell命令產生
TERMINAL_COMMAND_GENERATION = 'TERMINAL_COMMAND_GENERATION',
// 終端報錯修複
TERMINAL_EXPLAIN_FIX = 'TERMINAL_EXPLAIN_FIX',
// 代碼補全
COMPLETION = 'COMPLETION',
}出參定義
/**
* 預先處理結果
*/
export class HandlerResponse {
// 處理策略,通過該策略可以控制後續的處理邏輯
handlePolicy: HandlePolicy;
// 原因描述
reason?: string;
// 當handlePolicy=FILTER時,需要設定該屬性,其值為經過過濾後的資料(必須與ContentRequest.payload的內容保持一致)
payload?: ContentPayload;
constructor() {
// 預設值
// eslint-disable-next-line @typescript-eslint/no-use-before-define
this.handlePolicy = HandlePolicy.NO_OPS;
this.reason = '';
this.payload = new ContentPayload();
}
}
/**
* 處理策略枚舉
*/
export enum HandlePolicy {
// 阻斷策略,直接阻斷請求
BLOCK = 'BLOCK',
// 過濾策略,攔截請求並對payload內容進行修改
FILTER = 'FILTER',
// 忽略策略,不處理請求
NO_OPS = 'NO_OPS',
}智能問答、行間產生的後置過濾器配置
方式一:Regex配置
管理員在配置Regex時需要充分驗證,以避免開發人員使用IDE 外掛程式時效能下降或產生其他異常問題。
處理方式:支援通過Regex的方式配置過濾器,僅支援一種模式,如下:
匹配規則時不處理
匹配到正則後,不做任何處理。
訊息通知:支援開啟訊息通知,通過 webhook 的方式,推送到所需要的訊息接收平台。
執行順序:按照配置的排序執行。
正則數量限制:最多可添加10條。
Regex標準:正則配置遵循 ECMAScript 標準,支援
i(不區分大小寫)、g(全域匹配)、s(DOTALL 模式)等常用標誌位。正則配置樣本:
規則名稱
Regex
原文
社會安全號碼
(?<pre>.*)(\d{15})((\d{2})([0-9Xx]))(?<post>.*)
社會安全號碼:330204197709022312。
郵箱
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
我的郵箱是 lin***@aliyunmail.com
密碼
(.*password=)([\w\d]+)(.*)
{password=1213213}
方式二:自訂指令碼配置(僅適用於企業專屬版)
企業專屬版中支援通過自訂指令碼的方式進行過濾器配置,以實現對複雜情境下的後置過濾的需求。步驟如下:
步驟一:指令碼開發
目前支援使用 TypeScript 語言進行指令碼開發,可以參考範例進行代碼開發,操作步驟如下:
下載模板程式碼程式庫:單擊倉庫地址:lingma-extension-template,該模板倉庫整合了開發指令碼所需的腳手架,請仔細閱讀
README.md檔案和程式碼範例。實現“後置處理”介面:實現介面
RequestPostHandler,API 可參考自訂指令碼 API,以下為一個樣本片段LLMChatAuditHandler.ts的實現,實現的功能為對靈碼的AIChat操作進行審計,將審計內容上報至阿里雲SLS。import {ResultUtil} from '../common/HandlerRespUtil'; import { JsonUtil } from '../common/JsonUtil'; import {PayloadUtil} from '../common/PayloadUtil'; import {Config} from '../sdk/ConfigManager'; import {LingmaSDKTool} from '../sdk/LingmaSDKTool'; import axios from "axios"; import moment from "moment"; import os from "os"; import { ActionEnum, AIResponse, HandlePolicy, RawRequest, RequestPostHandler, RequestPreHandler } from '../sdk/RequestHandleSDK'; /** * 自訂指令碼後置過濾器,通過該指令碼可以完成將請求內容發送到遠程伺服器進行處理(如代碼掃描、內容審計等) */ export const llmResultAuditHandler: RequestPostHandler = { handle: async (request: RawRequest, response: AIResponse,SDKTool: LingmaSDKTool) => { // 操作人名稱 let userName = SDKTool.user.name; // 操作人id let userId = SDKTool.user.uid; // ide let ide = SDKTool.idePlatform; // ide let ideVersion = SDKTool.ideVersion; // 操作時間 let operationTime = moment().format("YYYY-MM-DD HH:mm:ss"); // 操作ip let opeartionIp = getIpAddress(); // 操作業務情境(補全 or 問答情境) let bizType = "chat"; // 操作的請求id let requestId = request.requestId; // 操作action let action = request.action; // 操作內容(此處建議參考自身審計需求選取合適欄位,避免上報內容過大(超過16k)導致上報失敗) let inferredResult = response.inferredResult.text; // 上報sls // sls的Project名稱 let slsProject = "xxx"; // sls的LogStore名稱 let slsLogStore = "xxx"; // sls執行個體所在地區的endPoint let endPoint = "cn-hangzhou.log.aliyuncs.com"; let slsWebTrackingUrl = `http://${slsProject}.${endPoint}/logstores/${slsLogStore}/track?APIVersion=0.6.0&request_id=${requestId}&action=${action}&biz_type=${bizType}&user_name=${userName}&user_id=${userId}&ide=${ide}&ide_version=${ideVersion}&operation_time=${operationTime}&opeartion_ip=${opeartionIp}&inferredResult=${inferredResult}`; axios.get(slsWebTrackingUrl).catch((error) => { console.error(error); }); // 返回過濾結果 return ResultUtil.buildPostHandlerResponse(HandlePolicy.NO_OPS, response.inferredResult,'無需處理'); }, }; /** * 將自訂指令碼過濾器添加到配置中 * @param config LingmaExtensionSDK提供的統一管理配置的對象 */ export function modifyConfig(config: Config) { config.postContentHandlers.push(llmResultAuditHandler); return config; } function getIpAddress() { const interfaces = os.networkInterfaces(); for (let devName in interfaces) { let iface = interfaces[devName]; for (let i = 0; i < iface.length; i++) { let alias = iface[i]; if ( alias.family === "IPv4" && alias.address !== "127.0.0.1" && !alias.internal ) return alias.address; } } return "No IP address found"; }運行調試代碼,通過運行
main方法來測試指令碼是否符合預期,操作步驟如下:步驟一
編輯
src/index.ts檔案,修改main函數,調整實際需要被調試的代碼,如下樣本:async function main() { const value2 = 'hello world'; const dataMap = new Map<PayloadDataKeyEnum, PayloadDataValueType>(); dataMap.set(PayloadDataKeyEnum.USER_INPUT, value2); const request: RawRequest = { action: ActionEnum.CODE_GENERATE_COMMENT, payload: { associatedContexts: [], data: dataMap, }, requestId: 'test-request-id', }; const aiResponse: AIResponse = { inferredResult: { text: 'reply hello world', }, }; const response = await llmResultAuditHandler.handle(request, aiResponse, SDKTool); console.log(response); }步驟二
在 VS Code 中開啟想要調試的代碼檔案並設定斷點,然後從調試視圖中選擇“啟動程式”並單擊運行按鈕即可。

步驟二:編譯構建
將運行調試完成的 ts 檔案編譯為 js 檔案,如將LLMChatAuditHandler.ts檔案編譯為LLMChatAuditHandler.js檔案,編譯構建步驟如下:
開啟設定檔
src/build.js,修改entryPoints和outfile兩個配置參數,並在entryPoints參數中指定需要編譯構建的 ts 檔案路徑,在outfile中指定構建後的產物輸出路徑。在程式碼程式庫根目錄下執行命令
node build.js,執行成功後對應的 js 檔案將輸出到outfile指定的產物輸出路徑。
步驟三:本地測試
在指令碼上傳企業配置後台之前,可在本地完成調試,以確保指令碼能夠與靈碼的 IDE 外掛程式整合,並對補全或問答情境的行為進行正確的安全過濾處理。具體調試步驟如下:
將構建好的 js 檔案拷貝到靈碼本機存放區路徑的
/extension/local/script/目錄下。修改
config.json檔案:該檔案所在目錄為靈碼本機存放區路徑的/extension/local/,開啟config.json檔案,並找到contentHandlerScripts,在對應的內容裡增加該指令碼的配置資訊,如果沒有contentHandlerScripts,可以新增一個數群組類型的配置,參考樣本如下:{ "contentHandlerScripts": [ { "identifier": "LLMChatAuditHandler", "name": "AIChat審計", "version": "1.0.0", "scriptPath": "~/.lingma/extension/local/script/LLMChatAuditHandler.js", "state": "enabled", "stage":"post", "bizType": "completion" } ] }配置參數說明:
參數
說明
identifier
指令碼 ID,需確保唯一性。
name
指令碼名稱。
version
指令碼的版本號碼,如果修改了指令碼內容,需要升級版本號碼,否則指令碼無法生效。
scriptPath
指令碼存放的路徑,請注意:
指令碼一定要存放在本機存放區路徑的
/extension/local/script/目錄下。指令碼的 js 檔案名稱(如:
LLMChatAuditHandler.js)一定要與identifier的值保持一致。
state
指令碼狀態,
enabled表示啟用、disabled表示禁用。stage
指令碼作用階段,
post表示後置過濾、pre表示前置過濾,預設值為pre前置過濾。bizType
指令碼應用的業務情境,
completion表示行間代碼產生補全、chat表示智能問答。
步驟四:指令碼上傳
經過本地調試並通過驗證後,可進行指令碼上傳,操作步驟如下:
前往靈碼控制台-策略管理,選擇需要開通安全過濾器的情境。
選擇過濾器選項為:自訂指令碼。
將構建後的 js檔案上傳。
上傳後單擊儲存配置,約5分鐘內會下發到外掛程式端生效。
自訂指令碼 API
目前自訂指令碼僅支援一種處理方式,如下:
無處理:對發送的資料沒有做任何處理,原樣返回,然後繼續後續流程。
介面定義
/**
* 靈碼編程助手後置處理介面
* @param request 使用者發送的請求
* @param response LLM返回的推理內容
* @param SDKTool SDK工具類,通過該工具類可以擷取與IDE、Plugin相關的資訊
* @returns 經過後置處理器處理後的返回結果
*/
export interface RequestPostHandler {
// 後置處理方法
handle: (request: RawRequest, response: AIResponse, SDKTool: LingmaSDKTool) => Promise<PostHandlerResponse>;
}入參定義
/**
* 請求對象定義,請求包括觸發的行為和待發送給 LLM 的未經處理資料
*/
export interface RawRequest {
// 當前請求唯一標識,可用於追蹤請求執行
action: ActionEnum;
// 觸發請求的行為枚舉
payload: ContentPayload;
// 封裝未經處理資料內容的payload
requestId: string;
}
/**
* 模型推理產生的結果資料
*/
export class InferredResult {
//LLM產生的常值內容
text: string;
constructor() {
this.text = '';
}
}
// ContentPayload.data 中 value 類型
export type PayloadDataValueType = string | number | string[];
/**
* 封裝發送給 LLM 的未經處理資料內容
*/
export class ContentPayload {
// 待處理的資料集合,對應的 key 參考 ContextValueKeyEnum 定義
data: Map<PayloadDataKeyEnum, PayloadDataValueType>;
// 與處理關聯的上下文
associatedContexts: ContextItem[];
constructor() {
this.data = new Map<PayloadDataKeyEnum, PayloadDataValueType>();
this.associatedContexts = [];
}
}
/**
* ContentPayload.data 中 key 枚舉
*/
export enum PayloadDataKeyEnum {
// 使用者圈選的程式碼片段
SELECTED_CODE ='lingma:code',
// 使用者輸入的文本
USER_INPUT = 'lingma:text',
// 報錯資訊
ERROR_MESSAGES = 'lingma:error_messages',
// 終端列印的日誌資訊
TERMINAL_CONTENT = 'lingma:terminal_content',
// 代碼補全時,當前游標所在行的前文程式碼片段
PREFIX_CODE = 'lingma:code_prefix',
// 代碼補全時,當前游標所在行的後文程式碼片段
SUFFIX_CODE = 'lingma:code_suffix',
// 相似程式碼片段
SIMILAR_CODE = 'lingma:similar_code',
// 補全情境執行補全的檔案路徑
FILE_PATH = 'lingma:file_path',
}
/**
* 觸發請求的行為枚舉
*/
export enum ActionEnum {
// 單元測試
GENERATE_TESTCASE = 'GENERATE_TESTCASE',
// 產生注釋
CODE_GENERATE_COMMENT = 'CODE_GENERATE_COMMENT',
// 代碼解釋
EXPLAIN_CODE = 'EXPLAIN_CODE',
// 代碼最佳化
OPTIMIZE_CODE = 'OPTIMIZE_CODE',
// 自由問答(即在問答輸入框中直接輸入文本的行為)
FREE_INPUT = 'FREE_INPUT',
// 代碼問題快捷修複
CODE_PROBLEM_SOLVE = 'CODE_PROBLEM_SOLVE',
// shell命令產生
TERMINAL_COMMAND_GENERATION = 'TERMINAL_COMMAND_GENERATION',
// 終端報錯修複
TERMINAL_EXPLAIN_FIX = 'TERMINAL_EXPLAIN_FIX',
// 代碼補全
COMPLETION = 'COMPLETION',
}出參定義
/**
* 後置處理結果
*/
export class PostHandlerResponse {
// 處理策略,通過該策略可以控制後續的處理邏輯
handlePolicy: HandlePolicy;
// 原因描述
reason?: string;
// 經過後置處理器處理過的模型返回結果
processedResult: InferredResult;
constructor() {
// 預設值
this.handlePolicy = HandlePolicy.NO_OPS;
this.reason = '';
this.processedResult = new InferredResult();
}
}
/**
* 封裝大模型返回結果
*/
export class AIResponse {
// 模型推理結果
inferredResult: InferredResult;
constructor() {
this.inferredResult = new InferredResult();
}
}
/**
* 模型推理產生的結果資料
*/
export class InferredResult {
//LLM產生的常值內容
text: string;
constructor() {
this.text = '';
}
}
/**
* 處理策略枚舉(後置過濾器當前只支援NO_OPS)
*/
export enum HandlePolicy {
// 阻斷策略,直接阻斷請求
BLOCK = 'BLOCK',
// 過濾策略,攔截請求並對payload內容進行修改
FILTER = 'FILTER',
// 忽略策略,不處理請求
NO_OPS = 'NO_OPS',
}知識庫上傳過濾器配置(僅適用於企業專屬版)
企業專屬版中,支援靈碼管理員、全域管理員通過在策略配置中配置知識庫過濾器,配置完成後,在知識庫檔案上傳前對其進行審查,從而滿足在特定情境下對知識庫內容前置過濾的需求。
過濾器配置說明
步驟一:開啟並編輯知識庫過濾器
在左側導覽列,單擊策略配置,在右側頁面,單擊知識庫過濾器頁簽。
在知識庫過濾器配置頁面,您可以開啟開關開啟/關閉知識庫上傳前置過濾器,進行參數配置編輯。
URL 地址
必填
企業提供的第三方掃描服務的介面地址。要求此介面必須使用 POST 請求。
Token 欄位名
必填
指定要求標頭中用於存放 Token 的欄位名。
Secret 密鑰
必填
產生訪問 Token 所需的密鑰。Token 會被放入指定的要求標頭欄位中,用於驗證請求的合法性。詳情請參考“安全 Token”章節。
步驟二:測試過濾器連通性
填寫正確後,進行連通性測試,單擊測試連接按鈕。當第三方過濾介面返回
2xx狀態代碼時,測試成功。如果返回其它狀態代碼,測試則會失敗,您需要檢查填寫資訊後再重現測試連接。
步驟三:儲存知識庫過濾器
單擊儲存配置按鈕,儲存您的過濾器配置。儲存成功後,過濾器將立即生效。
第三方掃描服務介面規範
企業需提供第三方掃描服務,以便知識庫過濾器可以使用該服務對上傳的知識內容進行掃描,通過掃描後方可上傳。為了確保您配置的過濾器正常運行,掃描服務的介面應符合以下設計要求:
要求標頭
參數名 | 是否必填 | 參數說明 | 參數樣本 |
X-Auth-Raw | 是 | 介面鑒權參數,參數名為您在過濾器配置頁面中配置的 Token 欄位名。參數值應為Secret 密鑰通過密碼編譯演算法產生的最終密鑰,具體產生邏輯詳見“安全 Token”章節。 | 6c3baa76c62550eab864e6f75c4bb |
Content-Type | 是 | 表示請求和響應中的媒體類型資訊。 | multipart/form-data |
安全Token:是阿里雲設計的一種安全簽名,旨在防止惡意攻擊者盜用您的雲端服務許可權。產生 Token 需要以下要素:Secret 密鑰、目前時間、其他資訊和密碼編譯演算法。
Token產生:靈碼調用第三方掃描服務介面時,將在要求標頭內攜帶安全Token 用於身份鑒權驗證。 根據如下參數計算產生 Token 值:
token = sha256Hex(method + url + timestamp + tokenSecret) + timestampHexmethod
為POST 方法。
url
為配置知識庫過濾器填寫的掃描服務介面 URL 地址。
timestamp
為目前時間。
tokenSecret
為配置知識庫過濾器時填寫的 Secret 密鑰。
timestampHex
將時間戳記轉換成十六進位。
Token驗證:您的第三方掃描服務在驗證請求的Token鑒權時,可以參考以下代碼進行合法性校正。
重要時間戳記:確保用戶端和服務端的時間同步,避免因時間偏差導致Token驗證失敗。
密鑰管理:妥善保管
tokenSecret,不要泄露給未經授權的使用者。到期時間:根據業務需求調整 Token 的有效時間,樣本中設定為60秒,可根據實際情況調整。
/* * 方法參數說明: * receivedHash:接收到的雜湊值,包含了時間戳記資訊。 * tokenSecret:用於產生雜湊的密鑰。 * url:請求的URL。 */ public boolean validateAuthRaw(String receivedHash, String tokenSecret, String url) { final String method = "POST"; // 從 receivedHash 中提取時間戳記部分 String tsHex = receivedHash.substring(receivedHash.length() - 8); long tsSec = Long.parseLong(tsHex, 16); // 計算目前時間與接收時間的差異,假設允許的最大時間差為60秒 long now = System.currentTimeMillis() / 1000L; if (Math.abs(now - tsSec) > 60) { return false; // 超過允許的時間範圍 } // 構建待簽名的字串 String plain = method + url + tsSec + tokenSecret; // 產生預期的雜湊值 String expectedHash = org.apache.commons.codec.digest.DigestUtils.sha256Hex(plain); // 比較接收到的雜湊值與預期的雜湊值 return expectedHash.equals(receivedHash.substring(0, receivedHash.length() - 8)); }
請求參數
參數名 | 參數類型 | 是否必填 | 參數解釋 | 參數樣本 |
metadata | string | 是 | 業務中繼資料,Content-Type: application/json | {"user": "user0000001", "queryId": "cd2fd109-c4d4-489f-9b27-53752f7827d6"} |
file | file | 是 | 送檢的檔案 |
請求樣本。
Content-Type: multipart/form-data; boundary=${bound}
--${bound}
Content-Disposition: form-data; name="metadata"
Content-Type: application/json
{
"user":"user0000001",
"queryID":"cd2fd109-c4d4-489f-9b27-53752f7827d6"
}
--${bound}
Content-Disposition: form-data; name="file"; filename="test-file.pdf"
Content-Type: application/pdf
%binary-file-content-here%響應結構
介面應返回 HTTP 狀態代碼 200,並包含以下格式的響應體。
參數名 | 參數類型 | 是否必填 | 參數解釋 | 參數樣本 |
forbidden | boolean | 是 | 安全檢測結果。true表示檢測失敗。 | false |
errorMsg | string | 否 | 錯誤資訊,說明檢測失敗的原因。 | "檔案包含惡意內容,請修改後再上傳" |
queryId | string | 否 | 請求 ID,需與請求 metadata 中的 queryId 欄位對應。 | "cd2fd109-c4d4-489f-9b27-53752f7827d6" |
user | string | 否 | 使用者識別碼,需與請求 metadata 中的 user 欄位對應。 | "user0001" |