跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
TypeScriptNode.jsAI大前端

用 DevUI 和 MateChat 做企业级 AI 助手

DevUI 适合企业中后台的基础界面,MateChat 负责 AI 对话交互,两者组合可以较快搭出企业级智能助手。文章给出了 Vue 3 + TypeScript + Vite 的接入方式,包括组件注册、对话界面、OpenAI SDK 流式调用、消息缓存、虚拟滚动、知识库检索、文件上传、安全校验以及 Docker 和 GitLab CI 部署示例。整体思路是先把 UI 和交互骨架搭稳,再逐步补上模型、RAG 和运维能力。

樱花落尽发布于 2026/6/300 浏览
用 DevUI 和 MateChat 做企业级 AI 助手

用 DevUI 和 MateChat 做企业级 AI 助手

企业中后台接 AI,最先碰到的通常不是模型,而是界面和交互怎么落到现有体系里。组件风格不统一、对话流程和业务页面割裂、接入成本高,这些问题比'选哪个大模型'更早冒出来。DevUI 和 MateChat 的组合,解决的正是这一层。

DevUI 适合承接企业中后台的基础界面,风格克制,组件也比较完整;MateChat 则把 GenAI 场景里常见的对话、输入、引导、消息展示这些东西先整理好了。两者放在一起,能少写很多重复工作,也更容易把 AI 能力塞进现有产品里,而不是另起一套页面语言。

架构和选型

我把整个方案拆成四层:

  • 展示层:DevUI 负责基础组件,MateChat 负责 AI 交互组件
  • 业务层:处理消息流、上下文和页面状态
  • 服务层:封装模型调用、数据处理和安全校验
  • 模型层:对接盘古大模型、ChatGPT 等大语言模型

技术栈保持得比较常规:

技术栈版本作用选择理由
Vue 33.4+前端框架响应式性能好,生态成熟
DevUI16.0+UI 组件库企业级组件齐全,设计统一
MateChat1.5+AI 交互组件适合直接搭 GenAI 场景
TypeScript5.0+开发语言类型约束足够,后期维护省心
Vite5.0+构建工具启动快,开发体验好
OpenAI SDK4.0+模型对接接口标准化,接入成本低

基础接入

先起一个 Vue 项目,再把 DevUI 和 MateChat 装进去:

# 创建 Vite 项目
npm create vite@latest ai-assistant -- --template vue-ts
cd ai-assistant
# 安装 DevUI 和 MateChat
npm install vue-devui @matechat/core @devui-design/icons
# 安装模型对接依赖
npm install openai

main.ts 里做全局注册就够了:

import { createApp } from 'vue'
import App from './App.vue'
// 引入 DevUI 和 MateChat
import DevUI from 'vue-devui'
import 'vue-devui/style.css'
import MateChat from '@matechat/core'
import '@matechat/core/style.css'
import '@devui-design/icons/icomoon/devui-icon.css'

const app = createApp(App)
app.use(DevUI)
app.use(MateChat)
app.mount('#app')

对话界面怎么搭

MateChat 的核心价值,不是'有一个聊天框',而是把企业里常见的 AI 交互细节都预先整理好了:欢迎页、提示词、气泡消息、输入区、操作按钮,这些东西拼起来就能形成一个完整的助手界面。

