{
  "source_file": "0930",
  "source_platform": "Dev.to",
  "author": "Nishikanta Ray",
  "title_listed": "KYC Admin Panel – Real-Time Voice KYC with AssemblyAI & Llama 3.3-70B",
  "keywords": "",
  "domain": "大模型算法",
  "content_type": "深度技术解析",
  "is_paid_flag": "否",
  "url": "https://dev.to/nishikantaray/kyc-admin-panel-real-time-voice-kyc-with-assemblyai-llama-33-70b-3d7h",
  "publish_date": "2025-07-27",
  "corpus_stage": "",
  "notes": "",
  "id": "1e88b6ef4393",
  "collected_at": "2026-10-02T14:05:13",
  "title": "KYC Admin Panel – Real-Time Voice KYC with AssemblyAI & Llama 3.3-70B - DEV Community",
  "body_markdown": "This is a submission for the\nAssemblyAI Voice Agents Challenge\nWhat I Built\nKYC Admin Panel – Real-Time Voice KYC with AssemblyAI & Llama 3.3-70B\nWhat I Built\nWe built a KYC Admin Panel that enables ultra-fast, accurate KYC form filling using real-time voice input.\nOur app addresses the Real-Time Performance category by leveraging AssemblyAI’s Universal-Streaming for sub-300ms transcription latency, and Cloudflare’s Llama 3.3-70B Instruct LLM for instant, field-specific extraction and normalization.\nDemo\nYOUTUBE LINK -\nhttps://youtu.be/GUWSwAg18DY?si=V_SOyv-kxNI9gayr\nHOST LINK -\nhttps://assembly-ai-voice-agents-challenge.vercel.app/\nSCREENSHOT\nGitHub Repository\nhttps://github.com/NishikantaRay/AssemblyAI_Voice_Agents_Challenge\nTechnical Implementation & AssemblyAI Integration\nReal-Time Voice Input\nWe use AssemblyAI’s Universal-Streaming WebSocket API for real-time transcription.\nKey code (from src/app/page.js):    \nconst wsUrl = ⁠ wss://streaming.assemblyai.com/v3/ws?sample_rate=16000&formatted_finals=true&token=${token} ⁠;\n    socket.current = new WebSocket(wsUrl);\n\n    const turns = {};\n\n    socket.current.onopen = async () => {\n      console.log(\"WebSocket connection established\");\n      setIsRecording(true);\n\n      mediaStream.current = await navigator.mediaDevices.getUserMedia({\n        audio: true,\n      });\n      audioContext.current = new AudioContext({ sampleRate: 16000 });\n\n      const source = audioContext.current.createMediaStreamSource(\n        mediaStream.current\n      );\n      scriptProcessor.current = audioContext.current.createScriptProcessor(\n        4096,\n        1,\n        1\n      );\n\n      source.connect(scriptProcessor.current);\n      scriptProcessor.current.connect(audioContext.current.destination);\n\n      scriptProcessor.current.onaudioprocess = (event) => {\n        if (!socket.current || socket.current.readyState !== WebSocket.OPEN)\n          return;\n\n        const input = event.inputBuffer.getChannelData(0);\n        const buffer = new Int16Array(input.length);\n        for (let i = 0; i < input.length; i++) {\n          buffer[i] = Math.max(-1, Math.min(1, input[i])) * 0x7fff;\n        }\n        socket.current.send(buffer.buffer);\n      };\n    };\n\n    socket.current.onmessage = (event) => {\n      const message = JSON.parse(event.data);\n\n      if (message.type === \"Turn\") {\n        const { turn_order, transcript } = message;\n        turns[turn_order] = transcript;\n\n        const ordered = Object.keys(turns)\n          .sort((a, b) => Number(a) - Number(b))\n          .map((k) => turns[k])\n          .join(\" \");\n\n        setTranscripts({ ...turns });\n\n        if (ordered.trim()) {\n          const fieldConfig = kycFields[category][fieldKey];\n          setLastTranscript(ordered.trim());\n\n          // Clear existing timer\n          if (lastActivityTimer.current) {\n            clearTimeout(lastActivityTimer.current);\n          }\n\n          // Set timer to process after 3 seconds of no new transcript updates\n          lastActivityTimer.current = setTimeout(() => {\n            processWhenSilent(ordered.trim(), fieldConfig, fieldKey, category);\n          }, 3000);\n        }\n      }\n    };\nLLM-Powered Field Extraction\nWe use Cloudflare’s Llama 3.3-70B Instruct via a Worker for robust, prompt-based extraction:\n\nconst extractDataWithAI = async (transcript, fieldType, fieldKey) => {\n    const prompt = createPromptForField(transcript, fieldType, fieldKey);\n    const encodedPrompt = encodeURIComponent(prompt);\n    const apiUrl = ⁠ https://old-poetry-937f.sumeetweb.workers.dev/?prompt=${encodedPrompt} ⁠;\n\n    console.log(\"Making API call for\", fieldKey, \"with prompt:\", prompt);\n\n    try {\n      const response = await fetch(apiUrl);\n      const data = await response.json();\n\n      console.log(\"API response data:\", data);\n\n      if (data.success && data.response?.response) {\n        const extractedValue = data.response.response.trim();\n        console.log(\"Extracted value from API:\", extractedValue);\n        return extractedValue;\n      } else {\n        console.error(\"API response was not successful:\", data);\n        throw new Error(\"API response was not successful\");\n      }\n    } catch (error) {\n      console.error(\"API call failed:\", error);\n      return transcript;\n    }\n  };\nEnter fullscreen mode\nExit fullscreen mode\nPerformance Benchmarking\nEnd-to-end latency: consistently under 300ms from speech to field fill\nAnalytics: Usage, accuracy, and response times are tracked and visualized in AnalyticsPage.j\nTeam Submissions:\nnishikantaray\nsumeetweb\nayushmohanty24",
  "metadata": {
    "title": "KYC Admin Panel – Real-Time Voice KYC with AssemblyAI & Llama 3.3-70B - DEV Community",
    "description": "This is a submission for the AssemblyAI Voice Agents Challenge           What I Built   KYC Admin... Tagged with devchallenge, assemblyaichallenge, ai, api.",
    "keywords": "devchallenge, assemblyaichallenge, ai, api, software, coding, development, engineering, inclusive, community",
    "author": null,
    "og:type": "article",
    "og:url": "https://dev.to/nishikantaray/kyc-admin-panel-real-time-voice-kyc-with-assemblyai-llama-33-70b-3d7h",
    "og:title": "KYC Admin Panel – Real-Time Voice KYC with AssemblyAI & Llama 3.3-70B",
    "og:description": "This is a submission for the AssemblyAI Voice Agents Challenge           What I Built   KYC Admin...",
    "og:site_name": "DEV Community",
    "og:image": "https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvpn6rk7ecshifvdtyp5.png",
    "twitter:site": "@thepracticaldev",
    "twitter:creator": "@",
    "twitter:title": "KYC Admin Panel – Real-Time Voice KYC with AssemblyAI & Llama 3.3-70B",
    "twitter:description": "This is a submission for the AssemblyAI Voice Agents Challenge           What I Built   KYC Admin...",
    "twitter:card": "summary_large_image",
    "twitter:widgets:new-embed-design": "on",
    "twitter:image:src": "https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvpn6rk7ecshifvdtyp5.png"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/1e88b6ef4393/code/body-000.txt",
      "chars": 3369,
      "language": "text"
    }
  ],
  "images": [
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkvzbditzgd3axqrrkvf.png",
      "bytes": 46136,
      "reused": true,
      "local_path": "attachments/1e88b6ef4393/images/002.png",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkvzbditzgd3axqrrkvf.png",
      "alt": " ",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidphyeoh56h2vaq0rv02.png",
      "bytes": 12590,
      "reused": true,
      "local_path": "attachments/1e88b6ef4393/images/003.png",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidphyeoh56h2vaq0rv02.png",
      "alt": " ",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15ow8j7auowrf28mcavx.png",
      "bytes": 53058,
      "reused": true,
      "local_path": "attachments/1e88b6ef4393/images/004.png",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15ow8j7auowrf28mcavx.png",
      "alt": " ",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgic9rtde9d1x1rwtk79x.png",
      "bytes": 51572,
      "reused": true,
      "local_path": "attachments/1e88b6ef4393/images/005.png",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgic9rtde9d1x1rwtk79x.png",
      "alt": " ",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6snshdph8y7juilqrnt.png",
      "bytes": 54508,
      "reused": true,
      "local_path": "attachments/1e88b6ef4393/images/006.png",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6snshdph8y7juilqrnt.png",
      "alt": " ",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [
    {
      "url": "https://www.youtube.com/watch?v=GUWSwAg18DY",
      "status": "ok",
      "local_path": "attachments/1e88b6ef4393/videos/GUWSwAg18DY.mp4",
      "bytes": 6835024,
      "valid": true,
      "height": 1080,
      "width": 1728,
      "duration": "166.501000"
    }
  ],
  "links": [
    {
      "href": "https://dev.to/challenges/assemblyai-2025-07-16",
      "label": "AssemblyAI Voice Agents Challenge",
      "type": "a"
    },
    {
      "href": "https://youtu.be/GUWSwAg18DY?si=V_SOyv-kxNI9gayr",
      "label": "https://youtu.be/GUWSwAg18DY?si=V_SOyv-kxNI9gayr",
      "type": "a"
    },
    {
      "href": "https://assembly-ai-voice-agents-challenge.vercel.app/",
      "label": "https://assembly-ai-voice-agents-challenge.vercel.app/",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkvzbditzgd3axqrrkvf.png",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidphyeoh56h2vaq0rv02.png",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15ow8j7auowrf28mcavx.png",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgic9rtde9d1x1rwtk79x.png",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6snshdph8y7juilqrnt.png",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://github.com/NishikantaRay/AssemblyAI_Voice_Agents_Challenge",
      "label": "https://github.com/NishikantaRay/AssemblyAI_Voice_Agents_Challenge",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:49:56Z",
  "source_url": "https://dev.to/nishikantaray/kyc-admin-panel-real-time-voice-kyc-with-assemblyai-llama-33-70b-3d7h",
  "papers": [],
  "actual_video_files": [
    {
      "local_path": "attachments/1e88b6ef4393/videos/GUWSwAg18DY.mp4",
      "bytes": 6835024,
      "valid": true,
      "height": 1080,
      "width": 1728,
      "duration": "166.501000",
      "status": "ok"
    }
  ],
  "body_chars": 4549,
  "expected_body_images": 5,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/1e88b6ef4393/pages/source.html",
  "local_html": "attachments/1e88b6ef4393/pages/article.html",
  "body_base_path": "attachments/1e88b6ef4393/pages/",
  "body_markdown_path": "attachments/1e88b6ef4393/pages/article.md"
}