diff --git a/bbit_ai/app/config/cubeReport.py b/bbit_ai/app/config/cubeReport.py
index a8c3046..d8b73c2 100644
--- a/bbit_ai/app/config/cubeReport.py
+++ b/bbit_ai/app/config/cubeReport.py
@@ -20,7 +20,7 @@ def get_cube_report_settings() -> CubeReportSettings:
"DIFY_DATABASE_ASSISTANT_API_BASE", "https://chat.bbitcn.net/v1"
).rstrip("/"),
dify_api_key=os.getenv(
- "DIFY_DATABASE_ASSISTANT_API_KEY", "app-uibWo8ZEpqHCsWXREPTCBDH6"
+ "DIFY_DATABASE_ASSISTANT_API_KEY", "app-Ojd3zT2wBsO2Bop575ZiHQOD"
),
cube_api_base=os.getenv(
"CUBE_API_BASE_URL", "http://10.10.12.101:4001/cubejs-api/v1"
diff --git a/vue2/apps/web-antd/src/api/llm/report-cube.ts b/vue2/apps/web-antd/src/api/llm/report-cube.ts
index db08764..9751ee7 100644
--- a/vue2/apps/web-antd/src/api/llm/report-cube.ts
+++ b/vue2/apps/web-antd/src/api/llm/report-cube.ts
@@ -138,6 +138,32 @@ function getFetchConfig() {
};
}
+async function authorizedFetch(path: string, init: RequestInit) {
+ const request = () => {
+ const { authorization, baseURL } = getFetchConfig();
+ const headers = new Headers(init.headers);
+ if (authorization) {
+ headers.set('Authorization', authorization);
+ } else {
+ headers.delete('Authorization');
+ }
+ return fetch(`${baseURL}${path}`, { ...init, headers });
+ };
+
+ let response = await request();
+ if (response.status !== 401) return response;
+
+ try {
+ // 标准请求客户端会使用项目现有的 refresh token 机制更新令牌。
+ await getCubeReportScope();
+ } catch {
+ return response;
+ }
+ await response.body?.cancel();
+ response = await request();
+ return response;
+}
+
async function responseError(response: Response) {
const text = await response.text();
try {
@@ -272,12 +298,10 @@ export async function stopCubeReportTask(taskId: string) {
}
export async function uploadCubeReportFile(file: File) {
- const { authorization, baseURL } = getFetchConfig();
const form = new FormData();
form.append('file', file);
- const response = await fetch(`${baseURL}/llm/cube-report/files/upload`, {
+ const response = await authorizedFetch('/llm/cube-report/files/upload', {
method: 'POST',
- headers: { Authorization: authorization },
body: form,
});
if (!response.ok) throw new Error(await responseError(response));
@@ -291,14 +315,13 @@ export async function downloadCubeReportFile(
conversationId: string,
file: CubeReportFile,
) {
- const { authorization, baseURL } = getFetchConfig();
const params = new URLSearchParams({
conversationId,
asAttachment: 'true',
});
- const response = await fetch(
- `${baseURL}/llm/cube-report/files/${file.id}/preview?${params}`,
- { headers: { Authorization: authorization } },
+ const response = await authorizedFetch(
+ `/llm/cube-report/files/${file.id}/preview?${params}`,
+ {},
);
if (!response.ok) throw new Error(await responseError(response));
const blob = await response.blob();
@@ -314,12 +337,10 @@ export async function streamCubeReportMessage(
payload: SendCubeReportMessage,
onEvent: (event: CubeReportStreamEvent) => void,
) {
- const { authorization, baseURL } = getFetchConfig();
- const response = await fetch(`${baseURL}/llm/cube-report/messages/stream`, {
+ const response = await authorizedFetch('/llm/cube-report/messages/stream', {
method: 'POST',
headers: {
Accept: 'text/event-stream',
- Authorization: authorization,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
diff --git a/vue2/apps/web-antd/src/views/llm/report/report-cube-chat/index.vue b/vue2/apps/web-antd/src/views/llm/report/report-cube-chat/index.vue
index 68a3576..2dda306 100644
--- a/vue2/apps/web-antd/src/views/llm/report/report-cube-chat/index.vue
+++ b/vue2/apps/web-antd/src/views/llm/report/report-cube-chat/index.vue
@@ -381,49 +381,64 @@ async function sendMessage() {
let completedConversationId = currentSessionId.value;
let completedWithData = false;
try {
- await api.streamCubeReportMessage(
- {
- content,
- conversationId: currentSessionId.value,
- files: sentFiles,
- tenantId: currentSession.value?.tenantId || selectedCompany.value?.id,
- tenantName:
- currentSession.value?.tenantName || selectedCompany.value?.name,
- },
- (event: CubeReportStreamEvent) => {
- switch (event.type) {
- case 'complete': {
- completedConversationId =
- event.conversationId || completedConversationId;
- completedWithData = event.hasData;
- assistantMessage.status = 'completed';
- if (event.hasData) activeView.value = 'split';
- break;
+ try {
+ await api.streamCubeReportMessage(
+ {
+ content,
+ conversationId: currentSessionId.value,
+ files: sentFiles,
+ tenantId: currentSession.value?.tenantId || selectedCompany.value?.id,
+ tenantName:
+ currentSession.value?.tenantName || selectedCompany.value?.name,
+ },
+ (event: CubeReportStreamEvent) => {
+ switch (event.type) {
+ case 'complete': {
+ completedConversationId =
+ event.conversationId || completedConversationId;
+ completedWithData = event.hasData;
+ assistantMessage.status = 'completed';
+ if (event.hasData) activeView.value = 'split';
+ break;
+ }
+ case 'message_delta': {
+ assistantMessage.content += event.content;
+ void scrollToBottom();
+ break;
+ }
+ case 'message_replace': {
+ assistantMessage.content = event.content;
+ break;
+ }
+ case 'status': {
+ streamStatus.value = event.text;
+ break;
+ }
+ case 'task': {
+ currentTaskId.value = event.taskId;
+ break;
+ }
+ case 'error': {
+ throw new Error(event.message);
+ }
+ // No default
}
- case 'message_delta': {
- assistantMessage.content += event.content;
- void scrollToBottom();
- break;
- }
- case 'message_replace': {
- assistantMessage.content = event.content;
- break;
- }
- case 'status': {
- streamStatus.value = event.text;
- break;
- }
- case 'task': {
- currentTaskId.value = event.taskId;
- break;
- }
- case 'error': {
- throw new Error(event.message);
- }
- // No default
- }
- },
- );
+ },
+ );
+ } catch (error) {
+ const text =
+ error instanceof Error ? error.message : '请求失败,请稍后重试';
+ assistantMessage.status = stopRequested.value ? 'completed' : 'failed';
+ assistantMessage.content = stopRequested.value
+ ? assistantMessage.content || '响应已停止。'
+ : `请求失败:${text}`;
+ if (!stopRequested.value) {
+ inputMessage.value = content;
+ pendingFiles.value = sentFiles;
+ message.error(text);
+ }
+ return;
+ }
if (!assistantMessage.content) {
assistantMessage.content = stopRequested.value
@@ -431,30 +446,24 @@ async function sendMessage() {
: '查询已完成。';
}
if (completedConversationId) {
- currentSessionId.value = completedConversationId;
- const detail = await api.getCubeReportSession(completedConversationId);
- currentSession.value = detail.session;
- messages.value = detail.messages;
- if (currentReportId.value) {
- currentReport.value = await api.getCubeReport(currentReportId.value);
+ try {
+ currentSessionId.value = completedConversationId;
+ const detail = await api.getCubeReportSession(completedConversationId);
+ currentSession.value = detail.session;
+ messages.value = detail.messages;
+ if (currentReportId.value) {
+ currentReport.value = await api.getCubeReport(currentReportId.value);
+ }
+ await reloadNavigation();
+ if (completedWithData || detail.session.hasData) {
+ activeView.value = 'split';
+ await loadData(1);
+ }
+ } catch (error) {
+ const text =
+ error instanceof Error ? error.message : '会话和数据刷新失败';
+ message.warning(`回复已完成,但数据刷新失败:${text}`);
}
- await reloadNavigation();
- if (completedWithData || detail.session.hasData) {
- activeView.value = 'split';
- await loadData(1);
- }
- }
- } catch (error) {
- const text =
- error instanceof Error ? error.message : '请求失败,请稍后重试';
- assistantMessage.status = stopRequested.value ? 'completed' : 'failed';
- assistantMessage.content = stopRequested.value
- ? assistantMessage.content || '响应已停止。'
- : `请求失败:${text}`;
- if (!stopRequested.value) {
- inputMessage.value = content;
- pendingFiles.value = sentFiles;
- message.error(text);
}
} finally {
sending.value = false;
@@ -465,6 +474,12 @@ async function sendMessage() {
}
}
+function sendSuggestedQuestion(question: string) {
+ if (sending.value) return;
+ inputMessage.value = question;
+ void sendMessage();
+}
+
async function stopResponse() {
if (!currentTaskId.value || stopping.value) return;
stopping.value = true;
@@ -874,11 +889,11 @@ onBeforeUnmount(() => {
v-for="session in sessions"
:key="session.id"
type="button"
- class="session-item"
- :class="{
- 'session-item-active':
- !currentReportId && currentSessionId === session.id,
- }"
+ class="session-item"
+ :class="{
+ 'session-item-active':
+ !currentReportId && currentSessionId === session.id,
+ }"
@click="loadConversation(session.id)"
>
@@ -1183,17 +1198,14 @@ onBeforeUnmount(() => {
v-for="(question, index) in suggestedQuestions"
:key="question"
type="button"
- @click="inputMessage = question"
+ :disabled="sending"
+ @click="sendSuggestedQuestion(question)"
>
{{ question }}
-
diff --git a/数据库助手v3.12.yml b/数据库助手v3.12.yml
new file mode 100644
index 0000000..b2a37da
--- /dev/null
+++ b/数据库助手v3.12.yml
@@ -0,0 +1,2716 @@
+app:
+ description: F8数据库业务助手-接入AI实验室(去除历史问答记录)
+ icon: face_with_hand_over_mouth
+ icon_background: '#ECE9FE'
+ icon_type: emoji
+ mode: advanced-chat
+ name: 数据库助手v3.12
+ use_icon_as_answer_icon: true
+dependencies:
+- current_identifier: null
+ type: marketplace
+ value:
+ marketplace_plugin_unique_identifier: langgenius/tongyi:0.2.4@72bdf0d70a10b1b9f64746ccd1bd792397598f4536872b310e77532af02ad6a6
+ version: null
+kind: app
+version: 0.6.0
+workflow:
+ conversation_variables:
+ - description: 最后一次生成
+ id: ab2439a1-9b4d-4ede-87b6-a4613f095a78
+ name: latest_load
+ selector:
+ - conversation
+ - latest_load
+ value: ''
+ value_type: string
+ - description: 当前蚕季ID
+ id: d541aee5-cedd-44f4-8434-5b3845e97a1e
+ name: canjiId
+ selector:
+ - conversation
+ - canjiId
+ value: 未指定
+ value_type: string
+ - description: 当前蚕季名
+ id: f8c87483-4d91-4828-a4f4-ab4dec0634a7
+ name: canjiName
+ selector:
+ - conversation
+ - canjiName
+ value: 未指定
+ value_type: string
+ - description: Cube表join关系
+ id: 4d28225d-2249-4390-b9c3-ea4e64184188
+ name: cube_joins
+ selector:
+ - conversation
+ - cube_joins
+ value: "{\n \"bus_co_breeding_assessment\": [\n \"poc_tenants\",\n \"cz_gyh\"\
+ ,\n \"nonghu_info\",\n \"batch_canji\"\n ],\n \"bus_farmer_operation\"\
+ : [\n \"poc_tenants\",\n \"cbms_rbac_base_departments\"\n ],\n \"bus_farmer_yield\"\
+ : [\n \"poc_tenants\",\n \"nonghu_info\",\n \"batch_canji\"\n ],\n\
+ \ \"bus_order_delivery\": [\n \"poc_tenants\",\n \"nonghu_info\",\n \
+ \ \"batch_canji\",\n \"cbms_rbac_base_departments\"\n ],\n \"bus_payment_transfer\"\
+ : [\n \"poc_tenants\",\n \"nonghu_info\",\n \"batch_canji\",\n \"\
+ cbms_rbac_base_departments\"\n ],\n \"bus_purchase_bill\": [\n \"poc_tenants\"\
+ ,\n \"nonghu_info\",\n \"batch_canji\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"bus_purchase_grade_mode\": [\n \"poc_tenants\",\n \"sg_chengzhong\"\
+ ,\n \"nonghu_info\",\n \"batch_canji\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"bus_quality_inspection\": [\n \"poc_tenants\",\n \"yp_bill_kpi_item_fix\"\
+ ,\n \"sg_chengzhong\",\n \"nonghu_info\",\n \"batch_canji\"\n ],\n\
+ \ \"bus_subsidy_policy\": [\n \"poc_tenants\",\n \"nonghu_info\",\n \
+ \ \"batch_canji\"\n ],\n \"bank_pay_base\": [\n \"poc_tenants\",\n \
+ \ \"nonghu_info\",\n \"batch_canji\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"batch_canji\": [\n \"poc_tenants\"\n ],\n \"cbms_rbac_assoc_department_users\"\
+ : [\n \"poc_tenants\",\n \"cbms_rbac_base_users\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"cbms_rbac_assoc_user_roles\": [\n \"poc_tenants\",\n \"cbms_rbac_base_users\"\
+ ,\n \"cbms_rbac_base_roles\"\n ],\n \"cbms_rbac_base_departments\": [\n\
+ \ \"poc_tenants\"\n ],\n \"cbms_rbac_base_roles\": [\n \"poc_tenants\"\
+ \n ],\n \"cbms_rbac_base_users\": [\n \"poc_tenants\"\n ],\n \"csb_exchange\"\
+ : [\n \"poc_tenants\",\n \"nonghu_info\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"cz_config_item\": [\n \"poc_tenants\",\n \"batch_canji\"\n\
+ \ ],\n \"cz_dzbill_list\": [\n \"poc_tenants\",\n \"nonghu_info\",\n\
+ \ \"batch_canji\",\n \"cz_gyh\",\n \"cbms_rbac_base_departments\"\n\
+ \ ],\n \"cz_gyh\": [\n \"poc_tenants\",\n \"nonghu_info\",\n \"batch_canji\"\
+ ,\n \"cbms_rbac_base_departments\"\n ],\n \"dep_xianxiangcun_config\":\
+ \ [\n \"poc_tenants\",\n \"cbms_rbac_base_departments\"\n ],\n \"gj_crm_clientinfo\"\
+ : [\n \"poc_tenants\"\n ],\n \"gj_cy_item\": [\n \"poc_tenants\",\n\
+ \ \"gj_cy_main\"\n ],\n \"gj_cy_main\": [\n \"poc_tenants\",\n \"\
+ batch_canji\"\n ],\n \"gj_jianbie\": [\n \"poc_tenants\"\n ],\n \"gj_kc_fbtl_item\"\
+ : [\n \"poc_tenants\",\n \"gj_kc_fbtl_plan\"\n ],\n \"gj_kc_fbtl_plan\"\
+ : [\n \"poc_tenants\",\n \"batch_canji\",\n \"gj_jianbie\"\n ],\n\
+ \ \"gj_kc_fbtl_release\": [\n \"poc_tenants\",\n \"batch_canji\"\n ],\n\
+ \ \"gyh_kaohe_check_result_bbit\": [\n \"poc_tenants\",\n \"batch_canji\"\
+ ,\n \"cz_gyh\"\n ],\n \"gyh_kaohe_check_result_item_bbit\": [\n \"poc_tenants\"\
+ ,\n \"batch_canji\",\n \"gyh_kaohe_check_result_bbit\",\n \"gyh_kaohe_config_bbit\"\
+ \n ],\n \"gyh_kaohe_config_bbit\": [\n \"poc_tenants\",\n \"batch_canji\"\
+ \n ],\n \"gyh_kpi_result\": [\n \"poc_tenants\",\n \"batch_canji\",\n\
+ \ \"cz_gyh\"\n ],\n \"ljtc_nonghu_pinkunhu\": [],\n \"nonghu_extend_con_config\"\
+ : [\n \"poc_tenants\"\n ],\n \"nonghu_info\": [\n \"poc_tenants\",\n\
+ \ \"cbms_rbac_base_departments\"\n ],\n \"nonghu_info_temp\": [\n \"\
+ poc_tenants\",\n \"nonghu_info\",\n \"cbms_rbac_base_departments\"\n \
+ \ ],\n \"nsl_pinkunhu_info\": [],\n \"poc_tenants\": [],\n \"sangyuan_manage\"\
+ : [\n \"poc_tenants\",\n \"nonghu_info\"\n ],\n \"sc_worker\": [\n \
+ \ \"poc_tenants\"\n ],\n \"sc_worker_xianxiangcun_config\": [\n \"poc_tenants\"\
+ ,\n \"sc_worker\"\n ],\n \"sg_box_config_bydep\": [\n \"poc_tenants\"\
+ ,\n \"batch_canji\",\n \"cbms_rbac_base_departments\"\n ],\n \"sg_butie_param\"\
+ : [\n \"poc_tenants\",\n \"batch_canji\"\n ],\n \"sg_canji_config\"\
+ : [\n \"poc_tenants\",\n \"batch_canji\"\n ],\n \"sg_canji_config_price\"\
+ : [\n \"poc_tenants\",\n \"batch_canji\",\n \"sg_type_config\",\n \
+ \ \"cbms_rbac_base_departments\"\n ],\n \"sg_chengzhong\": [\n \"poc_tenants\"\
+ ,\n \"nonghu_info\",\n \"batch_canji\",\n \"cbms_rbac_base_departments\"\
+ ,\n \"cz_gyh\"\n ],\n \"sg_chengzhong_extention\": [\n \"poc_tenants\"\
+ ,\n \"sg_chengzhong\"\n ],\n \"sg_chengzhong_inputdata\": [\n \"poc_tenants\"\
+ ,\n \"sg_chengzhong\"\n ],\n \"sg_chengzhong_item_sum\": [\n \"poc_tenants\"\
+ ,\n \"sg_chengzhong\",\n \"sg_type_config\"\n ],\n \"sg_datawall_config\"\
+ : [\n \"poc_tenants\",\n \"batch_canji\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"sg_fb_dan\": [\n \"poc_tenants\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"sg_fb_dan_detail\": [\n \"poc_tenants\",\n \"sg_fb_dan\"\n\
+ \ ],\n \"sg_type_config\": [\n \"poc_tenants\"\n ],\n \"sys_update_log\"\
+ : [\n \"poc_tenants\",\n \"cbms_rbac_base_departments\"\n ],\n \"user_xianxiangcun_config\"\
+ : [\n \"poc_tenants\",\n \"cbms_rbac_base_users\",\n \"cbms_rbac_base_roles\"\
+ \n ],\n \"wms_kufang\": [\n \"poc_tenants\"\n ],\n \"wms_wanglaidanwei\"\
+ : [\n \"poc_tenants\"\n ],\n \"wms_wuzi\": [\n \"poc_tenants\",\n \
+ \ \"wms_wanglaidanwei\"\n ],\n \"wms_wuzikucun\": [\n \"poc_tenants\"\
+ ,\n \"wms_wuzi\",\n \"wms_kufang\",\n \"wms_wanglaidanwei\"\n ],\n\
+ \ \"worker\": [\n \"poc_tenants\",\n \"cbms_rbac_base_departments\"\n\
+ \ ],\n \"worker_nonghu\": [\n \"poc_tenants\",\n \"worker\",\n \"\
+ nonghu_info\"\n ],\n \"worker_record\": [\n \"poc_tenants\",\n \"worker\"\
+ ,\n \"batch_canji\",\n \"cbms_rbac_base_departments\"\n ],\n \"wuzi_archives\"\
+ : [\n \"poc_tenants\"\n ],\n \"wuzi_commit\": [\n \"poc_tenants\"\n\
+ \ ],\n \"wuzi_commit_item\": [\n \"poc_tenants\",\n \"wuzi_commit\"\
+ ,\n \"wuzi_archives\"\n ],\n \"wuzi_config\": [\n \"poc_tenants\"\n\
+ \ ],\n \"wuzi_inout_bill\": [\n \"poc_tenants\",\n \"nonghu_info\",\n\
+ \ \"batch_canji\",\n \"cbms_rbac_base_departments\"\n ],\n \"wuzi_inout_bill_item\"\
+ : [\n \"poc_tenants\",\n \"wuzi_inout_bill\",\n \"wuzi_archives\"\n\
+ \ ],\n \"wuzi_input\": [\n \"poc_tenants\",\n \"wuzi_warehouse\",\n\
+ \ \"wuzi_supplier\"\n ],\n \"wuzi_input_item\": [\n \"poc_tenants\"\
+ ,\n \"wuzi_input\",\n \"wuzi_archives\"\n ],\n \"wuzi_inventory\": [\n\
+ \ \"poc_tenants\",\n \"wuzi_archives\",\n \"wuzi_warehouse\"\n ],\n\
+ \ \"wuzi_out\": [\n \"poc_tenants\",\n \"wuzi_warehouse\",\n \"nonghu_info\"\
+ \n ],\n \"wuzi_out_item\": [\n \"poc_tenants\",\n \"wuzi_out\",\n \
+ \ \"wuzi_archives\"\n ],\n \"wuzi_supplier\": [\n \"poc_tenants\"\n ],\n\
+ \ \"wuzi_warehouse\": [\n \"poc_tenants\",\n \"cbms_rbac_base_departments\"\
+ \n ],\n \"yp_bill_kpi_item\": [\n \"poc_tenants\",\n \"sg_chengzhong\"\
+ ,\n \"yp_bill_list\"\n ],\n \"yp_bill_kpi_item_fix\": [\n \"poc_tenants\"\
+ ,\n \"sg_chengzhong\"\n ],\n \"yp_bill_list\": [\n \"poc_tenants\",\n\
+ \ \"sg_chengzhong\",\n \"sg_type_config\"\n ]\n}\n"
+ value_type: string
+ - description: 用户提问
+ id: c0ec71d5-7fb5-4279-a8fd-95c94e35a837
+ name: user_query
+ selector:
+ - conversation
+ - user_query
+ value: ''
+ value_type: string
+ - description: 业务规则
+ id: 94f312c3-0a47-4d37-970c-aaa2bfbae2a7
+ name: global_rules
+ selector:
+ - conversation
+ - global_rules
+ value: '【实体与范围】
+
+ - 蚕季名称优先按 batch_canji.batchname 查询;需要拆分时使用 bathcyears + batchname,不按自然日期年份替代蚕季年度。
+
+ - 茧站名称或编码先查询 cbms_rbac_base_departments;收购站、订种站、支付站、建档站按各业务表 depsysid 或 departmentsysid
+ 区分。
+
+ - 常见蚕季名称:2020春三批、2019年正秋季、2024年晚春季等,在遇到类似名称时,要将其视为蚕季名称。且在查询时最好将用户所述的蚕季名分开查询,例如用户查询2026春一的情况,则需要分解”2026春一“为2026与春一,并限定"batch_canji".batchname
+ contain ”春一“ 同时 "batch_canji".batchyear equal ”2026“
+
+ - 常见租户名称/简称,在遇到此类名称时视为租户:鎏金铜蚕、南丝路集团/南丝路、主干信息、会东、嘉联、蓉桑里、嘉风、雅天丝、奥立丝绸、安泰茧丝绸。
+
+
+ 【默认有效口径】
+
+ - 农户数量默认统计 nonghu_info.flag=1;只有明确要求全部档案或包含冻结时才使用未过滤 count。
+
+ - 有效收购:sg_chengzhong.flag=1 且 billstate=2。
+
+ - 有效订种:cz_dzbill_list.flag=1 且 dzsum>0。
+
+ - 鎏金铜蚕租户特殊订种口径:当租户为鎏金铜蚕或 tenantid=603143556655353856,统计订种张数、领种数量、养蚕张数时,默认只统计支付成功订种,即
+ CZ_DZBILL_LIST.dzpaystate=1;使用业务 Cube 时优先选择 bus_order_delivery.paid_order_quantity_sheet,而不是
+ bus_order_delivery.order_quantity_sheet。
+
+ - 有效支付:bank_pay_base.flag>0;支付成功默认 paystate in (3,6,7)。
+
+
+ 【计算与模型选择】
+
+ - 选择能完整回答问题的最小 Cube;单纯农户档案、数量、年龄使用 nonghu_info,跨蚕季累计经营使用 bus_farmer_operation。
+
+ - 汇总均价、比率、单产必须使用汇总分子/汇总分母,不平均行级比率。
+
+ - 默认农户单产=有效售茧净重/全部有效订种张数;排行/Top 类问题默认按目标指标 DESC,大数在前;小于/低于阈值只作为过滤条件,不改变排序方向,只有明确“最低/风险优先”才
+ ASC。
+
+ - 收购新模式使用 sg_chengzhong.sgqudaotype<>0;订种新模式使用 cz_dzbill_list.dzplat<>4,两者不得混用。
+
+ - 农户年龄使用 nonghu_info.age_years;该维度从身份证出生日期计算周岁,无效身份证返回空值。
+
+ - 补贴金额均为测算,不代表实际发放;仪评加权指标以最终重量为权重。
+
+ '
+ value_type: string
+ environment_variables: []
+ features:
+ file_upload:
+ allowed_file_extensions:
+ - .XLSX
+ - .XLS
+ allowed_file_types:
+ - custom
+ allowed_file_upload_methods:
+ - local_file
+ enabled: true
+ fileUploadConfig:
+ attachment_image_file_size_limit: 2
+ audio_file_size_limit: 50
+ batch_count_limit: 5
+ file_size_limit: 15
+ file_upload_limit: 20
+ image_file_batch_limit: 10
+ image_file_size_limit: 10
+ single_chunk_attachment_limit: 10
+ video_file_size_limit: 100
+ workflow_file_upload_limit: 10
+ image:
+ enabled: false
+ number_limits: 3
+ transfer_methods:
+ - local_file
+ - remote_url
+ number_limits: 1
+ opening_statement: 您好,我是F8数据助手,请问有什么可以帮到您的呢?🫡
+ retriever_resource:
+ enabled: false
+ sensitive_word_avoidance:
+ enabled: false
+ speech_to_text:
+ enabled: false
+ suggested_questions:
+ - 有多少农户
+ - 查询农户张松期的手机号码
+ - '池河镇2026春一的单产多少 '
+ - 查询军民村的李志富的订种记录
+ - 统计当前蚕季的收购情况
+ - 统计当前蚕季各茧别的收购情况
+ - 统计石泉县单产中小于70公斤/张的前十农户排行榜
+ - 按农户乡镇统计新模式中蚕季为”2026春一“的蚕茧收购情况
+ - 统计农户年龄为小于16岁,大于70岁的农户。 农户名、身份证号 、手机号以及最近一次卖茧时间。
+ suggested_questions_after_answer:
+ enabled: false
+ model:
+ completion_params:
+ echo: false
+ frequency_penalty: 0
+ max_tokens: 0
+ presence_penalty: 0
+ stop: []
+ temperature: 0.7
+ top_p: 0
+ mode: chat
+ name: qwen3.5-flash-2026-02-23
+ provider: langgenius/tongyi/tongyi
+ text_to_speech:
+ enabled: false
+ language: ''
+ voice: ''
+ graph:
+ edges:
+ - data:
+ isInIteration: true
+ isInLoop: false
+ iteration_id: '1781599320305'
+ sourceType: iteration-start
+ targetType: knowledge-retrieval
+ id: 1781599320305start-source-1781599540907-target
+ selected: false
+ source: 1781599320305start
+ sourceHandle: source
+ target: '1781599540907'
+ targetHandle: target
+ type: custom
+ zIndex: 1002
+ - data:
+ isInLoop: false
+ sourceType: iteration
+ targetType: code
+ id: 1781599320305-source-1781594054454-target
+ selected: false
+ source: '1781599320305'
+ sourceHandle: source
+ target: '1781594054454'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInIteration: true
+ isInLoop: false
+ iteration_id: '17817582339680'
+ sourceType: iteration-start
+ targetType: knowledge-retrieval
+ id: 1781758233968start-source-1781758233968017817582339690-target
+ selected: false
+ source: 1781758233968start
+ sourceHandle: source
+ target: '1781758233968017817582339690'
+ targetHandle: target
+ type: custom
+ zIndex: 1002
+ - data:
+ isInLoop: false
+ sourceType: iteration
+ targetType: code
+ id: 17817582339680-source-17817583423940-target
+ selected: false
+ source: '17817582339680'
+ sourceHandle: source
+ target: '17817583423940'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInIteration: false
+ isInLoop: false
+ sourceType: document-extractor
+ targetType: llm
+ id: 1782889122238-source-1782889576269-target
+ selected: false
+ source: '1782889122238'
+ sourceHandle: source
+ target: '1782889576269'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInIteration: false
+ isInLoop: false
+ sourceType: llm
+ targetType: assigner
+ id: 1782889576269-source-1782889756496-target
+ selected: false
+ source: '1782889576269'
+ sourceHandle: source
+ target: '1782889756496'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: if-else
+ targetType: document-extractor
+ id: 1782889131357-true-1782889122238-target
+ selected: false
+ source: '1782889131357'
+ sourceHandle: 'true'
+ target: '1782889122238'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: if-else
+ targetType: assigner
+ id: 1782889131357-false-17828899879200-target
+ selected: false
+ source: '1782889131357'
+ sourceHandle: 'false'
+ target: '17828899879200'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInIteration: false
+ isInLoop: false
+ sourceType: llm
+ targetType: code
+ id: 1781581099032-source-1783053752709-target
+ selected: false
+ source: '1781581099032'
+ sourceHandle: source
+ target: '1783053752709'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: code
+ targetType: code
+ id: 1783053752709-source-1782400000012-target
+ selected: false
+ source: '1783053752709'
+ sourceHandle: source
+ target: '1782400000012'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: http-request
+ targetType: code
+ id: 17830731532390-source-17830731571350-target
+ selected: false
+ source: '17830731532390'
+ sourceHandle: source
+ target: '17830731571350'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: code
+ targetType: assigner
+ id: 17830731571350-source-17830731406880-target
+ selected: false
+ source: '17830731571350'
+ sourceHandle: source
+ target: '17830731406880'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: code
+ targetType: if-else
+ id: 1784083007146-source-1783073068957-target
+ selected: false
+ source: '1784083007146'
+ sourceHandle: source
+ target: '1783073068957'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: start
+ targetType: tool
+ id: 1780903664367-source-1781232881963-target
+ selected: false
+ source: '1780903664367'
+ sourceHandle: source
+ target: '1781232881963'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: if-else
+ targetType: http-request
+ id: 1783073068957-true-17830731532390-target
+ selected: false
+ source: '1783073068957'
+ sourceHandle: 'true'
+ target: '17830731532390'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: assigner
+ targetType: llm
+ id: 1782889756496-source-1782351696945-target
+ selected: false
+ source: '1782889756496'
+ sourceHandle: source
+ target: '1782351696945'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: assigner
+ targetType: llm
+ id: 17828899879200-source-1782351696945-target
+ selected: false
+ source: '17828899879200'
+ sourceHandle: source
+ target: '1782351696945'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: llm
+ targetType: answer
+ id: 1782400000011-source-1784098833176-target
+ selected: false
+ source: '1782400000011'
+ sourceHandle: source
+ target: '1784098833176'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: tool
+ targetType: code
+ id: 1781232881963-source-1784083007146-target
+ selected: false
+ source: '1781232881963'
+ sourceHandle: source
+ target: '1784083007146'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: tool
+ targetType: http-request
+ id: 1781232881963-source-1781581167522-target
+ selected: false
+ source: '1781232881963'
+ sourceHandle: source
+ target: '1781581167522'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: tool
+ targetType: if-else
+ id: 1781232881963-source-1782889131357-target
+ selected: false
+ source: '1781232881963'
+ sourceHandle: source
+ target: '1782889131357'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: llm
+ targetType: iteration
+ id: 1782351696945-source-17817582339680-target
+ selected: false
+ source: '1782351696945'
+ sourceHandle: source
+ target: '17817582339680'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: llm
+ targetType: iteration
+ id: 1782351696945-source-1781599320305-target
+ selected: false
+ source: '1782351696945'
+ sourceHandle: source
+ target: '1781599320305'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: code
+ targetType: llm
+ id: 1781594054454-source-1781581099032-target
+ selected: false
+ source: '1781594054454'
+ sourceHandle: source
+ target: '1781581099032'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: code
+ targetType: llm
+ id: 17817583423940-source-1781581099032-target
+ selected: false
+ source: '17817583423940'
+ sourceHandle: source
+ target: '1781581099032'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: http-request
+ targetType: code
+ id: 1781581167522-source-1782400000012-target
+ selected: false
+ source: '1781581167522'
+ sourceHandle: source
+ target: '1782400000012'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: code
+ targetType: if-else
+ id: 1782400000012-source-1784188747804-target
+ selected: false
+ source: '1782400000012'
+ sourceHandle: source
+ target: '1784188747804'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: if-else
+ targetType: llm
+ id: 1784188747804-true-1782400000011-target
+ selected: false
+ source: '1784188747804'
+ sourceHandle: 'true'
+ target: '1782400000011'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: assigner
+ targetType: if-else
+ id: 17830731406880-source-1784188747804-target
+ selected: false
+ source: '17830731406880'
+ sourceHandle: source
+ target: '1784188747804'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: if-else
+ targetType: llm
+ id: 1784188747804-false-17841887361130-target
+ selected: false
+ source: '1784188747804'
+ sourceHandle: 'false'
+ target: '17841887361130'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: llm
+ targetType: code
+ id: 1782400000011-source-1784188957627-target
+ selected: false
+ source: '1782400000011'
+ sourceHandle: source
+ target: '1784188957627'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: code
+ targetType: assigner
+ id: 1784188957627-source-1784183263188-target
+ selected: false
+ source: '1784188957627'
+ sourceHandle: source
+ target: '1784183263188'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: llm
+ targetType: code
+ id: 17841887361130-source-1784188957627-target
+ selected: false
+ source: '17841887361130'
+ sourceHandle: source
+ target: '1784188957627'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ - data:
+ isInLoop: false
+ sourceType: llm
+ targetType: answer
+ id: 17841887361130-source-1784098833176-target
+ source: '17841887361130'
+ sourceHandle: source
+ target: '1784098833176'
+ targetHandle: target
+ type: custom
+ zIndex: 0
+ nodes:
+ - data:
+ selected: false
+ title: 用户提问
+ type: start
+ variables:
+ - default: '603143556655353856'
+ hint: ''
+ label: 租户ID
+ max_length: 20
+ options: []
+ placeholder: ''
+ required: true
+ type: text-input
+ variable: tenant_id
+ - default: 鎏金铜蚕(石泉)茧丝绸有限公司
+ hint: ''
+ label: 租户名称
+ max_length: 20
+ options: []
+ placeholder: ''
+ required: true
+ type: text-input
+ variable: tenant_name
+ height: 135
+ id: '1780903664367'
+ position:
+ x: -11347.926845025962
+ y: -296.5887295533155
+ positionAbsolute:
+ x: -11347.926845025962
+ y: -296.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ context:
+ enabled: false
+ variable_selector: []
+ desc: ''
+ model:
+ completion_params:
+ response_format: json_object
+ mode: chat
+ name: qwen3.7-plus
+ provider: langgenius/tongyi/tongyi
+ prompt_config:
+ jinja2_variables: []
+ prompt_template:
+ - edition_type: basic
+ id: 99e91b51-0052-4e93-95b5-62e502798f91
+ jinja2_text: ''
+ role: system
+ text: '你是 Cube load 查询体生成器。
+
+
+ # 任务
+
+ 根据参考信息,生成可用于Cube `/cubejs-api/v1/load`接口的请求体的请求,以便获取用户想要的数据。
+
+
+ # 规则:
+
+ - 当查询农户名单、明细、记录或排行榜时,须额外加入当前 Cube 的农户唯一ID维度,如 nhsysid;不要只用农户姓名作为农户粒度。
+
+ - 如果选择的 measure 已经包含用户要求的业务状态或口径,不要再额外添加同义 filter。
+
+
+
+ # 参考知识:
+
+ ## 当前时间:{{#1781232881963.text#}}
+
+
+ ## 当前蚕季ID:{{#conversation.canjiId#}}
+
+ (当用户提问当前蚕季时,筛选数据时需要明确筛选蚕季ID)
+
+
+ ## 业务规则
+
+ {{#conversation.global_rules#}}
+
+
+ ## Cube数据
+
+ {{#1782400000012.result#}}'
+ - edition_type: basic
+ id: c5f6e041-13bd-48f8-b879-f4c2fbd2f183
+ role: user
+ text: '{{#conversation.user_query#}}
+
+
+ 当前租户ID:{{#1780903664367.tenant_id#}}
+
+ **(如果Cube数据中包含类似tenant_id或租户隔离的字段,必须必须必须加此ID筛选)**
+
+ '
+ reasoning_format: separated
+ selected: false
+ structured_output:
+ schema:
+ additionalProperties: false
+ properties:
+ limit_source:
+ description: 如果query中有限制limit的话,此处说明限制来源是系统要求还是用户要求
+ enum:
+ - system
+ - user
+ type: string
+ message:
+ description: 如果status为false或者无法根据知识完全覆盖用户所需要的字段,则此处说明原因以及缺失的字段,否则填写:“成功生成”
+ type: string
+ query:
+ additionalProperties: false
+ description: Cube的/v1/load请求
+ properties:
+ dimensions:
+ description: 维度,负责“按什么看、返回哪些分类/明细字段” 来源是 Cube 元数据里的 dimensions[].name。不可放入measures的name
+ items:
+ type: string
+ type: array
+ filters:
+ description: 过滤条件
+ items:
+ additionalProperties: false
+ properties:
+ and:
+ description: “且”条件时使用
+ items:
+ additionalProperties: false
+ properties:
+ member:
+ description: 过滤对象
+ type: string
+ operator:
+ description: 操作符,用户表达“蚕季为/名称为/包含/叫/查某某名称”,优先使用 operator="contains",不要使用
+ equals,除非用户明确说“精确等于/完全等于/ID
+ enum:
+ - equals
+ - notEquals
+ - contains
+ - startsWith
+ - gt
+ - lt
+ - set
+ - notSet
+ - inDateRange
+ type: string
+ values:
+ description: 过滤值
+ items:
+ type: string
+ type: array
+ required: []
+ type: object
+ type: array
+ or:
+ description: “或”条件时使用,
+ items:
+ additionalProperties: false
+ properties:
+ member:
+ description: 过滤对象
+ type: string
+ operator:
+ description: 操作符,用户表达“蚕季为/名称为/包含/叫/查某某名称”,优先使用 operator="contains",不要使用
+ equals,除非用户明确说“精确等于/完全等于/ID
+ enum:
+ - equals
+ - notEquals
+ - contains
+ - startsWith
+ - gt
+ - lt
+ - set
+ - notSet
+ - inDateRange
+ type: string
+ values:
+ description: 过滤值
+ items:
+ type: string
+ type: array
+ required: []
+ type: object
+ type: array
+ required: []
+ type: object
+ type: array
+ limit:
+ description: 限制返回数量,最大5
+ type: number
+ measures:
+ description: 指标,负责“算什么数” 来源是 Cube 元数据里的 measures[].name。不可放入dimensions的name
+ items:
+ type: string
+ type: array
+ offset:
+ description: 跳过前面多少行,可以结合limit实现分页
+ type: number
+ order:
+ description: 排序,必须是二维数组,例如 [["bus_farmer_yield.yield_kg_per_sheet",
+ "asc"]]
+ items:
+ maxItems: 2
+ minItems: 2
+ prefixItems:
+ - description: 排序字段,例如 bus_farmer_yield.yield_kg_per_sheet
+ type: string
+ - description: 排序方向
+ enum:
+ - asc
+ - desc
+ type: string
+ type: array
+ type: array
+ segments:
+ description: 预先在 Cube 模型中定义好的命名过滤条件
+ items:
+ type: string
+ type: array
+ timeDimensions:
+ description: 时间维度过滤
+ items:
+ additionalProperties: false
+ properties:
+ dateRange:
+ items:
+ type: string
+ type: array
+ dimension:
+ description: 时间维度字段,例如 orders.createdAt
+ type: string
+ granularity:
+ description: 如果不写 granularity,只过滤时间,不按时间分组
+ enum:
+ - year
+ - quarter
+ - month
+ - week
+ - day
+ - hour
+ - minute
+ - second
+ type: string
+ required: []
+ type: object
+ type: array
+ required:
+ - limit
+ - dimensions
+ type: object
+ status:
+ description: 是否可以生成query。缺失字段时仍然返回true
+ enum:
+ - 'true'
+ - 'false'
+ type: string
+ required:
+ - query
+ - message
+ - status
+ - limit_source
+ type: object
+ structured_output_enabled: true
+ title: 生成数据请求
+ type: llm
+ vision:
+ enabled: false
+ height: 88
+ id: '1782400000011'
+ position:
+ x: -7843.845548425899
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -7843.845548425899
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ desc: ''
+ is_team_authorization: true
+ paramSchemas:
+ - auto_generate: null
+ default: '%Y-%m-%d %H:%M:%S'
+ form: form
+ human_description:
+ en_US: Time format in strftime standard.
+ ja_JP: Time format in strftime standard.
+ pt_BR: Time format in strftime standard.
+ zh_Hans: strftime 标准的时间格式。
+ label:
+ en_US: Format
+ ja_JP: Format
+ pt_BR: Format
+ zh_Hans: 格式
+ llm_description: null
+ max: null
+ min: null
+ name: format
+ options: []
+ placeholder: null
+ precision: null
+ required: false
+ scope: null
+ template: null
+ type: string
+ - auto_generate: null
+ default: UTC
+ form: form
+ human_description:
+ en_US: Timezone
+ ja_JP: Timezone
+ pt_BR: Timezone
+ zh_Hans: 时区
+ label:
+ en_US: Timezone
+ ja_JP: Timezone
+ pt_BR: Timezone
+ zh_Hans: 时区
+ llm_description: null
+ max: null
+ min: null
+ name: timezone
+ options:
+ - icon: null
+ label:
+ en_US: UTC
+ ja_JP: UTC
+ pt_BR: UTC
+ zh_Hans: UTC
+ value: UTC
+ - icon: null
+ label:
+ en_US: America/New_York
+ ja_JP: America/New_York
+ pt_BR: America/New_York
+ zh_Hans: 美洲/纽约
+ value: America/New_York
+ - icon: null
+ label:
+ en_US: America/Los_Angeles
+ ja_JP: America/Los_Angeles
+ pt_BR: America/Los_Angeles
+ zh_Hans: 美洲/洛杉矶
+ value: America/Los_Angeles
+ - icon: null
+ label:
+ en_US: America/Chicago
+ ja_JP: America/Chicago
+ pt_BR: America/Chicago
+ zh_Hans: 美洲/芝加哥
+ value: America/Chicago
+ - icon: null
+ label:
+ en_US: America/Sao_Paulo
+ ja_JP: America/Sao_Paulo
+ pt_BR: América/São Paulo
+ zh_Hans: 美洲/圣保罗
+ value: America/Sao_Paulo
+ - icon: null
+ label:
+ en_US: Asia/Shanghai
+ ja_JP: Asia/Shanghai
+ pt_BR: Asia/Shanghai
+ zh_Hans: 亚洲/上海
+ value: Asia/Shanghai
+ - icon: null
+ label:
+ en_US: Asia/Ho_Chi_Minh
+ ja_JP: Asia/Ho_Chi_Minh
+ pt_BR: Ásia/Ho Chi Minh
+ zh_Hans: 亚洲/胡志明市
+ value: Asia/Ho_Chi_Minh
+ - icon: null
+ label:
+ en_US: Asia/Tokyo
+ ja_JP: Asia/Tokyo
+ pt_BR: Asia/Tokyo
+ zh_Hans: 亚洲/东京
+ value: Asia/Tokyo
+ - icon: null
+ label:
+ en_US: Asia/Dubai
+ ja_JP: Asia/Dubai
+ pt_BR: Asia/Dubai
+ zh_Hans: 亚洲/迪拜
+ value: Asia/Dubai
+ - icon: null
+ label:
+ en_US: Asia/Kolkata
+ ja_JP: Asia/Kolkata
+ pt_BR: Asia/Kolkata
+ zh_Hans: 亚洲/加尔各答
+ value: Asia/Kolkata
+ - icon: null
+ label:
+ en_US: Asia/Seoul
+ ja_JP: Asia/Seoul
+ pt_BR: Asia/Seoul
+ zh_Hans: 亚洲/首尔
+ value: Asia/Seoul
+ - icon: null
+ label:
+ en_US: Asia/Singapore
+ ja_JP: Asia/Singapore
+ pt_BR: Asia/Singapore
+ zh_Hans: 亚洲/新加坡
+ value: Asia/Singapore
+ - icon: null
+ label:
+ en_US: Europe/London
+ ja_JP: Europe/London
+ pt_BR: Europe/London
+ zh_Hans: 欧洲/伦敦
+ value: Europe/London
+ - icon: null
+ label:
+ en_US: Europe/Berlin
+ ja_JP: Europe/Berlin
+ pt_BR: Europe/Berlin
+ zh_Hans: 欧洲/柏林
+ value: Europe/Berlin
+ - icon: null
+ label:
+ en_US: Europe/Moscow
+ ja_JP: Europe/Moscow
+ pt_BR: Europe/Moscow
+ zh_Hans: 欧洲/莫斯科
+ value: Europe/Moscow
+ - icon: null
+ label:
+ en_US: Australia/Sydney
+ ja_JP: Australia/Sydney
+ pt_BR: Australia/Sydney
+ zh_Hans: 澳大利亚/悉尼
+ value: Australia/Sydney
+ - icon: null
+ label:
+ en_US: Pacific/Auckland
+ ja_JP: Pacific/Auckland
+ pt_BR: Pacific/Auckland
+ zh_Hans: 太平洋/奥克兰
+ value: Pacific/Auckland
+ - icon: null
+ label:
+ en_US: Africa/Cairo
+ ja_JP: Africa/Cairo
+ pt_BR: Africa/Cairo
+ zh_Hans: 非洲/开罗
+ value: Africa/Cairo
+ placeholder: null
+ precision: null
+ required: false
+ scope: null
+ template: null
+ type: select
+ params:
+ format: ''
+ timezone: ''
+ plugin_id: null
+ plugin_unique_identifier: ''
+ provider_icon: http://10.10.12.101:8095/console/api/workspaces/current/tool-provider/builtin/time/icon
+ provider_id: time
+ provider_name: time
+ provider_type: builtin
+ selected: false
+ title: 获取当前时间
+ tool_configurations:
+ format:
+ type: mixed
+ value: '%Y-%m-%d %H:%M:%S'
+ timezone:
+ type: constant
+ value: Asia/Shanghai
+ tool_description: 一个用于获取当前时间的工具。
+ tool_label: 获取当前时间
+ tool_name: current_time
+ tool_node_version: '2'
+ tool_parameters: {}
+ type: tool
+ height: 114
+ id: '1781232881963'
+ position:
+ x: -11092.366793451323
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -11092.366793451323
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ context:
+ enabled: false
+ variable_selector: []
+ desc: ''
+ model:
+ completion_params:
+ response_format: json_object
+ temperature: 0
+ top_p: 0.1
+ mode: chat
+ name: qwen3.5-plus
+ provider: langgenius/tongyi/tongyi
+ prompt_config:
+ jinja2_variables: []
+ prompt_template:
+ - edition_type: basic
+ id: 47a93af5-5c9f-463d-bc6d-009ab0a498c7
+ role: system
+ text: '你是 Cube 核心业务口径识别器。
+
+
+ 根据用户问题和知识库召回结果,识别本次查询最核心的业务 Cube,用于后续扩展可 join 的 Cube Meta。
+
+
+ # 任务
+
+ 只输出“核心 Cube”,也就是决定本次查询业务口径、数据粒度和主事实来源的 Cube。
+
+
+ # 生成规则
+
+ - 输出的 name 必须来自业务 Cube CSV 的“业务Cube名”列,或基础 Cube CSV 的“主表”列。
+
+ - 优先输出 1 个核心 Cube;
+
+ - 不要输出仅用于补充字段的 join 表,例如租户表、农户档案、蚕季表、部门表、用户表等。
+
+ - 用户问题包含“手机/电话/身份证”时,不要因此输出 nonghu_info;这些是补充字段,由后续可 join 扩展自动判断。
+
+
+ # 业务提示
+
+ - 看到“订种、领种、养蚕张数、订种模式、订种清单、农户订种明细”,核心 Cube 必须优先输出 bus_order_delivery。
+
+ - 如果问题是普通农户档案、农户名单、农户手机号、身份证号,且不涉及订种/收购/补助等业务事实,核心 Cube 可输出 nonghu_info。
+
+ - 如果问题是农户经营画像、累计订种、累计售茧、经营蚕季数,核心 Cube 优先输出 bus_farmer_operation。
+
+ - 如果问题是售茧、收购、交售、收购金额,核心 Cube 优先输出 bus_purchase_bill。
+
+ - 如果问题是补助、补贴政策、补贴金额,核心 Cube 优先输出 bus_subsidy_policy。
+
+ - 如果用户问题包含以下任何一种茧别:茧别、正茧、普茧、普通正茧、方格正茧、口评茧、双宫、双宫茧、黄斑、黄斑茧、血茧、下茧、下足茧、上茧、品类、分类净重、分类金额问题,同时涉及收购、售茧、鲜茧、茧款、重量、金额、均价、收购情况等语义,使用bus_purchase_grade_mode。
+
+
+ # 业务规则
+
+ {{#conversation.global_rules#}}
+
+
+ # 业务逻辑知识库召回结果(CSV结构)
+
+ 业务词或别名,业务含义,业务Cube名,核心成员,可用维度,数据粒度,默认规则,不适用情况,应用场景
+
+ {{#17817583423940.csv#}}
+
+
+ # 基础表知识库召回结果(CSV结构)
+
+ 业务名词或别名,含义解释,主表,涉及的其他表,涉及字段,不适用的情况
+
+ {{#1781594054454.csv#}}'
+ - id: 3f574f4c-73ff-4de5-8a00-724830b23ed7
+ role: user
+ text: '{{#conversation.user_query#}}'
+ reasoning_format: separated
+ selected: false
+ structured_output:
+ schema:
+ additionalProperties: false
+ properties:
+ core_cube:
+ description: ''
+ type: string
+ required:
+ - core_cube
+ type: object
+ structured_output_enabled: true
+ title: 获取重点表
+ type: llm
+ vision:
+ enabled: false
+ height: 88
+ id: '1781581099032'
+ position:
+ x: -8868.424816665049
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -8868.424816665049
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ authorization:
+ config: null
+ type: no-auth
+ body:
+ data: []
+ type: none
+ headers: ''
+ method: get
+ params: ''
+ retry_config:
+ max_retries: 3
+ retry_enabled: false
+ retry_interval: 100
+ selected: false
+ ssl_verify: false
+ timeout:
+ max_connect_timeout: 0
+ max_read_timeout: 0
+ max_write_timeout: 0
+ title: 获取最新表结构
+ type: http-request
+ url: http://10.10.12.101:4001/cubejs-api/v1/meta
+ variables: []
+ height: 108
+ id: '1781581167522'
+ position:
+ x: -10836.84627996062
+ y: -466.4249608991162
+ positionAbsolute:
+ x: -10836.84627996062
+ y: -466.4249608991162
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ code: "function main({ schema_json, cube_names }) {\n let schema = schema_json;\n\
+ \n if (typeof schema_json === \"string\") {\n try {\n schema =\
+ \ JSON.parse(schema_json);\n } catch {\n return { result: \"[]\"\
+ \ };\n }\n }\n\n const cubes =\n schema && Array.isArray(schema.cubes)\n\
+ \ ? schema.cubes\n : [];\n\n const nameSet = parseCubeNameSet(cube_names);\n\
+ \n if (nameSet.size === 0) {\n return { result: \"[]\" };\n }\n\n \
+ \ // 筛选和转换合并为一次遍历,避免 selectedCubes 中间数组\n const slimCubes = [];\n\n for\
+ \ (let i = 0; i < cubes.length; i++) {\n const cube = cubes[i];\n\n \
+ \ if (nameSet.has(normalizeName(cube.name))) {\n slimCubes.push(toLLMSchemaCube(cube));\n\
+ \ }\n }\n\n return {\n result: JSON.stringify(slimCubes)\n };\n\
+ }\n\n/**\n * 直接生成标准化后的 Set,避免:\n * normalizeList → map → filter → new Set\n\
+ \ */\nfunction parseCubeNameSet(value, result) {\n const nameSet = result\
+ \ || new Set();\n\n if (!value) {\n return nameSet;\n }\n\n if (Array.isArray(value))\
+ \ {\n addNamesToSet(value, nameSet);\n return nameSet;\n }\n\n if\
+ \ (typeof value === \"string\") {\n const text = value.trim();\n\n \
+ \ if (!text) {\n return nameSet;\n }\n\n /*\n * 只有看起来可能是合法\
+ \ JSON 时才调用 JSON.parse。\n * 普通的 \"orders,users\" 不再通过异常进入降级路径。\n \
+ \ */\n if (looksLikeJson(text)) {\n try {\n const parsed\
+ \ = JSON.parse(text);\n\n if (Array.isArray(parsed)) {\n \
+ \ addNamesToSet(parsed, nameSet);\n return nameSet;\n }\n\
+ \n if (typeof parsed === \"string\") {\n addNameToSet(parsed,\
+ \ nameSet);\n return nameSet;\n }\n\n if (parsed\
+ \ && typeof parsed === \"object\") {\n parseCubeNamesObject(parsed,\
+ \ nameSet);\n }\n\n // JSON 解析成功,但类型不受支持时,与原逻辑一样返回空结果\n \
+ \ return nameSet;\n } catch {\n // 解析失败时按逗号字符串处理\n \
+ \ }\n }\n\n addCommaSeparatedNames(text, nameSet);\n return nameSet;\n\
+ \ }\n\n if (typeof value === \"object\") {\n parseCubeNamesObject(value,\
+ \ nameSet);\n }\n\n return nameSet;\n}\n\nfunction parseCubeNamesObject(value,\
+ \ nameSet) {\n // 保持原来的判断优先级\n if (Array.isArray(value.cubes)) {\n \
+ \ addNamesToSet(value.cubes, nameSet);\n return;\n }\n\n if (Array.isArray(value.cube_names))\
+ \ {\n addNamesToSet(value.cube_names, nameSet);\n return;\n }\n\n\
+ \ if (\n typeof value.result === \"string\" ||\n Array.isArray(value.result)\n\
+ \ ) {\n parseCubeNameSet(value.result, nameSet);\n }\n}\n\nfunction\
+ \ addCommaSeparatedNames(text, nameSet) {\n let start = 0;\n\n for (let\
+ \ i = 0; i <= text.length; i++) {\n if (i === text.length || text.charCodeAt(i)\
+ \ === 44) {\n addNameToSet(text.slice(start, i), nameSet);\n start\
+ \ = i + 1;\n }\n }\n}\n\nfunction addNamesToSet(values, nameSet) {\n\
+ \ for (let i = 0; i < values.length; i++) {\n addNameToSet(values[i],\
+ \ nameSet);\n }\n}\n\nfunction addNameToSet(value, nameSet) {\n if (typeof\
+ \ value !== \"string\") {\n return;\n }\n\n const text = value.trim();\n\
+ \n if (!text) {\n return;\n }\n\n const key = normalizeName(text);\n\
+ \n if (key) {\n nameSet.add(key);\n }\n}\n\nfunction looksLikeJson(text)\
+ \ {\n const first = text.charCodeAt(0);\n\n // { [ \" -\n if (\n first\
+ \ === 123 ||\n first === 91 ||\n first === 34 ||\n first === 45\n\
+ \ ) {\n return true;\n }\n\n // 0-9\n if (first >= 48 && first <=\
+ \ 57) {\n return true;\n }\n\n // JSON 原始值\n return (\n text ===\
+ \ \"true\" ||\n text === \"false\" ||\n text === \"null\"\n );\n\
+ }\n\nfunction normalizeName(name) {\n if (typeof name === \"string\") {\n\
+ \ return name.trim().toLowerCase();\n }\n\n return String(name || \"\
+ \")\n .trim()\n .toLowerCase();\n}\n\nfunction toLLMSchemaCube(cube)\
+ \ {\n const result = {};\n\n assignNonEmpty(result, \"name\", cube.name);\n\
+ \ assignNonEmpty(result, \"title\", cube.title);\n assignNonEmpty(result,\
+ \ \"description\", cube.description);\n\n if (Array.isArray(cube.joins)\
+ \ && cube.joins.length > 0) {\n result.joins = mapArray(cube.joins, toLLMJoin);\n\
+ \ }\n\n if (Array.isArray(cube.measures) && cube.measures.length > 0)\
+ \ {\n result.measures = mapArray(cube.measures, toLLMMeasure);\n }\n\
+ \n if (\n Array.isArray(cube.dimensions) &&\n cube.dimensions.length\
+ \ > 0\n ) {\n result.dimensions = mapArray(\n cube.dimensions,\n\
+ \ toLLMDimension\n );\n }\n\n return result;\n}\n\nfunction toLLMJoin(join)\
+ \ {\n const result = {};\n\n assignNonEmpty(result, \"name\", join.name);\n\
+ \ assignNonEmpty(result, \"relationship\", join.relationship);\n\n return\
+ \ result;\n}\n\nfunction toLLMMeasure(measure) {\n const result = {};\n\
+ \n assignNonEmpty(result, \"name\", measure.name);\n assignNonEmpty(result,\
+ \ \"title\", measure.title);\n assignNonEmpty(result, \"description\",\
+ \ measure.description);\n assignNonEmpty(result, \"type\", measure.type);\n\
+ \ assignNonEmpty(result, \"aggType\", measure.aggType);\n assignNonEmpty(result,\
+ \ \"format\", measure.format);\n\n return result;\n}\n\nfunction toLLMDimension(dimension)\
+ \ {\n const result = {};\n\n assignNonEmpty(result, \"name\", dimension.name);\n\
+ \ assignNonEmpty(result, \"title\", dimension.title);\n assignNonEmpty(result,\
+ \ \"description\", dimension.description);\n assignNonEmpty(result, \"\
+ type\", dimension.type);\n\n return result;\n}\n\n/**\n * 替代 removeEmpty\
+ \ + Object.entries。\n * 保留原 removeEmpty 的判断语义:\n * - 跳过 undefined/null\n\
+ \ * - 跳过空白字符串\n * - 跳过空数组\n * - 保留 0、false、NaN、空对象等值\n */\nfunction assignNonEmpty(target,\
+ \ key, value) {\n if (value === undefined || value === null) {\n return;\n\
+ \ }\n\n if (typeof value === \"string\") {\n if (value.trim() === \"\
+ \") {\n return;\n }\n } else if (Array.isArray(value) && value.length\
+ \ === 0) {\n return;\n }\n\n target[key] = value;\n}\n\n/**\n * 与 Array.prototype.map\
+ \ 一样保留稀疏数组结构。\n */\nfunction mapArray(source, mapper) {\n const result\
+ \ = new Array(source.length);\n\n for (let i = 0; i < source.length; i++)\
+ \ {\n if (i in source) {\n result[i] = mapper(source[i]);\n }\n\
+ \ }\n\n return result;\n}"
+ code_language: javascript
+ outputs:
+ result:
+ children: null
+ type: string
+ selected: false
+ title: 筛选所需表
+ type: code
+ variables:
+ - value_selector:
+ - '1781581167522'
+ - body
+ value_type: string
+ variable: schema_json
+ - value_selector:
+ - '1783053752709'
+ - result
+ value_type: string
+ variable: cube_names
+ height: 52
+ id: '1782400000012'
+ position:
+ x: -8375.53288280137
+ y: -466.4249608991162
+ positionAbsolute:
+ x: -8375.53288280137
+ y: -466.4249608991162
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ code: "function main({ input }) {\n let data = input;\n\n // 如果 input 是字符串,先尝试转\
+ \ JSON\n if (typeof data === 'string') {\n try {\n data = JSON.parse(data);\n\
+ \ } catch (e) {\n return {\n csv: '',\n count: 0\n\
+ \ };\n }\n }\n\n const contents = [];\n const seen = new Set();\n\
+ \n // 递归提取所有 content\n function collect(value) {\n if (!value) return;\n\
+ \n // 兼容字符串形式的 JSON\n if (typeof value === 'string') {\n const\
+ \ text = value.trim();\n if (!text) return;\n\n try {\n \
+ \ const parsed = JSON.parse(text);\n collect(parsed);\n } catch\
+ \ (e) {\n // 如果本身就是一行 CSV 文本,也允许收集\n addContent(text);\n \
+ \ }\n\n return;\n }\n\n // 数组:逐项递归\n if (Array.isArray(value))\
+ \ {\n for (const item of value) {\n collect(item);\n }\n\
+ \ return;\n }\n\n // 对象:优先处理 content\n if (typeof value ===\
+ \ 'object') {\n if (typeof value.content === 'string') {\n addContent(value.content);\n\
+ \ }\n\n // 兼容 Dify 常见包装结构\n if (Array.isArray(value.input))\
+ \ collect(value.input);\n if (Array.isArray(value.result)) collect(value.result);\n\
+ \ if (Array.isArray(value.results)) collect(value.results);\n \
+ \ if (Array.isArray(value.data)) collect(value.data);\n if (Array.isArray(value.items))\
+ \ collect(value.items);\n if (Array.isArray(value.output)) collect(value.output);\n\
+ \ }\n }\n\n function addContent(content) {\n const text = String(content).trim();\n\
+ \ if (!text) return;\n\n // 归一化 key:去掉所有空白,降低重复误差\n const key =\
+ \ text.replace(/\\s+/g, '');\n\n if (seen.has(key)) return;\n\n seen.add(key);\n\
+ \ contents.push(text);\n }\n\n collect(data);\n\n return {\n csv:\
+ \ contents.join('\\n')\n };\n}"
+ code_language: javascript
+ desc: ''
+ outputs:
+ csv:
+ children: null
+ type: string
+ selected: false
+ title: 格式化基础表知识
+ type: code
+ variables:
+ - value_selector:
+ - '1781599320305'
+ - output
+ value_type: array[object]
+ variable: input
+ height: 52
+ id: '1781594054454'
+ position:
+ x: -9124.069219455127
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -9124.069219455127
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ error_handle_mode: terminated
+ flatten_output: true
+ height: 181
+ is_parallel: true
+ iterator_input_type: object
+ iterator_selector:
+ - '1782351696945'
+ - structured_output
+ - base_queries
+ output_selector:
+ - '1781599540907'
+ - result
+ output_type: array[object]
+ parallel_nums: 10
+ selected: false
+ start_node_id: 1781599320305start
+ title: 深度检索基础表知识库
+ type: iteration
+ width: 387
+ height: 181
+ id: '1781599320305'
+ position:
+ x: -9518.358462826265
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -9518.358462826265
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 387
+ zIndex: 1
+ - data:
+ desc: ''
+ isInIteration: true
+ selected: false
+ title: ''
+ type: iteration-start
+ draggable: false
+ height: 48
+ id: 1781599320305start
+ parentId: '1781599320305'
+ position:
+ x: 24
+ y: 68
+ positionAbsolute:
+ x: -9494.358462826265
+ y: -41.81201181221708
+ selectable: false
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom-iteration-start
+ width: 44
+ zIndex: 1002
+ - data:
+ dataset_ids:
+ - BCdSJboJ+yZpNXBm4gDUIqxRo7DFaNkkrfR2/ccOpsUknXvLnp5xVzH81WRrWHsR
+ isInIteration: true
+ isInLoop: false
+ iteration_id: '1781599320305'
+ multiple_retrieval_config:
+ reranking_enable: true
+ reranking_mode: reranking_model
+ reranking_model:
+ model: qwen3-rerank
+ provider: langgenius/tongyi/tongyi
+ score_threshold: null
+ top_k: 1
+ weights:
+ keyword_setting:
+ keyword_weight: 0.8
+ vector_setting:
+ embedding_model_name: text-embedding-v4
+ embedding_provider_name: langgenius/tongyi/tongyi
+ vector_weight: 0.2
+ weight_type: customized
+ query_attachment_selector: []
+ query_variable_selector:
+ - '1781599320305'
+ - item
+ retrieval_mode: multiple
+ selected: false
+ title: 检索基础表知识库
+ type: knowledge-retrieval
+ height: 90
+ id: '1781599540907'
+ parentId: '1781599320305'
+ position:
+ x: 16
+ y: 65
+ positionAbsolute:
+ x: -9502.358462826265
+ y: -44.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ zIndex: 1002
+ - data:
+ desc: ''
+ error_handle_mode: terminated
+ flatten_output: true
+ height: 180
+ isInIteration: false
+ isInLoop: false
+ is_parallel: true
+ iterator_input_type: object
+ iterator_selector:
+ - '1782351696945'
+ - structured_output
+ - business_queries
+ output_selector:
+ - '1781758233968017817582339690'
+ - result
+ output_type: array[object]
+ parallel_nums: 10
+ selected: false
+ start_node_id: 1781758233968start
+ title: 深度检索业务知识库
+ type: iteration
+ width: 389
+ height: 180
+ id: '17817582339680'
+ position:
+ x: -9518.358462826265
+ y: 86.07331027256038
+ positionAbsolute:
+ x: -9518.358462826265
+ y: 86.07331027256038
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 389
+ zIndex: 1
+ - data:
+ dataset_ids:
+ - vPpPaNv/0AGRcN8EkOHLdghdF945aY9k9WiMl95EPLEl1rvgcTneSjK6S7VhRsmr
+ desc: ''
+ isInIteration: true
+ isInLoop: false
+ iteration_id: '17817582339680'
+ multiple_retrieval_config:
+ reranking_enable: true
+ reranking_mode: reranking_model
+ reranking_model:
+ model: qwen3-rerank
+ provider: langgenius/tongyi/tongyi
+ score_threshold: null
+ top_k: 1
+ weights:
+ keyword_setting:
+ keyword_weight: 0.8
+ vector_setting:
+ embedding_model_name: text-embedding-v4
+ embedding_provider_name: langgenius/tongyi/tongyi
+ vector_weight: 0.2
+ weight_type: customized
+ query_attachment_selector: []
+ query_variable_selector:
+ - '17817582339680'
+ - item
+ retrieval_mode: multiple
+ selected: false
+ title: 检索业务知识库
+ type: knowledge-retrieval
+ height: 90
+ id: '1781758233968017817582339690'
+ parentId: '17817582339680'
+ position:
+ x: 118
+ y: 68
+ positionAbsolute:
+ x: -9400.358462826265
+ y: 154.07331027256038
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ zIndex: 1002
+ - data:
+ desc: ''
+ isInIteration: true
+ selected: false
+ title: ''
+ type: iteration-start
+ draggable: false
+ height: 48
+ id: 1781758233968start
+ parentId: '17817582339680'
+ position:
+ x: 24
+ y: 68
+ positionAbsolute:
+ x: -9494.358462826265
+ y: 154.07331027256038
+ selectable: false
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom-iteration-start
+ width: 44
+ zIndex: 1002
+ - data:
+ code: "function main({ input }) {\n let data = input;\n\n // 如果 input 是字符串,先尝试转\
+ \ JSON\n if (typeof data === 'string') {\n try {\n data = JSON.parse(data);\n\
+ \ } catch (e) {\n return {\n csv: '',\n count: 0\n\
+ \ };\n }\n }\n\n const contents = [];\n const seen = new Set();\n\
+ \n // 递归提取所有 content\n function collect(value) {\n if (!value) return;\n\
+ \n // 兼容字符串形式的 JSON\n if (typeof value === 'string') {\n const\
+ \ text = value.trim();\n if (!text) return;\n\n try {\n \
+ \ const parsed = JSON.parse(text);\n collect(parsed);\n } catch\
+ \ (e) {\n // 如果本身就是一行 CSV 文本,也允许收集\n addContent(text);\n \
+ \ }\n\n return;\n }\n\n // 数组:逐项递归\n if (Array.isArray(value))\
+ \ {\n for (const item of value) {\n collect(item);\n }\n\
+ \ return;\n }\n\n // 对象:优先处理 content\n if (typeof value ===\
+ \ 'object') {\n if (typeof value.content === 'string') {\n addContent(value.content);\n\
+ \ }\n\n // 兼容 Dify 常见包装结构\n if (Array.isArray(value.input))\
+ \ collect(value.input);\n if (Array.isArray(value.result)) collect(value.result);\n\
+ \ if (Array.isArray(value.results)) collect(value.results);\n \
+ \ if (Array.isArray(value.data)) collect(value.data);\n if (Array.isArray(value.items))\
+ \ collect(value.items);\n if (Array.isArray(value.output)) collect(value.output);\n\
+ \ }\n }\n\n function addContent(content) {\n const text = String(content).trim();\n\
+ \ if (!text) return;\n\n // 归一化 key:去掉所有空白,降低重复误差\n const key =\
+ \ text.replace(/\\s+/g, '');\n\n if (seen.has(key)) return;\n\n seen.add(key);\n\
+ \ contents.push(text);\n }\n\n collect(data);\n\n return {\n csv:\
+ \ contents.join('\\n')\n };\n}"
+ code_language: javascript
+ desc: ''
+ isInIteration: false
+ isInLoop: false
+ outputs:
+ csv:
+ children: null
+ type: string
+ selected: false
+ title: 格式化业务知识
+ type: code
+ variables:
+ - value_selector:
+ - '17817582339680'
+ - output
+ value_type: array[object]
+ variable: input
+ height: 52
+ id: '17817583423940'
+ position:
+ x: -9124.069219455127
+ y: 86.07331027256038
+ positionAbsolute:
+ x: -9124.069219455127
+ y: 86.07331027256038
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ context:
+ enabled: false
+ variable_selector: []
+ model:
+ completion_params:
+ response_format: json_object
+ temperature: 0.7
+ mode: chat
+ name: qwen3.5-plus
+ provider: langgenius/tongyi/tongyi
+ prompt_template:
+ - id: 47b4da58-d911-439e-b970-3e3f2486b74f
+ role: system
+ text: "你是业务知识库检索词生成器。\n\n根据用户原始问题,分别生成:\n\n- business_queries:用于检索“业务逻辑知识库”\n\
+ - base_queries:用于检索“基础表知识库”\n- qa_queries:用于检索历史问答知识库\n- \n\n业务逻辑知识库主要包含:\n\
+ - 业务指标和业务含义\n- 核心成员和可用维度\n- 数据粒度\n- 适用和不适用场景\n\n基础表知识库主要包含:\n- 业务名词和别名\n\
+ - 实体所在表\n- 原始字段含义\n- 表关系\n- 状态字段\n- 实体定位方式\n\n生成要求:\n\n1. 每类最多生成2条检索词,简短明确。\n\
+ 3. 不要把具体租户名、人名、身份证号、编号、日期或数值放入检索词。\n4. 保留影响业务含义的条件,例如“有效农户”“年龄”“低产”“已支付”。\n\
+ 5. business_queries重点描述查询指标、维度和业务场景。\n6. base_queries重点描述实体定位、字段含义和原始数据关系。\n\
+ 7. qa_queries 只参考用户原始问题,提取 1~5 个核心业务关键词或短语,用于召回相似历史问题。\n8. 不要生成含义重复的检索词。\n\
+ \n其他规则:\n{{#conversation.global_rules#}}"
+ - id: e83796ca-f021-41d2-85b3-91790d1db984
+ role: user
+ text: '{{#conversation.user_query#}}'
+ selected: false
+ structured_output:
+ schema:
+ additionalProperties: false
+ properties:
+ base_queries:
+ items:
+ type: string
+ type: array
+ business_queries:
+ items:
+ type: string
+ type: array
+ qa_queries:
+ items:
+ type: string
+ type: array
+ required:
+ - business_queries
+ - base_queries
+ - qa_queries
+ type: object
+ structured_output_enabled: true
+ title: 意图理解
+ type: llm
+ vision:
+ enabled: false
+ height: 88
+ id: '1782351696945'
+ position:
+ x: -9793.33434626631
+ y: 27.746422531720228
+ positionAbsolute:
+ x: -9793.33434626631
+ y: 27.746422531720228
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ is_array_file: true
+ selected: false
+ title: 文档解析
+ type: document-extractor
+ variable_selector:
+ - sys
+ - files
+ height: 104
+ id: '1782889122238'
+ position:
+ x: -10582.764943990636
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -10582.764943990636
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ cases:
+ - case_id: 'true'
+ conditions:
+ - comparison_operator: not empty
+ id: f16c19d2-12b2-4890-b13a-95ab9ff3c102
+ sub_variable_condition:
+ case_id: 596e5c2a-c188-490c-a210-10bf05151805
+ conditions:
+ - comparison_operator: '>'
+ id: 8278eaf8-c597-4023-8a61-616164ec2fcf
+ key: size
+ value: '0'
+ varType: string
+ logical_operator: and
+ value: ''
+ varType: array[file]
+ variable_selector:
+ - sys
+ - files
+ id: 'true'
+ logical_operator: and
+ selected: false
+ title: 判断用户文件输入
+ type: if-else
+ height: 124
+ id: '1782889131357'
+ position:
+ x: -10836.84627996062
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -10836.84627996062
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ context:
+ enabled: false
+ variable_selector: []
+ model:
+ completion_params:
+ temperature: 0.7
+ mode: chat
+ name: qwen3.5-flash
+ provider: langgenius/tongyi/tongyi
+ prompt_template:
+ - id: cd5e2e74-1424-4f74-83ba-ee5366f71130
+ role: system
+ text: '你是一个数据查询问题整理助手。请结合用户原始问题和用户提供的表格字段信息,将其整理成一个语义完整、条件明确、可直接用于数据查询或自然语言转
+ SQL 的问题。
+
+
+ 整理要求:
+
+ - 保留用户原始问题中的查询对象、范围、筛选条件和业务含义。
+
+ - 根据表格字段补充查询所需的返回内容,但不要虚构表格中不存在的字段。
+
+ - 对用户问题中的口语化、模糊或不完整表达进行规范化。
+
+ - 只输出整理后的完整问题,不要输出分析过程、解释或 SQL。
+
+ - 不要将示例数据、字段说明或无关内容加入最终问题。'
+ - id: fddcbfa6-abf2-4030-b331-951a739fdd4a
+ role: user
+ text: '用户提问:
+
+ {{#sys.query#}}
+
+
+ 用户提供的表格:
+
+ {{#1782889122238.text#}}'
+ selected: false
+ title: 整理文件
+ type: llm
+ vision:
+ enabled: false
+ height: 88
+ id: '1782889576269'
+ position:
+ x: -10317.383808423989
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -10317.383808423989
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ items:
+ - input_type: variable
+ operation: over-write
+ value:
+ - '1782889576269'
+ - text
+ variable_selector:
+ - conversation
+ - user_query
+ selected: false
+ title: 整理问题
+ type: assigner
+ version: '2'
+ height: 84
+ id: '1782889756496'
+ position:
+ x: -10049.790484827632
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -10049.790484827632
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ desc: ''
+ isInIteration: false
+ isInLoop: false
+ items:
+ - input_type: variable
+ operation: over-write
+ value:
+ - sys
+ - query
+ variable_selector:
+ - conversation
+ - user_query
+ selected: false
+ title: 整理问题
+ type: assigner
+ version: '2'
+ height: 84
+ id: '17828899879200'
+ position:
+ x: -10582.764943990636
+ y: 27.746422531720228
+ positionAbsolute:
+ x: -10582.764943990636
+ y: 27.746422531720228
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ code: "function main({ cube_joins, core_name }) {\n const joinMap = parseJsonObject(cube_joins);\n\
+ \ const coreName = parseCoreName(core_name);\n\n if (!coreName) {\n \
+ \ return {\n result: \"[]\"\n };\n }\n\n const normalizedCore\
+ \ = normalizeName(coreName);\n const keyMap = buildKeyMap(joinMap);\n\n\
+ \ const actualCoreKey = keyMap[normalizedCore] || coreName;\n const joinNames\
+ \ = Array.isArray(joinMap[actualCoreKey])\n ? joinMap[actualCoreKey]\n\
+ \ : [];\n\n const result = unique([\n actualCoreKey,\n ...joinNames\n\
+ \ ]);\n\n return {\n result: JSON.stringify(result)\n };\n}\n\nfunction\
+ \ parseJsonObject(value) {\n if (!value) {\n return {};\n }\n\n if\
+ \ (typeof value === \"object\" && !Array.isArray(value)) {\n return value;\n\
+ \ }\n\n if (typeof value !== \"string\") {\n return {};\n }\n\n try\
+ \ {\n const parsed = JSON.parse(value);\n return parsed && typeof\
+ \ parsed === \"object\" && !Array.isArray(parsed)\n ? parsed\n \
+ \ : {};\n } catch (e) {\n return {};\n }\n}\n\nfunction parseCoreName(value)\
+ \ {\n if (!value) {\n return \"\";\n }\n\n if (typeof value === \"\
+ string\") {\n const text = value.trim();\n\n if (!text) {\n return\
+ \ \"\";\n }\n\n try {\n const parsed = JSON.parse(text);\n\n\
+ \ if (typeof parsed === \"string\") {\n return parsed.trim();\n\
+ \ }\n\n if (Array.isArray(parsed)) {\n return String(parsed[0]\
+ \ || \"\").trim();\n }\n\n if (parsed && Array.isArray(parsed.cubes))\
+ \ {\n return String(parsed.cubes[0] || \"\").trim();\n }\n\n\
+ \ if (parsed && typeof parsed.core_name === \"string\") {\n \
+ \ return parsed.core_name.trim();\n }\n\n if (parsed && typeof\
+ \ parsed.name === \"string\") {\n return parsed.name.trim();\n \
+ \ }\n } catch (e) {\n return text;\n }\n\n return text;\n\
+ \ }\n\n if (Array.isArray(value)) {\n return String(value[0] || \"\"\
+ ).trim();\n }\n\n if (typeof value === \"object\") {\n if (Array.isArray(value.cubes))\
+ \ {\n return String(value.cubes[0] || \"\").trim();\n }\n\n if\
+ \ (typeof value.core_name === \"string\") {\n return value.core_name.trim();\n\
+ \ }\n\n if (typeof value.name === \"string\") {\n return value.name.trim();\n\
+ \ }\n }\n\n return \"\";\n}\n\nfunction buildKeyMap(object) {\n const\
+ \ result = {};\n\n for (const key of Object.keys(object || {})) {\n \
+ \ result[normalizeName(key)] = key;\n }\n\n return result;\n}\n\nfunction\
+ \ normalizeName(name) {\n return String(name || \"\")\n .trim()\n \
+ \ .toLowerCase();\n}\n\nfunction unique(values) {\n const result = [];\n\
+ \ const seen = new Set();\n\n for (const value of values) {\n if (typeof\
+ \ value !== \"string\") {\n continue;\n }\n\n const text = value.trim();\n\
+ \n if (!text) {\n continue;\n }\n\n const key = normalizeName(text);\n\
+ \n if (seen.has(key)) {\n continue;\n }\n\n seen.add(key);\n\
+ \ result.push(text);\n }\n\n return result;\n}"
+ code_language: javascript
+ outputs:
+ result:
+ children: null
+ type: string
+ selected: false
+ title: 查询joins
+ type: code
+ variables:
+ - value_selector:
+ - conversation
+ - cube_joins
+ value_type: string
+ variable: cube_joins
+ - value_selector:
+ - '1781581099032'
+ - structured_output
+ - core_cube
+ value_type: object
+ variable: core_name
+ height: 52
+ id: '1783053752709'
+ position:
+ x: -8614.489525771321
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -8614.489525771321
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ cases:
+ - case_id: 'true'
+ conditions:
+ - comparison_operator: is
+ id: d1187a47-b9e2-4637-b3d8-2d93cb55613b
+ value: 'true'
+ varType: string
+ variable_selector:
+ - '1784083007146'
+ - need_current_batch
+ id: 'true'
+ logical_operator: and
+ selected: false
+ title: 是否要求当前蚕季
+ type: if-else
+ height: 148
+ id: '1783073068957'
+ position:
+ x: -10582.764943990636
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -10582.764943990636
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ desc: ''
+ isInIteration: false
+ isInLoop: false
+ items:
+ - input_type: variable
+ operation: over-write
+ value:
+ - '17830731571350'
+ - canjiId
+ variable_selector:
+ - conversation
+ - canjiId
+ - input_type: variable
+ operation: over-write
+ value:
+ - '17830731571350'
+ - canjiName
+ variable_selector:
+ - conversation
+ - canjiName
+ selected: false
+ title: '确定蚕季ID '
+ type: assigner
+ version: '2'
+ height: 110
+ id: '17830731406880'
+ position:
+ x: -9793.33434626631
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -9793.33434626631
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ authorization:
+ config: null
+ type: no-auth
+ body:
+ data:
+ - id: key-value-323
+ key: ''
+ type: text
+ value: '{
+
+ "query": {
+
+ "dimensions": [
+
+ "sg_canji_config.cjsysid",
+
+ "sg_canji_config.cjname",
+
+ "sg_canji_config.sgstartdatettime",
+
+ "sg_canji_config.sgenddatettime"
+
+ ],
+
+ "filters": [
+
+ {
+
+ "member": "sg_canji_config.tenantid",
+
+ "operator": "equals",
+
+ "values": ["{{#conversation.default_tenant_id#}}"]
+
+ },
+
+ {
+
+ "member": "sg_canji_config.flag",
+
+ "operator": "gt",
+
+ "values": ["0"]
+
+ },
+
+ {
+
+ "or": [
+
+ {
+
+ "and": [
+
+ {
+
+ "member": "sg_canji_config.sgstartdatettime",
+
+ "operator": "beforeOrOnDate",
+
+ "values": ["{{#1781232881963.text#}}"]
+
+ },
+
+ {
+
+ "member": "sg_canji_config.sgenddatettime",
+
+ "operator": "afterOrOnDate",
+
+ "values": ["{{#1781232881963.text#}}"]
+
+ }
+
+ ]
+
+ },
+
+ {
+
+ "member": "sg_canji_config.sgenddatettime",
+
+ "operator": "beforeDate",
+
+ "values": ["{{#1781232881963.text#}}"]
+
+ }
+
+ ]
+
+ }
+
+ ],
+
+ "order": [
+
+ ["sg_canji_config.sgenddatettime", "desc"],
+
+ ["sg_canji_config.sgstartdatettime", "desc"],
+
+ ["sg_canji_config.cjsysid", "desc"]
+
+ ],
+
+ "limit": 1
+
+ }
+
+ }'
+ type: json
+ desc: ''
+ headers: ''
+ isInIteration: false
+ isInLoop: false
+ method: post
+ params: ''
+ retry_config:
+ max_retries: 3
+ retry_enabled: false
+ retry_interval: 100
+ selected: false
+ ssl_verify: false
+ timeout:
+ connect: 2
+ max_connect_timeout: 0
+ max_read_timeout: 0
+ max_write_timeout: 0
+ read: 10
+ write: 10
+ title: 查询当前蚕季ID
+ type: http-request
+ url: http://10.10.12.101:4001/cubejs-api/v1/load
+ variables: []
+ height: 108
+ id: '17830731532390'
+ position:
+ x: -10317.383808423989
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -10317.383808423989
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ code: "function main({ input }) {\n let data = input;\n\n if (typeof input\
+ \ === \"string\") {\n try {\n data = JSON.parse(input);\n } catch\
+ \ (e) {\n return {\n canjiId: \"\",\n canjiName: \"\"\
+ \n };\n }\n }\n\n const firstItem = data?.data?.[0] ?? {};\n\n\
+ \ return {\n canjiId: firstItem[\"sg_canji_config.cjsysid\"] ?? \"\"\
+ ,\n canjiName: firstItem[\"sg_canji_config.cjname\"] ?? \"\"\n };\n}"
+ code_language: javascript
+ desc: ''
+ isInIteration: false
+ isInLoop: false
+ outputs:
+ canjiId:
+ children: null
+ type: string
+ canjiName:
+ children: null
+ type: string
+ selected: false
+ title: 提取蚕季ID
+ type: code
+ variables:
+ - value_selector:
+ - '17830731532390'
+ - body
+ value_type: string
+ variable: input
+ height: 52
+ id: '17830731571350'
+ position:
+ x: -10049.790484827632
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -10049.790484827632
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ code: "function main(inputs) {\n const question = inputs.question;\n\n return\
+ \ {\n need_current_batch: String(\n typeof question === \"string\"\
+ \ &&\n question.includes(\"当前蚕季\")\n )\n };\n}"
+ code_language: javascript
+ outputs:
+ need_current_batch:
+ children: null
+ type: string
+ selected: false
+ title: 判断当前蚕季
+ type: code
+ variables:
+ - value_selector:
+ - sys
+ - query
+ value_type: string
+ variable: question
+ height: 52
+ id: '1784083007146'
+ position:
+ x: -10836.84627996062
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -10836.84627996062
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ answer: '{{#1782400000011.structured_output#}}
+
+ {{#17841887361130.structured_output#}}'
+ selected: false
+ title: 返回load请求
+ type: answer
+ variables: []
+ height: 122
+ id: '1784098833176'
+ position:
+ x: -7585.9671110161225
+ y: -377.5887295533152
+ positionAbsolute:
+ x: -7585.9671110161225
+ y: -377.5887295533152
+ selected: true
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ items:
+ - input_type: variable
+ operation: over-write
+ value:
+ - '1784188957627'
+ - result
+ variable_selector:
+ - conversation
+ - latest_load
+ selected: false
+ title: 保存上次Load
+ type: assigner
+ version: '2'
+ height: 84
+ id: '1784183263188'
+ position:
+ x: -7296.9671110161225
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -7296.9671110161225
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ context:
+ enabled: false
+ variable_selector: []
+ desc: ''
+ isInIteration: false
+ isInLoop: false
+ model:
+ completion_params:
+ response_format: json_object
+ mode: chat
+ name: qwen3.7-plus
+ provider: langgenius/tongyi/tongyi
+ prompt_config:
+ jinja2_variables: []
+ prompt_template:
+ - edition_type: basic
+ id: 99e91b51-0052-4e93-95b5-62e502798f91
+ jinja2_text: ''
+ role: system
+ text: '你是 Cube load 查询体生成器。
+
+
+ # 任务
+
+ 根据参考信息,生成可用于Cube `/cubejs-api/v1/load`接口的请求体的请求,以便获取用户想要的数据。
+
+
+ # 规则:
+
+ - 当查询农户名单、明细、记录或排行榜时,须额外加入当前 Cube 的农户唯一ID维度,如 nhsysid;不要只用农户姓名作为农户粒度。
+
+ - 如果选择的 measure 已经包含用户要求的业务状态或口径,不要再额外添加同义 filter。
+
+ - 去掉/不要 XXX 为空的"、"排除 XXX 为空"、"只保留 XXX 不为空"均表示修改 filter,不得删除该 dimension。只有用户明确要求"不要显示
+ XXX"、"去掉 XXX 列"、"隐藏 XXX"时,才能从 dimensions 中删除字段。
+
+
+ # 参考知识:
+
+ ## 当前时间:{{#1781232881963.text#}}
+
+
+ ## 当前蚕季ID:{{#conversation.canjiId#}}
+
+ (当用户提问当前蚕季时,筛选数据时需要明确筛选蚕季ID)
+
+
+ ## 业务规则
+
+ {{#conversation.global_rules#}}
+
+
+ ## Cube数据
+
+ {{#1782400000012.result#}}'
+ - edition_type: basic
+ id: c5f6e041-13bd-48f8-b879-f4c2fbd2f183
+ role: user
+ text: '当前的Cube请求:
+
+ {{#conversation.latest_load#}}
+
+
+ 用户的新要求:
+
+ {{#conversation.user_query#}}
+
+
+ 当前租户ID:{{#1780903664367.tenant_id#}}
+
+ **(如果Cube数据中包含类似tenant_id或租户隔离的字段,必须必须必须加此ID筛选)**
+
+ '
+ reasoning_format: separated
+ selected: false
+ structured_output:
+ schema:
+ additionalProperties: false
+ properties:
+ limit_source:
+ description: 如果query中有限制limit的话,此处说明限制来源是系统要求还是用户要求
+ enum:
+ - system
+ - user
+ type: string
+ message:
+ description: 如果status为false或者无法根据知识完全覆盖用户所需要的字段,则此处说明原因以及缺失的字段,否则填写:“成功生成”
+ type: string
+ query:
+ additionalProperties: false
+ description: Cube的/v1/load请求
+ properties:
+ dimensions:
+ description: 维度,负责“按什么看、返回哪些分类/明细字段” 来源是 Cube 元数据里的 dimensions[].name。不可放入measures的name
+ items:
+ type: string
+ type: array
+ filters:
+ description: 过滤条件
+ items:
+ additionalProperties: false
+ properties:
+ and:
+ description: “且”条件时使用
+ items:
+ additionalProperties: false
+ properties:
+ member:
+ description: 过滤对象
+ type: string
+ operator:
+ description: 操作符,用户表达“蚕季为/名称为/包含/叫/查某某名称”,优先使用 operator="contains",不要使用
+ equals,除非用户明确说“精确等于/完全等于/ID
+ enum:
+ - equals
+ - notEquals
+ - contains
+ - startsWith
+ - gt
+ - lt
+ - set
+ - notSet
+ - inDateRange
+ type: string
+ values:
+ description: 过滤值
+ items:
+ type: string
+ type: array
+ required: []
+ type: object
+ type: array
+ or:
+ description: “或”条件时使用,
+ items:
+ additionalProperties: false
+ properties:
+ member:
+ description: 过滤对象
+ type: string
+ operator:
+ description: 操作符,用户表达“蚕季为/名称为/包含/叫/查某某名称”,优先使用 operator="contains",不要使用
+ equals,除非用户明确说“精确等于/完全等于/ID
+ enum:
+ - equals
+ - notEquals
+ - contains
+ - startsWith
+ - gt
+ - lt
+ - set
+ - notSet
+ - inDateRange
+ type: string
+ values:
+ description: 过滤值
+ items:
+ type: string
+ type: array
+ required: []
+ type: object
+ type: array
+ required: []
+ type: object
+ type: array
+ limit:
+ description: 限制返回数量,最大5
+ type: number
+ measures:
+ description: 指标,负责“算什么数” 来源是 Cube 元数据里的 measures[].name。不可放入dimensions的name
+ items:
+ type: string
+ type: array
+ offset:
+ description: 跳过前面多少行,可以结合limit实现分页
+ type: number
+ order:
+ description: 排序,必须是二维数组,例如 [["bus_farmer_yield.yield_kg_per_sheet",
+ "asc"]]
+ items:
+ maxItems: 2
+ minItems: 2
+ prefixItems:
+ - description: 排序字段,例如 bus_farmer_yield.yield_kg_per_sheet
+ type: string
+ - description: 排序方向
+ enum:
+ - asc
+ - desc
+ type: string
+ type: array
+ type: array
+ segments:
+ description: 预先在 Cube 模型中定义好的命名过滤条件
+ items:
+ type: string
+ type: array
+ timeDimensions:
+ description: 时间维度过滤
+ items:
+ additionalProperties: false
+ properties:
+ dateRange:
+ items:
+ type: string
+ type: array
+ dimension:
+ description: 时间维度字段,例如 orders.createdAt
+ type: string
+ granularity:
+ description: 如果不写 granularity,只过滤时间,不按时间分组
+ enum:
+ - year
+ - quarter
+ - month
+ - week
+ - day
+ - hour
+ - minute
+ - second
+ type: string
+ required: []
+ type: object
+ type: array
+ required:
+ - limit
+ - dimensions
+ type: object
+ status:
+ description: 是否可以生成query。缺失字段时仍然返回true
+ enum:
+ - 'true'
+ - 'false'
+ type: string
+ required:
+ - query
+ - message
+ - status
+ - limit_source
+ type: object
+ structured_output_enabled: true
+ title: 修正数据请求
+ type: llm
+ vision:
+ enabled: false
+ height: 88
+ id: '17841887361130'
+ position:
+ x: -7843.845548425899
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -7843.845548425899
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ cases:
+ - case_id: 'true'
+ conditions:
+ - comparison_operator: empty
+ id: 1bbb3588-583e-43d7-9214-446c406370d6
+ value: ''
+ varType: string
+ variable_selector:
+ - conversation
+ - latest_load
+ id: 'true'
+ logical_operator: and
+ selected: false
+ title: 条件分支 3
+ type: if-else
+ height: 124
+ id: '1784188747804'
+ position:
+ x: -8107.816891509001
+ y: -275.5887295533155
+ positionAbsolute:
+ x: -8107.816891509001
+ y: -275.5887295533155
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ - data:
+ code: "function main({ input }) {\n return {\n result: JSON.stringify(input)\n\
+ \ };\n}"
+ code_language: javascript
+ outputs:
+ result:
+ children: null
+ type: string
+ selected: false
+ title: 代码执行 7
+ type: code
+ variables:
+ - value_selector:
+ - '1782400000011'
+ - structured_output
+ value_type: object
+ variable: input
+ height: 52
+ id: '1784188957627'
+ position:
+ x: -7576.967111016122
+ y: -109.81201181221708
+ positionAbsolute:
+ x: -7576.967111016122
+ y: -109.81201181221708
+ selected: false
+ sourcePosition: right
+ targetPosition: left
+ type: custom
+ width: 242
+ viewport:
+ x: 5449.14149570833
+ y: 542.9157509872703
+ zoom: 0.6597539553864491
+ rag_pipeline_variables: []