<template>
  <McLayout>
    <McHeader :title="'智能助手'" :logoImg="'https://example.com/logo.svg'">
      <template #operationArea>
        <div>
          <i title="帮助文档"></i>
          <i title="设置"></i>
        </div>
      </template>
    </McHeader>
    <McLayoutContent>
      <div v-if="messages.length === 0">
        <McIntroduction 
          :logoImg="'https://example.com/logo2x.svg'" 
          :title="'欢迎使用智能助手'" 
          :subTitle="'AI 助手为您服务'" 
          :description="welcomeDescription" 
        />
        <McPrompt 
          :list="welcomePrompts" 
          :direction="'horizontal'" 
          @itemClick="handlePromptClick" 
        />
      </div>
      <template v-for="(message, index) in messages" :key="index">
        <McBubble 
          v-if="message.role === 'user'" 
          :content="message.content" 
          :align="'right'" 
          :avatarConfig="{ imgSrc: '/user-avatar.svg' }" 
        />
        <McBubble 
          v-else 
          :content="message.content" 
          :avatarConfig="{ imgSrc: 'https://example.com/logo.svg' }" 
          :loading="message.loading" 
          :type="message.error ? 'error' : 'default'"
        >
          <template v-if="message.hasActions" #actions>
            <div>
              <Button icon="op-favorite" size="sm" @click="handleLike(index)">点赞</Button>
              <Button icon="op-report" size="sm" @click="handleReport(index)">反馈</Button>
            </div>
          </template>
        </McBubble>
      </template>
    </McLayoutContent>
    <McLayoutSender>
      <McInput 
        v-model="inputMessage" 
        :maxLength="2000" 
        placeholder="请输入您的问题..." 
        @submit="handleSubmit" 
        :disabled="isProcessing"
      >
        <template #extra>
          <div>
            <div>
              <i title="@智能体"></i>
              <i title="知识库"></i>
              <i title="上传文件"></i>
            </div>
            <div>{{ inputMessage.length }}/2000</div>
          </div>
        </template>
      </McInput>
    </McLayoutSender>
  </McLayout>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { Button } from 'vue-devui/button'
import 'vue-devui/button/style.css'

const welcomeDescription = [
  '我是您的智能助手,可以帮助您解答技术问题、编写代码、查询文档等。',
  '作为 AI 模型,我的回答可能不总是准确的,但您的反馈可以帮助我做得更好。'
]

const welcomePrompts = [
  { label: '如何优化前端性能?', value: 'performance' },
  { label: '帮我写一个排序算法', value: 'sort-algorithm' },
  { label: '解释 Vue3 的响应式原理', value: 'vue3-reactivity' }
]

const messages = ref<any[]>([])
const inputMessage = ref('')
const isProcessing = ref(false)

const handleSubmit = async () => {
  if (!inputMessage.value.trim() || isProcessing.value) return
  const userMessage = inputMessage.value.trim()
  inputMessage.value = ''
  // 添加用户消息
  messages.value.push({ role: 'user', content: userMessage })
  // 添加 AI 回复占位符
  messages.value.push({ role: 'assistant', content: '', loading: true, hasActions: false })
  isProcessing.value = true
  try {
    // 调用 AI 服务
    const response = await callAIModel(userMessage)
    // 更新 AI 回复
    const lastIndex = messages.value.length - 1
    messages.value[lastIndex] = { ...messages.value[lastIndex], content: response, loading: false, hasActions: true }
  } catch (error) {
    const lastIndex = messages.value.length - 1
    messages.value[lastIndex] = { ...messages.value[lastIndex], content: '抱歉,服务暂时不可用,请稍后再试。', loading: false, error: true }
  } finally {
    isProcessing.value = false
  }
}

// 模拟 AI 模型调用
const callAIModel = async (question: string): Promise<string> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      if (question.includes('性能')) {
        resolve('前端性能优化的关键点包括:1. 代码分割和懒加载 2. 图片优化和 CDN 加速 3. 减少重绘重排 4. 使用 Web Workers 处理复杂计算 5. 服务端渲染 (SSR) 等。具体方案需要根据业务场景选择。')
      } else if (question.includes('排序')) {
        resolve('```typescript\nfunction quickSort(arr: number[]): number[] {\n if (arr.length <= 1) return arr;\n const pivot = arr[Math.floor(arr.length / 2)];\n const left = arr.filter(x => x < pivot);\n const right = arr.filter(x => x > pivot);\n return [...quickSort(left), pivot, ...quickSort(right)];\n}\n\n// 使用示例\nconst numbers = [5, 2, 8, 1, 9, 3];\nconsole.log(quickSort(numbers)); // [1, 2, 3, 5, 8, 9]\n```')
      } else {
        resolve('这是 AI 助手的回复内容。在实际应用中,这里会调用真实的大模型 API 获取响应。')
      }
    }, 1500)
  })
}
</script>

