当前位置: 首页 > news >正文

Vue Flow 设计大模型工作流 - 自定义大模型节点

Vue Flow 设计大模型工作流

vue-flow 是一个基于 Vue 3 的库,用于创建可交互的节点式编辑器。它非常适合用来设计工作流、数据流或可视化编程界面。

Orange AI 管理平台在线演示

  • Orange 官网: http://hengzq.cn
  • 在线体验: http://tiny.hengzq.cn
  • 项目文档: http://hengzq.cn/community/index

大模型节点

在这里插入图片描述

源码

<template><div class="node-container"><div class="node-title"><div class="flex items-center"><svg-icon name="wf-llm" /> {{ node.name ?? '大模型' }}</div><div class="right-btn" @click.stop><tiny-button :icon="IconDeltaRight" type="text" @click="runNode"></tiny-button><tiny-action-menu :options="options" mode="card" :max-show-num="0" @item-click="(data: any) => optionsClick(data.itemData.label)"><template #item="{ data }"><span v-if="data.label == 'opt.delete'" style="color: var(--button-delete-color)">{{ $t(data.label) }}</span><span v-else> {{ $t(data.label) }} </span></template></tiny-action-menu></div></div><NodeToolbar :is-visible="runResult ? true : false" :position="Position.Bottom"><RunResultIndex :run-result="runResult"></RunResultIndex></NodeToolbar><!--    <div class="llm-body">--><!--      we--><!--    </div>--><Handle id="llm-target-left" type="target" :position="Position.Left" /><Handle id="llm-source-right" type="source" :position="Position.Right" /></div>
</template><script setup lang="ts">
import * as WfNodeApi from "@/api/large-model/wf-node";
import * as WfRunApi from "@/api/large-model/wf-run";
import { useWfStore } from "@/store/modules/wf";
import { iconDeltaRight } from '@opentiny/vue-icon';
import { Handle, Position } from '@vue-flow/core';
import { NodeToolbar } from '@vue-flow/node-toolbar';
import { computed, defineProps, getCurrentInstance, PropType, ref, Ref } from "vue";
import { updateWfGraphDebounced } from '../utils';import RunResultIndex from '../components/run-result/index.vue';const IconDeltaRight = iconDeltaRight()const { proxy } = getCurrentInstance() as any;
const wfStore = useWfStore();const emit = defineEmits(['delete']);
const props = defineProps({node: {type: Object as PropType<WfNodeApi.WfNode>,required: true},
});const runResult = computed(() => {return wfStore.getRunNodeResultById(props.node.id);
}) as Ref<WfRunApi.WFRunNodeVO>const options = ref([{label: 'opt.delete',}
])const optionsClick = (label: string) => {switch (label) {case 'opt.delete': {wfStore.removeNodeByNodeCode(props.node.nodeCode);updateWfGraphDebounced()break;}default:console.log('code is error.');}
};const runNode = () => {proxy.$modal.message({ message: '开发中...', status: 'info' });// WfExecutionApi.invokeLlmNode({//   id: ""// }).then((res) => {//   proxy.$modal.message({message: '调用成功', status: 'success'});//// })
}</script>
<style lang="less" scoped></style>

大模型配置节点

在这里插入图片描述

源码

