Dify.ai 开发 “Figma to Code” 智能体

808 阅读2分钟

Figma to Code 智能体

背景

记一次 Dify.ai 开发的 “Figma to Code” 智能体

智能体流程

“Figma to Code” 智能体主要包括以下核心流程:

1. 调用 Figma API 获取 JSON 文件结构

截屏2025-05-12 下午4.15.21.png

Figma REST API:www.figma.com/developers/…

通过接入 Figma API,用户只需提供公开链接或文件 ID,智能体即可获取设计文件的结构信息,包括页面、图层、组件、布局等。

代码执行节点:

import requests

def main():
    return {
        "result": figmaRequest(),
    }
def figmaRequest():
    figma_file_id = ""
    response = requests.get(
        f"https://api.figma.com/v1/files/{figma_file_id}",
        headers={"X-Figma-Token": ""}
    )
    return response.text

fileId:

截屏2025-05-12 下午3.33.02.png

X-Figma-Token:

截屏2025-05-12 下午3.37.28.png

2. 配置大模型

配置大模型节点,调整模型参数,优化模型提示词

模型配置

截屏2025-05-12 下午3.46.04.png

提示词:

你是一个前端专家,请将以下 Figma 设计数据,转换为VUE+SCSS的页面:

Figma 设计数据:{result}

要求:

-不要使用SCSS的map语法

-字体,颜色, 元素的宽度和高度要从Figma样式提取

-布局优先使用Flexbox/Grid

-图片和图标可以用占位符替代

-生成干净的代码,添加注释

-输出Vue + Scss代码

示例展示

Figma 设计稿图片

截屏2025-05-12 下午4.10.00.png

输出代码呈现效果:

截屏2025-05-12 下午4.11.50.png

输出代码片段(VUE + SCSS)

<template>
  <div class="container">
    <!-- 导航栏 -->
    <nav class="nav-bar">
      <h1 class="nav-title">Projects</h1>
      <div class="nav-icon"></div>
    </nav>

    <!-- 内容切换器 -->
    <div class="content-switcher">
      <div 
        v-for="(tab, index) in tabs"
        :key="index"
        :class="['tab', { active: tab.active }]"
      >
        {{ tab.title }}
      </div>
    </div>

    <!-- 空状态 -->
    <div class="empty-state">
      <div class="image-placeholder"></div>
      <h2 class="empty-title">Nothing here. For now.</h2>
      <p class="empty-description">This is where you’ll find your finished projects.</p>
      <button class="primary-button">Start a project</button>
    </div>

    <!-- 底部标签栏 -->
    <div class="tab-bar">
      <div 
        v-for="(item, index) in tabItems"
        :key="index"
        class="tab-item"
      >
        <div class="tab-icon"></div>
        <span :class="['tab-label', { active: item.active }]">{{ item.label }}</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tabs: [
        { title: 'To do', active: false },
        { title: 'In progress', active: false },
        { title: 'Finished', active: true }
      ],
      tabItems: [
        { label: 'Explore', active: false },
        { label: 'Projects', active: true },
        { label: 'Inbox', active: false },
        { label: 'Profile', active: false }
      ]
    }
  }
}
</script>

<style lang="scss">
// 颜色变量
$neutral-dark: #1E1E1E;
$neutral-medium: #71727A;
$neutral-light: #D4D6DD;
$neutral-bg: #F8F9FE;
$highlight-blue: #006FFD;
$pure-white: #FFFFFF;

.container {
  max-width: 375px;
  margin: 0 auto;
  background: $pure-white;
  min-height: 100vh;
  position: relative;
}

// 导航栏样式
.nav-bar {
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 0.5px solid $neutral-light;
  position: relative;

  .nav-title {
    font-size: 14px;
    font-weight: 700;
    color: $neutral-dark;
    letter-spacing: -0.15px;
  }

  .nav-icon {
    width: 20px;
    height: 20px;
    background: $highlight-blue;
    position: absolute;
    right: 16px;
    border-radius: 4px;
  }
}

// 内容切换器
.content-switcher {
  background: $neutral-bg;
  border-radius: 16px;
  margin: 16px;
  padding: 4px;
  display: flex;
  justify-content: space-between;

  .tab {
    flex: 1;
    padding: 8px 12px;
    border-radius: 12px;
    text-align: center;
    font-size: 12px;
    font-weight: 600;
    color: $neutral-medium;
    transition: all 0.2s;

    &.active {
      background: $pure-white;
      color: $neutral-dark;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
    }
  }
}

// 空状态
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 40px 24px;
  margin-top: 32px;

  .image-placeholder {
    width: 100px;
    height: 100px;
    background: #EAF2FF;
    border-radius: 24px;
    margin-bottom: 32px;
    position: relative;
    
    &::after {
      content: '';
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 32px;
      height: 32px;
      background: $highlight-blue;
      border-radius: 6px;
    }
  }

  .empty-title {
    font-size: 18px;
    font-weight: 800;
    color: $neutral-dark;
    letter-spacing: 0.09px;
    margin-bottom: 8px;
  }

  .empty-description {
    font-size: 14px;
    color: $neutral-medium;
    text-align: center;
    line-height: 20px;
    margin-bottom: 32px;
  }
}

// 主要按钮
.primary-button {
  background: $highlight-blue;
  color: $pure-white;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  transition: opacity 0.2s;

  &:hover {
    opacity: 0.9;
  }
}

// 底部标签栏
.tab-bar {
  position: fixed;
  bottom: 0;
  width: 100%;
  max-width: 375px;
  background: $pure-white;
  padding: 16px;
  display: flex;
  justify-content: space-around;
  border-top: 0.5px solid $neutral-light;

  .tab-item {
    display: flex;
    flex-direction: column;
    align-items: center;

    .tab-icon {
      width: 20px;
      height: 20px;
      background: $neutral-light;
      margin-bottom: 8px;
      border-radius: 4px;
    }

    .tab-label {
      font-size: 10px;
      color: $neutral-medium;
      letter-spacing: 0.15px;

      &.active {
        color: $neutral-dark;
        font-weight: 600;
      }
    }
  }
}
</style>

问题

  1. figma数据结构嵌套过深

截屏2025-05-12 下午4.24.20.png

解决方案:github.com/langgenius/…

  1. 字符串长度过长

截屏2025-05-12 下午4.28.59.png

解决方案:github.com/langgenius/…

总结

经过这次的智能体开发,深入了解到了dify.ai智能体的开发流程,也验证了由Figma设计稿快速转换为高保真页面的可行性