<style scoped>
.ai-container { width: 100%; max-width: 1200px; margin: 0 auto; height: calc(100vh - 40px); display: flex; flex-direction: column; }
.chat-content { flex: 1; overflow-y: auto; padding: 20px; }
.welcome-page { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; text-align: center; }
.message-actions { display: flex; gap: 8px; margin-top: 8px; }
.input-extra { display: flex; justify-content: space-between; width: 100%; padding: 0 16px; }
.input-controls { display: flex; gap: 12px; color: #5e7ce0; cursor: pointer; }
.input-count { color: #71757f; font-size: 14px; }
.header-operations { display: flex; gap: 16px; cursor: pointer; }
</style>

实际项目里,这段代码还要再收一层。比如消息状态、错误态、流式输出,都不适合直接堆在一个组件里,但作为原型,它已经足够说明 MateChat 的接入方式。

模型服务对接

真正的 AI 能力,还是要接模型接口。这里用 OpenAI SDK 做了一个流式返回的封装,思路不复杂:把对话历史拼好,发给模型,然后一段段把返回内容更新到界面上。

import OpenAI from 'openai'
import { ref } from 'vue'

// 配置模型服务
const openai = new OpenAI({
  apiKey: import.meta.env.VITE_OPENAI_API_KEY,
  baseURL: import.meta.env.VITE_OPENAI_BASE_URL,
  dangerouslyAllowBrowser: true
})

// 对话历史管理
const conversationHistory = ref<any[]>([])

// 流式响应处理
const handleStreamResponse = async (messages: any[], callback: (content: string) => void) => {
  try {
    let fullResponse = ''
    const completion = await openai.chat.completions.create({
      model: import.meta.env.VITE_MODEL_NAME || 'gpt-3.5-turbo',
      messages: messages.map(msg => ({ role: msg.role, content: msg.content })),
      stream: true,
      temperature: 0.7,
      max_tokens: 2000
    })
    for await (const chunk of completion) {
      const content = chunk.choices[0]?.delta?.content || ''
      fullResponse += content
      callback(content)
    }
    return fullResponse
  } catch (error) {
    console.error('模型调用失败:', error)
    throw new Error('服务调用失败,请稍后重试')
  }
}

// 完整的对话处理函数
const processConversation = async (userInput: string) => {
  // 添加用户消息到历史
  conversationHistory.value.push({ role: 'user', content: userInput })
  // 准备 API 调用的消息
  const apiMessages = [
    { role: 'system', content: '你是一个专业的技术助手,专注于帮助开发者解决编程问题、优化代码、解释技术概念。请用中文回答,并保持专业、准确、简洁。' },
    ...conversationHistory.value.slice(-6) // 保留最近 6 条对话上下文
  ]
  return new Promise<string>((resolve, reject) => {
    let responseContent = ''
    handleStreamResponse(apiMessages, (chunk) => {
      responseContent += chunk
    }).then(() => {
      // 添加 AI 回复到历史
      conversationHistory.value.push({ role: 'assistant', content: responseContent })
      resolve(responseContent)
    }).catch(reject)
  })
}

这里有个取舍:直接浏览器里调用 OpenAI 方便调试,但正式环境里通常还是要把密钥放到服务端,不然安全性说不过去。示例代码保留 dangerouslyAllowBrowser: true,主要是为了演示链路。

让它更像一个能用的产品

如果只是把消息发出去,产品感还不够。下面几件事在实际场景里更常见,也更值得先做:

// 1. 消息缓存与本地存储
const saveConversationToLocalStorage = () => {
  localStorage.setItem('ai_conversation_history', JSON.stringify(conversationHistory.value))
}
const loadConversationFromLocalStorage = () => {
  const saved = localStorage.getItem('ai_conversation_history')
  if (saved) {
    conversationHistory.value = JSON.parse(saved)
  }
}

// 2. 节流与防抖处理
const throttle = (func: Function, limit: number) => {
  let inThrottle = false
  return (...args: any[]) => {
    if (!inThrottle) {
      func.apply(this, args)
      inThrottle = true
      setTimeout(() => inThrottle = false, limit)
    }
  }
}
const debouncedSearch = throttle((query: string) => {
  // 执行搜索逻辑
}, 300)

// 3. 虚拟滚动优化长列表
const useVirtualScroll = (items: any[], containerHeight: number, itemHeight: number) => {
  const visibleItems = ref<any[]>([])
  const scrollTop = ref(0)
  const updateVisibleItems = () => {
    const startIndex = Math.floor(scrollTop.value / itemHeight)
    const endIndex = Math.min(startIndex + Math.ceil(containerHeight / itemHeight) + 2, items.value.length)
    visibleItems.value = items.value.slice(startIndex, endIndex)
  }
  return { visibleItems, updateVisibleItems }
}

这些优化都不花哨,但够实用。尤其是消息历史、长列表和输入节流,后面都会直接影响到用户对'AI 助手稳不稳'的判断。

DevUI 和 MateChat 各自负责什么

DevUI

DevUI 更像企业中后台的地基。它不是专门为 AI 场景设计的,但它把常规业务界面需要的东西做得比较完整,适合承接复杂表格、树、表单这些页面结构。

它的几个特点比较明确:

  • 组件库完整,适合做中后台页面
  • 设计语言统一,页面不容易散
  • 主题能力比较灵活,能贴企业品牌
  • 代码开源,MIT 协议,接入成本低

DevUI 目前支持 Angular ^10.0.0 版本,项目也已经积累了比较长时间的内部实践。下面这个示例保留了它在 Angular 里的基本用法:

// DevUI 组件使用示例
import { Component } from '@angular/core';
import { DButtonComponent } from 'ng-devui/button';

@Component({
  selector: 'app-example',
  template: `
    <d-button bsStyle="primary" (click)="handleClick()">主要按钮</d-button>
    <d-table [data]="tableData" [columns]="columns"></d-table>
  `,
  standalone: true,
  imports: [DButtonComponent]
})
export class ExampleComponent {
  tableData = [
    { id: 1, name: '张三', age: 28 },
    { id: 2, name: '李四', age: 32 }
  ];
  columns = [
    { field: 'id', header: 'ID' },
    { field: 'name', header: '姓名' },
    { field: 'age', header: '年龄' }
  ];
  handleClick() {
    console.log('按钮被点击');
  }
}

MateChat

MateChat 的定位更直接,就是把 GenAI 场景常用的交互骨架搭好。它关心的是:用户怎么唤醒助手、怎么开始提问、模型回复怎么展示、过程中状态怎么表达。

它的价值在于少走弯路。对研发工具、协作平台或者知识助手这类场景来说,不需要从零设计一套聊天系统,直接用它的组件体系起步更快。

它常见的几个能力包括:

  • 快速唤醒
  • 输入区域扩展
  • 消息气泡展示
  • Markdown 渲染
  • 过程态反馈

下面这段是 MateChat 的一个简化示例:

<!-- MateChat 组件使用示例 -->
<template>
  <div>
    <mc-header :title="'智能助手'" :logo-img="'https://example.com/logo.svg'" >
      <template #operation-area>
        <div>
          <i></i>
          <i></i>
        </div>
      </template>
    </mc-header>
    <mc-layout-content>
      <mc-bubble v-for="(msg, index) in messages" :key="index" 
        :content="msg.content" 
        :align="msg.role === 'user' ? 'right' : 'left'" 
        :avatar-config="{ imgSrc: msg.role === 'user' ? '/user-avatar.svg' : 'https://example.com/logo.svg' }" 
      />
    </mc-layout-content>
    <mc-layout-sender>
      <mc-input v-model="inputValue" :max-length="2000" @submit="handleSend" placeholder="输入您的问题..." >
        <template #extra>
          <div>
            <span>智能体</span>
            <span>词库</span>
            <span>{{ inputValue.length }}/2000</span>
          </div>
        </template>
      </mc-input>
    </mc-layout-sender>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const messages = ref([
  { role: 'assistant', content: '您好!我是您的智能助手,有什么可以帮助您?' }
]);
const inputValue = ref('');
const handleSend = () => {
  if (!inputValue.value.trim()) return;
  // 添加用户消息
  messages.value.push({ role: 'user', content: inputValue.value });
  // 模拟 AI 回复
  setTimeout(() => {
    messages.value.push({ role: 'assistant', content: `您输入了:"${inputValue.value}",这是一个 AI 助手的回复示例。` });
  }, 1000);
  inputValue.value = '';
};
</script>
<style scoped>
.chat-container { width: 100%; max-width: 800px; height: 600px; margin: 0 auto; border: 1px solid #ddd; border-radius: 8px; overflow: hidden; }
.chat-content { padding: 20px; overflow-y: auto; }
.input-footer { display: flex; justify-content: space-between; padding: 0 16px; color: #666; }
.icon-at, .icon-standard { cursor: pointer; margin-right: 16px; }
.input-count { color: #999; }
</style>

知识库、多模态和安全

把 AI 助手真正放到企业里,通常还会补三块:知识库、文件处理和安全控制。

知识库这块更像 RAG 的基础设施。模型本身不一定知道企业内部文档,但如果能先检索再回答,命中率会高很多:

interface KnowledgeDocument {
  id: string
  title: string
  content: string
  source: string
  embedding: number[]
}

// 向量检索实现
const searchKnowledgeBase = async (query: string, topK: number = 3): Promise<KnowledgeDocument[]> => {
  try {
    // 调用向量数据库 API
    const response = await fetch('/api/knowledge/search', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      },
      body: JSON.stringify({ query: query, top_k: topK })
    })
    if (!response.ok) {
      throw new Error('知识库搜索失败')
    }
    const results = await response.json()
    return results.documents
  } catch (error) {
    console.error('知识库搜索出错:', error)
    return []
  }
}

// 增强对话上下文
const enhanceContextWithKnowledge = async (messages: any[]) => {
  const lastUserMessage = messages[messages.length - 1]?.content || ''
  // 检测是否需要知识库检索
  const needsKnowledge = /如何 | 为什么 | 解释 | 文档 | 规范/.test(lastUserMessage)
  if (needsKnowledge) {
    const knowledgeDocs = await searchKnowledgeBase(lastUserMessage, 3)
    if (knowledgeDocs.length > 0) {
      const knowledgeContext = knowledgeDocs.map(doc => `【${doc.title}】\n${doc.content.substring(0, 500)}...\n来源:${doc.source}`).join('\n\n')
      messages.unshift({ role: 'system', content: `以下是相关的技术文档和知识库内容,请基于这些信息回答用户问题:\n\n${knowledgeContext}` })
    }
  }
  return messages
}

多模态这部分,重点其实不是'支持多少格式',而是把文件上传和预处理先接起来,别让入口卡在第一步:

<template>
  <div>
    <McInput v-model="inputMessage" placeholder="输入文字或上传文件..." @submit="handleSubmit" >
      <template #prefix>
        <div>
          <label>
            <i></i>
            <input type="file" @change="handleFileUpload" accept=".txt,.md,.pdf,.png,.jpg,.jpeg" hidden >
          </label>
        </div>
      </template>
    </McInput>
    <div v-if="uploadedFiles.length > 0">
      <div v-for="(file, index) in uploadedFiles" :key="index">
        <i :class="getFileIcon(file.type)"></i>
        <span>{{ file.name }}</span>
        <i @click="removeFile(index)"></i>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'

const uploadedFiles = ref<File[]>([])
const inputMessage = ref('')

const handleFileUpload = async (event: Event) => {
  const input = event.target as HTMLInputElement
  const files = input.files
  if (files && files.length > 0) {
    for (let i = 0; i < files.length; i++) {
      const file = files[i]
      // 文件大小限制
      if (file.size > 10 * 1024 * 1024) { // 10MB
        alert(`文件 "${file.name}" 大小超过限制(10MB)`)
        continue
      }
      // 图片文件预处理
      if (file.type.startsWith('image/')) {
        const processedImage = await processImage(file)
        uploadedFiles.value.push({ ...file, processedImage } as File)
      } else {
        uploadedFiles.value.push(file)
      }
    }
    // 重置 input
    input.value = ''
  }
}

const processImage = async (file: File): Promise<string> => {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      const img = new Image()
      img.onload = () => {
        // 创建 canvas 进行缩放
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')!
        // 计算缩放比例
        const maxWidth = 800
        const ratio = Math.min(1, maxWidth / img.width)
        canvas.width = img.width * ratio
        canvas.height = img.height * ratio
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
        // 转换为 base64
        const base64 = canvas.toDataURL('image/jpeg', 0.8)
        resolve(base64)
      }
      img.src = e.target?.result as string
    }
    reader.readAsDataURL(file)
  })
}
</script>