<template><tiny-drawer class="config-dialog" :title="title" :visible="visible" :mask="false" width="30%" @close="onClose"><tiny-input v-model="formData.description" class="description" placeholder="请输入描述..." @change="updateFormData" /><tiny-divider /><tiny-collapse v-model="activeNames"><tiny-collapse-item title="模型配置" name="modelConfig"><tiny-cascader v-model="llmParam.modelId" :options="modelList" :props="{ emitPath: false }" style="width: 100%"@change="updateFormData" /></tiny-collapse-item></tiny-collapse><tiny-collapse v-model="activeNames"><tiny-collapse-item title="输入" name="inputParams"><template #title-right><tiny-button type="info" :icon="IconPlus()" size="mini" @click="addInputAttr"></tiny-button></template><tiny-grid ref="inputGridTableRef" :data="inputData" show-overflow="tooltip":edit-config="{ trigger: 'click', mode: 'row', showStatus: true }" @edit-closed="updateFormData"><tiny-grid-column field="name" title="变量名" width="150px" :editor="{ component: 'input', type: 'visible' }"><template #edit="data"><tiny-input v-model="data.row.name" placeholder="请输入内容" @change="updateFormData"></tiny-input></template></tiny-grid-column><tiny-grid-column title="变量值" :editor="{ type: 'visible' }"><template #edit="data"><param-value-index :param="data.row" :node="formData" @delete-value="deleteInputParam" /></template></tiny-grid-column><template #empty></template></tiny-grid></tiny-collapse-item></tiny-collapse><tiny-collapse v-model="activeNames"><tiny-collapse-item title="系统提示词" name="systemPrompt"><tiny-input v-model="llmParam.systemPrompt" type="textarea" :autosize="{ minRows: 5 }" :maxlength="5000"show-word-limit :placeholder="$t('llm.app.systemPrompt.placeholder')" @change="updateFormData" /></tiny-collapse-item></tiny-collapse><tiny-collapse v-model="activeNames"><tiny-collapse-item title="用户提示词" name="prompt"><tiny-input v-model="llmParam.prompt" type="textarea" :autosize="{ minRows: 5 }" :maxlength="5000"show-word-limit :placeholder="$t('llm.app.systemPrompt.placeholder')" @change="updateFormData" /></tiny-collapse-item></tiny-collapse><tiny-collapse v-model="activeNames"><tiny-collapse-item title="输出变量" name="outputParams"><template #title-right><tiny-button type="info" :icon="IconPlus()" size="mini" @click="addOutputAttr"></tiny-button></template><tiny-grid ref="outputGridTableRef" :data="outputData" show-overflow="tooltip":edit-config="{ trigger: 'click', mode: 'row', showStatus: true }" @edit-closed="updateFormData"><tiny-grid-column field="name" title="变量名" :editor="{ component: 'input' }"><template #edit="data"><tiny-input v-model="data.row.name" placeholder="请输入内容" @change="updateFormData"></tiny-input></template></tiny-grid-column><tiny-grid-column title="变量值" :editor="{ type: 'visible' }" width="145px"><template #edit="data"><param-value-index :param="data.row" :node="formData" :input-visible="false"@delete-value="deleteInputParam" /></template></tiny-grid-column><template #empty></template></tiny-grid></tiny-collapse-item></tiny-collapse></tiny-drawer>
</template><script lang="ts" setup>
import * as ModelApi from '@/api/large-model/model';
import * as PlatformApi from '@/api/large-model/platform';
import * as WfNodeApi from "@/api/large-model/wf-node";
import { useWfStore } from "@/store/modules/wf";
import { IconPlus } from '@opentiny/vue-icon';
import { computed, getCurrentInstance, ref } from 'vue';
import ParamValueIndex from '../components/param-value/index.vue';
import { updateWfGraphDebounced } from '../utils';const wfStore = useWfStore();const emit = defineEmits(['update']);
const { proxy } = getCurrentInstance() as any;const visibleKey = 'llm-config-from';const visible = computed(() => {return wfStore.getConfigVisible === visibleKey;
});const title = computed(() => {return '大模型';
});const activeNames = ref(['modelConfig', 'inputParams', 'systemPrompt', 'prompt', 'outputParams']);const formData = ref<WfNodeApi.WfNode>({} as WfNodeApi.WfNode);
const llmParam = ref<WfNodeApi.LlmParam>({} as WfNodeApi.LlmParam);const onClose = () => {if (visible.value) {wfStore.setConfigVisible('');}
};const inputData = ref<WfNodeApi.Param[]>([])
const addInputAttr = () => {proxy.$refs.inputGridTableRef.insert({}).then((res: any) => {proxy.$refs.inputGridTableRef.setActiveRow(res.row);});
}const deleteInputParam = (id: string) => {inputData.value = inputData.value.filter(item => item.id !== id);updateFormData();
}const outputData = ref<WfNodeApi.Param[]>([])
const addOutputAttr = () => {proxy.$refs.outputGridTableRef.insert({}).then((res: any) => {proxy.$refs.outputGridTableRef.setActiveRow(res.row);});
}const updateFormData = () => {if (!formData.value.inputConfig) {formData.value.inputConfig = {};}formData.value.inputConfig.llmParam = llmParam.value ?? {}formData.value.inputConfig.inputParams = proxy.$refs.inputGridTableRef.getTableData().fullData;if (!formData.value.outputConfig) {formData.value.outputConfig = {};}formData.value.outputConfig.outParams = proxy.$refs.outputGridTableRef.getTableData().fullData;// 更新数据wfStore.updateNode(formData.value)updateWfGraphDebounced();
}const modelList = ref<ModelApi.PlatformModelTree[]>([])
const queryPlatformList = () => {PlatformApi.listPlatform().then((res) => {modelList.value = res.data.map((item: PlatformApi.PlatformVO) => ({ 'value': item.code, 'label': item.name }))queryModelList()});
};const queryModelList = () => {ModelApi.listModel({modelType: 'CHAT',enabled: true,}).then((res) => {const models = res.data.map((item: ModelApi.ModelVO) => ({ 'value': item.id, 'label': item.name, 'platform': item.platform }))modelList.value.forEach(item => {item.children = models.filter((model: ModelApi.ModelVO) => model.platform === item.value)})});
};const open = (node: WfNodeApi.WfNode) => {formData.value = node;formData.value.inputConfig = formData.value.inputConfig ?? {}llmParam.value = formData.value.inputConfig.llmParam ?? {}inputData.value = formData.value.inputConfig.inputParams ?? []formData.value.outputConfig = formData.value.outputConfig ?? {}outputData.value = formData.value.outputConfig?.outParams ?? []wfStore.setConfigVisible(visibleKey);queryPlatformList()
};defineExpose({open,
});
</script>