安全这块没有捷径,输入校验、敏感词过滤、重试和错误上报这些东西,往往比'多一个炫酷组件'更重要:

// 输入验证与过滤
const sanitizeInput = (input: string): string => {
  // XSS 防护
  const div = document.createElement('div')
  div.textContent = input
  let safeInput = div.innerHTML
  // 敏感词过滤
  const sensitiveWords = ['password', 'secret', 'token', 'admin']
  sensitiveWords.forEach(word => {
    const regex = new RegExp(word, 'gi')
    safeInput = safeInput.replace(regex, '***')
  })
  // 长度限制
  if (safeInput.length > 2000) {
    safeInput = safeInput.substring(0, 2000) + '...'
  }
  return safeInput
}

// API 调用安全封装
const safeAPICall = async <T>(apiCall: () => Promise<T>, retries = 3): Promise<T> => {
  for (let i = 0; i < retries; i++) {
    try {
      return await apiCall()
    } catch (error) {
      if (i === retries - 1) throw error
      // 指数退避重试
      const delay = Math.pow(2, i) * 1000
      await new Promise(resolve => setTimeout(resolve, delay))
    }
  }
  throw new Error('API 调用失败')
}

部署和运维

到部署阶段,容器化和流水线是比较标准的做法。代码不复杂,但能把交付方式固定下来:

# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install --production=false
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

build:
  stage: build
  image: node:18
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour

test:
  stage: test
  image: node:18
  script:
    - npm install
    - npm run test:unit
    - npm run test:e2e

deploy-production:
  stage: deploy
  image: alpine
  script:
    - apk add --no-cache curl
    - curl -X POST -H "Authorization: Bearer $DEPLOY_TOKEN" https://api.example.com/deploy
  only:
    - main

结尾

这套组合的价值不在'AI'两个字本身,而在于它把企业中后台最容易散掉的那几部分——基础 UI、对话交互、模型接入和工程化落地——拉到了一起。DevUI 负责稳住界面底盘,MateChat 负责把 AI 场景的交互骨架搭出来,模型和知识库再往上补能力,链路就完整了。

如果只是做一个演示,很多东西可以再简化;但真要进企业系统,安全、上下文、错误处理和部署方式都不能省。这个方案的好处是起步快,坏处也很明显:它不是'一套代码通吃所有场景',后面还是要根据业务再做收敛和拆分。

目录

  1. 用 DevUI 和 MateChat 做企业级 AI 助手
  2. 架构和选型
  3. 基础接入
  4. 创建 Vite 项目
  5. 安装 DevUI 和 MateChat
  6. 安装模型对接依赖
  7. 对话界面怎么搭
  8. 模型服务对接
  9. 让它更像一个能用的产品
  10. DevUI 和 MateChat 各自负责什么
  11. DevUI
  12. MateChat
  13. 知识库、多模态和安全
  14. 部署和运维
  15. Dockerfile
  16. .gitlab-ci.yml
  17. 结尾
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 腾讯三款 AI Agent 怎么选:WorkBuddy、QClaw、CodeBuddy 实测
  • 提升 PyTorch 训练效率的 9 个实用做法
  • 通义万相 2.1 的架构、能力与落地观察
  • 大语言模型原理、应用与演进路线
  • Seedance 2.0 实测:AI 视频从“能看”走向“能用”
  • C++ 虚函数表与多态实现原理
  • 华为机试:素数伴侣的二分图匹配解法
  • Python 学习路线:先打基础,再做项目
  • 大模型面试题整理:RAG、SFT、RLHF 与核心架构
  • USB-Blaster 驱动安装与 FPGA 下载排障
  • Open3D.Art 生成模型到拓竹打印的实用流程
  • Python 3.11 新特性:性能、异常与类型系统的变化
  • RISC-V 处理器从 RTL 到 FPGA 验证实录
  • CoPaw 部署与定制实操笔记
  • IntelliJ IDEA 2026.1 EAP:Java 26、Spring Boot 4 与 Gradle 9 适配
  • 用 WebGIS 和百度天气做一个复古天气预报页
  • YOLOv8 无人机道路病害识别的工程落地思路
  • 在安卓上用 Termux 跑 Debian 和桌面应用
  • 双指针滑动窗口:4 道经典题的思路拆解
  • NWPU VHR-10 遥感目标检测与 YOLO 实践

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online