源码下载

  • GitHub: https://github.com/hengzq/orange-tiny-vue3-ui
  • Gitee: https://gitee.com/hengzq/orange-tiny-vue3-ui
http://www.dtcms.com/a/351777.html

相关文章:

  • 基于XiaothinkT6语言模型的文本相似度计算:轻量方案实现文本匹配与去重
  • 乳腺癌数据集支持向量机实践学习总结
  • 2025最新的软件测试热点面试题(答案+解析)
  • OnlyOffice 渲染时间获取指南
  • from中烟科技翼支付 面试题2
  • 项目集升级:顶部导览优化、字段自定义、路线图双模式、阶段图掌控、甘特图升级、工作量优化、仪表盘权限清晰
  • 用大语言模型提升语音翻译:一种全新的端到端方法
  • vue2+elementui 表格单元格增加背景色,根据每列数据的大小 颜色依次变浅显示2
  • 「大模型学习」(15)Prompt Tuning → P-Tuning v1 → P-Tuning v2
  • (论文速读)Prompt Depth Anything:让深度估计进入“提示时代“
  • 6.5 el-tree 组件
  • 用大语言模型实现语音到语音翻译的新方法:Scheduled Interleaved Speech-Text Training
  • Research相关的面试(个人)
  • 云服务器的作用
  • yggjs_rbutton React按钮组件v1.0.0 API 参考文档
  • linux、window java程序导出pdf\word、excel文字字体显示异常、字体样式不一样
  • 【lucene】spancontainingquery
  • 8月26日
  • 【QT学习之路】-Qt入门
  • 新型隐蔽恶意软件利用TP-Link、思科等路由器漏洞获取远程控制权
  • ZMC900E如何实现多主站协同控制?
  • 【typenum】 29 类型级别的数字数组标记特质(TypeArray)
  • 基于政策传导因子与就业脆弱性指数的鲍威尔9月降息决策分析
  • Prometheus 告警组件 Alertmanager 的使用并接入 Grafana
  • docker 安装nacos(vL2.5.0)
  • Android之讯飞语音合成和语音识别
  • React 代码规范
  • 算法练习-合并两个有序数组
  • 表格比对的实现
  • 如何确定哪些层应添加适配器(Adapter)?(58)