×
Community Blog 실시간 멀티모달 AI Agent 구축하기

실시간 멀티모달 AI Agent 구축하기

알리바바클라우드의 빌트인 솔루션을 조합하여 리얼타임 멀티모달 AI AGENT를 적은 시간 투입과 저비용으로 간편하게 구축하여 실 워크로드에 투입할 수 있는 방법에 대한 구축가이드를 살펴봅니다.

실시간 멀티모달 AI Agent 구축하기



실시간 멀티모달 AI Agent의 활용범위

실시간 멀티모달 에이전트가 활용될 수 있는 분야는 거짓말을 약간 섞자면 인간이 활동하는 모든 범주에 있다고 말을 하여도 과언이 아니다. 우리가 종종 전화를 거는 AI 콜센터, 자율주행 자동차의 드라이빙 어시스턴트, 스마트폰의 어시스턴트, 안내데스크 에이전트 등 매일 인터페이스 하는 공간에 모두 적용될 수 있으며, 기술의 발전이 도입을 압박하는 수준에 이르렀다고 말해도 과언이 아니다. 사람과 대면하는 데에 가장 필수적인 요소는 인간의 언어와 감정의 이해, 사물에 대한 이해도, 인간과 유사한 형태의 발화 능력, 일반적인 지식에 대한 이해 및 특정 도메인 지식에 대한 전문적 이해도, 빠른 처리속도, 낮은 엔드투엔드 레이턴시, 해야할 말과 해서는 안되는 말에 대한 가드 및 필터링 등 도입에 필요한 모든 기술요소들의 빈 공간이 거의 다 채워져 가고 있고 이제는 사회적 합의와 수용만이 남아 있는 단계에 와 있다.

실시간 멀티모달 AI Agent 도입의 주역

이러한 변화의 주역에는 클라우드 공급업체가 선봉에 있다. 아무리 완벽한 AI 모델이라도 인간과의 교감 속도가 현저히 떨어진다면 그것은 무인도에 존재하는 한낱 비디오 재생기에 불과하다. 인간의 눈 앞에서 정보를 받아들여 가장 근거리의 AI 모델에게 정보를 전달하고 연산하여 다시 응답을 할 수 있는 기술을 낮은 비용과 가장 적은 병목을 거치는 기술은 클라우드만이 제공할 수 있다.

알리바바 클라우드는 컴퓨팅, 네트워크, 엣지 인프라, AI 모델, AI 훈련/추론 인프라 등 모든 솔루션 별 마켓 탑클래스의 성능으로 보유하고 있는 유일한 클라우드 서비스 공급자이다. 그 중심에는 범용의 정보, 범용의 도메인, 범용의 인더스트리에 탁월한 Qwen AI 모델이 자리하고 있으며, 실생활에 AI 모델이 사용될 수 있도록, 듣고, 보고, 이해하고, 생각하고, 배우고, 전달하는 모든 영역에 필요한 모델 시리즈를 지속적으로 출시하고 있다.

Qwen 베이스 모델

Qwen-plus
채팅 베이스의 어플리케이션에서 가장 범용적으로 활용될 수 있는 Qwen3의 플래그쉽 모델이며, API 호출을 할 때 모델명으로 qwen-plus 라고 입력한다. 성능과 속도, 그리고 비용을 다 잡은 육각형 타입의 챗 모델이다. 맥시멈 컨텍스트 윈도우는 1,000,000 토큰이며, 100만 토큰당 인풋:아웃풋 가격은 $0.4:$1.2 로서 주류 AI 모델 중에서 가장 저렴하면서도 최상위 군류의 성능을 제공한다. 가볍고 복잡하지 않은 어플리케이션에는 qwen-flash 모델을 추천하며, 100만 토큰당 인풋:아웃풋 $0.05:$0.4 가격으로 사용할 수 있다.

오디오 AI 모델

Qwen3-asr-flash-realtime
라이브스트리밍, 음성채팅, 스마트 어시스턴트의 어플리케이션이 발생하는 음성을 인터페이스하는 상황에서 필수적으로 사용이 되는 Acoustic Speech Recognition 모델이다. 오디오 스트림을 텍스트로 실시간으로 인식하여 바로 표기하거나, 당 텍스트를 다음 워크플로우 노드로 전달되는 것이 주된 사용처이다.

알리바바의 Tongyi Lab에서 고도의 음성학 기술을 기반으로 훈련된 모델로서, 중국어, 영어, 한국어, 일본어, 스페인어, 베트남어, 아랍어 등 전세계 주류 언어의 음성을 이해하며, 문맥과 감정에 대한 이해를 바탕으로 정확도가 높은 음성 컨텍스트를 포착하여 텍스트화 한다.

pcm, opus 오디오 포맷으로 디텍션하며, 샘플링 레이트는 8000 Hz, 16000 Hz을 지원하고 있다.

현재 알리바바클라우드의 모델스튜디오에서 API 콜 형태로 인터페이스를 제공하고 있다. Websocket API로 콜을 수행하여 콜백을 받거나, 알리바바클라우드에서 개발한 DashScope SDK를 임포트하여 사용할 수 있다.

풀 코드 : https://modelstudio.console.alibabacloud.com/?console-base_search-panel.dtab-product_sfm.1fd4QmVmQmVmUA&tab=doc#/doc/?type=model&url=2989727


Qwen3-tts-flash-realtime
AI 모델에게 음성을 발화하는 기능을 부여한 Text-to-Speech 모델이다. 다국어 언어와 방언을 발화할 수 있어, 한국어 뿐만 아니라 텍스트로부터 영어, 중국어, 일본어, 러시아어 등으로 음성을 생성해야 하는 어플리케이션에 유용하게 적용시킬 수 있다.

변환된 음성 결과물 10,000개 문자 기준 $0.1로 과금이 되며 (한국어와 중국어, 일본어의 1글자는 2문자로 계상), wav와 pcm 파일 포맷으로 생성된다. (스트리밍 아웃풋의 경우에는 Based64 인코딩 된 pcm 파일 포맷으로 생성. )

리얼타임 플레이백을 지원하는 파이썬 API 코드의 예시는 다음과 같다.

import os
import dashscope
import pyaudio
import time
import base64
import numpy as np

# This is the URL for the Singapore region. If you use a model in the China (Beijing) region, replace the URL with: https://dashscope.aliyuncs.com/api/v1
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'

p = pyaudio.PyAudio()
# Create an audio stream
stream = p.open(format=pyaudio.paInt16,
                channels=1,
                rate=24000,
                output=True)


text = "Today is a wonderful day to build something people love!"
response = dashscope.MultiModalConversation.call(
    # API keys for the Singapore and China (Beijing) regions are different. To get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # If you have not configured an environment variable, replace the following line with your Model Studio API key: api_key = "sk-xxx"
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    model="qwen3-tts-flash",
    text=text,
    voice="Cherry",
    language_type="English", # We recommend that this matches the text language to ensure correct pronunciation and natural intonation.
    stream=True
)

for chunk in response:
    if chunk.output is not None:
      audio = chunk.output.audio
      if audio.data is not None:
          wav_bytes = base64.b64decode(audio.data)
          audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
          # Play the audio data directly
          stream.write(audio_np.tobytes())
      if chunk.output.finish_reason == "stop":
          print("finish at: {} ", chunk.output.audio.expires_at)
time.sleep(0.8)
# Clean up resources
stream.stop_stream()
stream.close()
p.terminate()

모델스튜디오 Qwen-tts 지원 음성 샘플 : https://www.alibabacloud.com/help/en/model-studio/qwen-tts


Vision AI 모델

Qwen3-VL
Qwen3의 기본 역량을 바탕으로 이미지 또는 비디오를 기반으로 질문에 답변하는 모델이다. 다중 이미지 입력을 지원하며 이미지 캡션 생성, 시각적 질문 답변, 객체 감지 등 다양한 작업에 활용된다. 이미지에 대한 인식 뿐 아니라, 문서 내의 이미지,테이블 인식을 위한 OCR 기능, 비디오의 구간별 이해 등을 하나의 모델로 처리할 수 있다. 모든 Qwen3 모델에 공통으로 적용되는 Thinking / Non-Thinking Hybrid 모드 역시 유연하게 지원한다. 이 외에도 다양한 기능과 옵션들이 있으므로 아래 링크에서 참조할 수 있다.
https://modelstudio.console.alibabacloud.com/?console-base_search-panel.dtab-product_sfm.1fd47b6bEoi3hK&tab=doc#/doc/?type=model&url=2845871

OpenAI 호환 또는 Dashscope 라이브러리를 Python, Node.js, Java 등의 언어로 호출할 수 있으며, 샘플 코드는 아래와 같다.

import os
from openai import OpenAI

client = OpenAI(
    # The API keys for the Singapore and China (Beijing) regions are different. To obtain an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    # The following base_url is for the Singapore region. If you use a model in the China (Beijing) region, replace the base_url with https://dashscope-intl.aliyuncs.com/compatible-mode/v1
    base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)

completion = client.chat.completions.create(
    model="qwen3-vl-plus",  #  This example uses qwen3-vl-plus. You can replace the model name as needed. For a list of models, see https://www.alibabacloud.com/help/model-studio/getting-started/models
    messages=[
        {"role": "user","content": [
            {"type": "image_url","image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"},},
            {"type": "image_url","image_url": {"url": "https://dashscope.oss-cn-beijing.aliyuncs.com/images/tiger.png"},},
            {"type": "text", "text": "What do these images depict?"},
            ],
        }
    ],
)

print(completion.choices[0].message.content)


Wan 모델
Wan 모델은 알리바바 클라우드의 이미지/비디오 이해 및 생성을 위해 개발된 프랜차이즈 모델로서, 범용적으로 활용되는 이미지/비디오 이해 및 편집 기능을 지원할 뿐만 아니라, 텍스트로부터 이미지 또는 비디오 영상을 프로페셔널 레벨로 생성한다.

2025년 12월 17일에 Wan 2.6 버전을 공식 런칭함으로써, Text-to-Image, Text-to-Video(With Audio), Image-to-Image, Image-to-Video(with Audio), Reference-to-Video, Speech-to-Video 등 이미지와 비디오 생성에 필요한 모든 시나리오를 오디오와 함께 지원하는 세계 유일한 베스트-인-클래스 모델이다. 다음 페이지에서 상세 설명을 참고할 수 있다.
https://wan.video/



AI 에이전트 인터렉션 제로코딩 플랫폼

대화형 AI Agent를 구축할 때 고민해야 할 문제 중 하나는, 인프라 셀프 구축과 클라우드에서 제공하는 서비스의 사용 범위를 어디까지 가져가느냐일 것이다. AI 모델만 제공하는 업체로부터 시작한다면, 테스트 워크플로우와 샌드박스를 구축하는 것은 VM 1,2개 머신, 퍼블릭 IP 1,2개의 구성으로 구현이 가능하지만, 실재 프러덕션에서 서비스를 운용하기 위해서는, 클라우드 서비스 프로바이더의 검증된 워크플로우 기반 인프라를 이용하는 것이 초기 서비스 런칭의 가속화 및 추후 규모 있는 시스템으로의 확장에 큰 도움을 받을 수 있다.

다만, 기업의 CTO, CEO 입장에서는 특정 CSP로의 락업이 되어 고가의 요금 청구를 감당해야 하는 불합리한 상황에 처할 수 있기에 밑바탕 부터 직접 구현하여 독립성을 높이는 작업에 불필요한 시간낭비를 하는 경우가 흔하다. 이러한 고민을 알리바바 클라우드를 사용할 경우에는 없앨 수 있는 것이, AI 모델을 저렴하게 사용할 수 있을 뿐 아니라 관련 인프라 서비스 비용을 타 클라우드 대비 최소 20~30% 이상 저렴하게 가져갈 수 있기 때문이다. 그러면 바로 AI 에이전트 기동을 위한 워크플로우를 디자인 해 보고 AI Agent 서비스를 런칭해보자.

워크플로우 템플릿
알리바바 클라우드에서는 AI 에이전트와 상호작용을 하는 과정을 인간과 대화하는 과정에 비유하여 종류별 Call에 대한 워크플로우 템플릿을 제작하였다. 상호작용하는 매개의 종류에 따라서 Audio Call, Avatar Call, Vision Call, Messaging call, Video Call 의 워크플로우 템플릿을 제공하여, 워크플로우를 선택함으로서 각 모듈별 AI모델 및 인제스트와 스트림에 필요한 모든 인프라를 빠르게 구현한다. 이번 예시에서는 콜센터나 채팅 어시스턴트에서 널리 사용되는 오디오 콜 템플릿을 예시로 보겠다.
audio_workflow_template

주목해야 할 부분은 Start와 End Node에 구현이 되어 있는 RTC Input과 RTC Output 이다. RTC는 Real-time Communication의 약자로서 간단히 말하면 CDN 엣지 노드에 구성된 스트림 인풋과 스트림 아웃풋 채널이라고 보면 된다. AI 앱을 런칭하여 초기에 한국에서만 서빙해야 한다면 고민하지 않는 부분이지만, 추후 국가 내에서 원거리 또는 글로벌 리전으로 서빙 대상 클라이언트가 확장이 된다면, 음성 또는 비디오를 인풋 송출해야 하는 경우 최소한의 레이턴시로 컨텐츠를 전송하지 않으면 어플리케이션은 가치를 상실한다. 미디어 컨텐츠 영역에서 장기간 다수의 고객에게 솔루션을 제공해 본 CSP인 알리바바 클라우드이기에 그 필요성을 알기에 솔루션으로 구현해 놓았다.

audio_flow_stt
Speech-to-Text 노드의 설정 항목이다. 템플릿에서 제공하는 Preset 모델 (Qwen3-asr) 또는, 별도의 외부 모델을 사용을 위한 Third-party Plug-in 옵션을 제공한다.

audio_workflow_llm
LLM 노드는 ASR 노드로부터 전달받은 텍스트에 대한 응답을 생성하는 역할을 수행한다. 프리셋 설정으로 간편하게 설정을 마무리하거나, 알리바바 클라우드의 모델스튜디오에서 제공하는 모델id (i.e. qwen-plus)와 API-Key를 사용하여 호출하는 방식, 또는 ChatGPT, OpenAI 규격의 자체서버에서 구동중인 모델을 호출하여 사용할 수도 있다.

실 어플리케이션에 적용 시에는 웹이나 앱 어플리케이션의 음성 인터페이스를 통해 ASR을 수행하고, 인식된 텍스트를 LLM 노드에 전달하여 LLM이 의도하는 비지니스 시나리오에 적절한 응답을 생성한다. LLM에 의해 생성된 응답 텍스트를 그대로 클라이언트에게 텍스트 포맷으로 출력하거나, Text-to-Speech 노드에서 음성 합성을 수행하여 전달할 수 있다. LLM 노드의 모델로는 범용으로 활용되는 Qwen-Plus 모델을 적용한다.

실재 사람과 대화하는 듯한 느낌을 부여하기 위해서 LLM 노드는 TTS 노드로 생성 응답을 전달한다. TTS(Text-to-Speech) 모델을 사용하면, 전세계 주요 국가에서 사용되는 보이스 언어를 다양한 캐릭터 톤으로 발화시킬 수 있다. 다국적의 고객을 응대하는 AICC (AI 콜센터), 멀티 리전에서 사업을 영위하는 인터네셔널 컴퍼니에서 필수적으로 사용되는 기술이다.

최종적으로 생성된 답변은 클라이언트 디바이스에 PCM 포맷으로 가장 가까운 엣지노드의 리시버로 전달하여 플레이백 할 수 있도록 한다.

AI 에이전트
워크플로우는 AI 인프라와 모델 엔진을 생성하는 과정이라 이해하면 편하다. 인프라를 준비하였으므로 이 인프라를 이용할 AI 에이전트를 생성한다. 생성절차는 간단하다. 위 절차에서 생성한 Audio Workflow를 선택 후, Realtime Communication Channel로 네트워크 가속을 사용하기 위하여 ARTC Application을 생성 후 입력한다.

AIAGENT_VOICE

ARTC application 생성을 클릭하면 ApsaraVideo Realtime Communication 콘솔로 이동하며, 초기 생성비용없이 Apsarvideo Live 플랫폼에서 제공하는 오디오/비디오 네트워크 가속플랫폼을 빠르게 구현할 수 있다. 별도 인제스트/아웃풋 도메인 설정이 필요없으며 Apsaravideo 플랫폼에서 기 구축해 놓은 네트워크 망을 임차한다고 보면 된다.

artc_audio
어플리케이션을 생성후에 별도 해야할 작업은 없으며, Application ID와 AppKey를 노트해둔다.

다시, IMS-AI AGENT로 돌아서 생성한 ARTC APPLICAITON을 선택하며, 추가로 Audio call Agent의 환영인사말 문구와 에이전트의 이미지를 업로드하여 커스터마이제이션 할 수 있다.

Self-Developed 모델 액세스를 위한 Standard API
IMS는 사용자의 편의성을 위하여 Preset Qwen 모델 외에도 사용자가 자체 개발한 모델로의 엑세스를 지원한다. LLM, MLLM (Multi-Modal LLM), TTS 모델 액세스를 위한 Standard API를 제공하고 있다. 개 중 가장 구현 난이도가 높은 TTS 모델의 맞춤 구성을 위하여 자체 구축 TTS 모델을 호출하는 서버 구축 예시를 보고자 한다.

https://www.alibabacloud.com/help/en/ims/user-guide/tts-configuration?help-menu-193643.d_2_8_5_4_2.447b74ccv610Zq

IMS 콘솔에서 템플릿을 제공하고 있으며, 필요 입력 정보는 TTS Server의 URL과 Port 정보이다. LLM 노드에서 텍스트 응답 데이터는 POST Request에 조립되어 자체 구축 TTS 서버의 HTTPS URL로 전달되므로 이에 맞게 서버를 세팅해주면 된다.

공식 Document 에서 제공하고 있는 파이썬 TTS 서버의 샘플 코드는 다음 링크에서 확인할 수 있으며, (https://www.alibabacloud.com/help/en/ims/user-guide/tts-configuration?help-menu-193643.d_2_8_5_4_2.447b74ccv610Zq), 본 데모에서는 편의성을 위하여 해당 코드를 일부 수정하였다.

import os
import dashscope
import base64
from aiohttp import web
import asyncio
import json
import ssl

# Set the base HTTP API URL for the Singapore region
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
print("DashScope base URL set to: https://dashscope-intl.aliyuncs.com/api/v1")

async def stream_audio(request):
    """
    Handle POST request to generate TTS and stream PCM audio data
    """
    print("=== NEW REQUEST ===")
    print("Received POST request to /stream-audio endpoint")
    print(f"Request details: {request.method} {request.path}")
    print(f"Request headers: {dict(request.headers)}")
    
    try:
        # Parse JSON data from request
        print("Parsing JSON data from request")
        data = await request.json()
        print(f"Raw request data: {data}")
        
        text = data.get('Text', "")
        token = data.get('Token', None)
        sample_rate = data.get('SampleRate', 48000)  # Default to 24000 for qwen3-tts-flash
        voice = data.get('Voice', 'Cherry')
        language_type = data.get('LanguageType', 'Korean')
        
        print(f"Request parameters - text:{text}, token:{token}, sample_rate:{sample_rate}, voice:{voice}, language:{language_type}")
        
        # Validate required parameters
        if not text:
            print("No text provided in request")
            response_obj = web.Response(
                status=400,
                text=json.dumps({"error": "Text parameter is required"}),
                content_type='application/json'
            )
            return response_obj

        # Prepare streaming response
        print("Preparing streaming response with audio/pcm content type")
        response = web.StreamResponse(
            status=200,
            reason='OK',
            headers={'Content-Type': 'audio/pcm'}
        )

        # Start the response
        print("Starting HTTP response")
        await response.prepare(request)
        print("HTTP response prepared successfully")

        # Call Qwen3 TTS service
        print("Calling Qwen3 TTS service with model=qwen3-tts-flash")
        print(f"TTS parameters: text='{text}', voice='{voice}', language_type='{language_type}'")
        
        tts_response = dashscope.MultiModalConversation.call(
            api_key='sk-***',
            model="qwen3-tts-flash",
            text=text,
            voice=voice,
            language_type=language_type,
            stream=True
        )
        print("TTS service call initiated successfully")

        # Stream audio chunks as they arrive
        chunk_count = 0
        total_bytes = 0
        print("Starting to process TTS response chunks")
        
        for chunk in tts_response:
            chunk_count += 1
            print(f"Processing chunk #{chunk_count}")
            
            if chunk.output is not None:
                print(f"Chunk #{chunk_count}: output is not None")
                audio = chunk.output.audio
                finish_reason = getattr(chunk.output, 'finish_reason', 'N/A')
                print(f"Chunk #{chunk_count}: output details - finish_reason={finish_reason}")
                
                if audio.data is not None:
                    print(f"Chunk #{chunk_count}: audio data found")
                    # Decode base64 audio data
                    try:
                        wav_bytes = base64.b64decode(audio.data)
                        chunk_size = len(wav_bytes)
                        total_bytes += chunk_size
                        print(f"Chunk #{chunk_count}: decoded {chunk_size} bytes, total: {total_bytes} bytes")
                        
                        # Send audio chunk
                        await response.write(wav_bytes)
                        print(f"Chunk #{chunk_count}: sent {chunk_size} bytes to client")
                    except Exception as decode_error:
                        print(f"Chunk #{chunk_count}: Failed to decode base64 audio data: {str(decode_error)}")
                        print(f"Chunk #{chunk_count}: Audio data length: {len(audio.data) if audio.data else 0}")
                else:
                    print(f"Chunk #{chunk_count}: audio.data is None")
                    
                if chunk.output.finish_reason == "stop":
                    print(f"TTS generation completed. Processed {chunk_count} chunks, total {total_bytes} bytes")
                    break
                elif hasattr(chunk.output, 'finish_reason'):
                    print(f"Chunk #{chunk_count}: finish_reason={chunk.output.finish_reason}")
            else:
                print(f"Chunk #{chunk_count}: chunk.output is None")

        # Complete the response
        print("Completing HTTP response")
        await response.write_eof()
        print("HTTP response completed successfully")
        print("=== REQUEST COMPLETED ===")
        return response
        
    except json.JSONDecodeError as e:
        print(f"Invalid JSON in request: {str(e)}")
        print("Request body that caused error: %s", await request.text())
        error_response = web.StreamResponse(
            status=400,
            reason='Bad Request',
            headers={'Content-Type': 'application/json'}
        )
        await error_response.prepare(request)
        error_msg = json.dumps({"error": "Invalid JSON in request"}).encode()
        await error_response.write(error_msg)
        await error_response.write_eof()
        print("Error response sent to client")
        return error_response
    except Exception as e:
        print(f"Exception occurred during TTS processing: {str(e)}")
        import traceback
        print(f"Traceback: {traceback.format_exc()}")
        # Handle errors
        error_response = web.StreamResponse(
            status=500,
            reason='Internal Server Error',
            headers={'Content-Type': 'application/json'}
        )
        await error_response.prepare(request)
        error_msg = json.dumps({"error": str(e)}).encode()
        await error_response.write(error_msg)
        await error_response.write_eof()
        print("Error response sent to client")
        return error_response

# Create application and routes
print("Creating aiohttp web application")
app = web.Application()
app.add_routes([web.post('/stream-audio', stream_audio)])
print("Route /stream-audio added to application")

@app.on_startup.append
async def on_startup(app):
    print("Application startup completed")

@app.on_shutdown.append
async def on_shutdown(app):
    print("Application shutdown initiated")

if __name__ == '__main__':
    print("Starting TTS server on localhost:8443")
    print(f"Server PID: {os.getpid()}")
    # Run the server
    ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    ssl_context.load_cert_chain('/ssl/cert.pem', '/ssl/cert.key')
    #ssl_context = ('/ssl/cert.pem', '/ssl/cert.key')  # Replace with your actual certificate paths
    web.run_app(app, ssl_context=ssl_context)
    print("TTS server started successfully")


리얼타임 콜 테스트

알리바바 클라우드에서는 빠른 어플리케이션 구축을 지원하고자 깃허브에서 간단한 어플리케이션 클라이언트와 서버 프로그램을 제공한다.
https://github.com/MediaBox-AUIKits/AUIAICall

프로그램의 구성은 Java 환경의 서버와 클라이언트 (iOS, Android, Web) 로 제공되며, 템플릿의 몇 가지 변수를 입력한 후에, 서버프로그램은 알리바바클라우드의 ECS에, 클라이언트는 사용자의 PC에서 웹 프로그램으로 수행한다.

서버 구동
다음 가이드에 의해서 서버 프로그램이 IMS에 액세스 할 수 있도록, application.yaml의 biz 탭에 RAM USER의 Access Key와 Secret을 입력한다.
https://github.com/MediaBox-AUIKits/AUIAICall/tree/main/Server/Java

server:
  port: 8080

spring:
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd'T'HH:mm:ss
    default-property-inclusion: non_null

# 参考 https://help.aliyun.com/zh/ims/user-guide/app-server-reference, 不需要的配置保留*******即可
biz:
  # 阿里云AK、SK,参考 https://help.aliyun.com/zh/ram/user-guide/create-an-accesskey-pair。 创建RAM用户时,最小权限为AliyunICEFullAccess
  openapi:
    # 调用generateMessageToken 获取chatBot token时需要配置
    # 调用describeAIAgentInstance 获取智能体信息时需要配置
    access:
      key: "****************"
      secret: "************************"

  # 实时音视频应用ID和AppKey,通话场景下需要配置
  live_mic:
    app_id: ""
    app_key: ""

http:
  cors:
    host: "*"

수정한 어플리케이션 파일을 mvn으로 패키지하여 ECS위에 구동시킨다.

#!/usr/bin/env bash

mvn package -DskipTests
cp target/*.jar target/webframework.jar
java -Dserver.port=9000 -jar target/webframework.jar

java_server_boot

웹 클라이언트 구동
웹클라이언트는 React 환경에서 typescript로 구성되어 있다.
( https://github.com/MediaBox-AUIKits/AUIAICall/tree/main/Web/React )

/Web/React/src/runConfig.ts 에서 클라이언트가 호출할 appServer 주소(위 생성한 Java 서버), 그리고 클라이언트의 React 인터페이스가 호출할 IMS에서 생성한 voiceAgent의 ID를 입력한다.

import { AICallAgentConfig } from 'aliyun-auikit-aicall';

import { AICallRunConfig } from '@/interface.ts';

// 如果需要自定义 AgentConfig,请参考以下写法
// when you need to customize AgentConfig, please refer to the following code

const callAgentConfig = new AICallAgentConfig();
// callAgentConfig.agentGreeting = 'Custom Greeting';

const runConfig: AICallRunConfig = {
  region: 'ap-southeast-1',
  // 应用服务器地址,格式示例 https://xxxx.domain.com
  // Your Application Server Address
  appServer: 'http://8.2.2.2:9000',

  // 您的语音通话智能体id
  // Your Voice Agent Id
  voiceAgentId: '7fda013f09464827a9144a3befb2ad95',
  
  // 您的数字人智能体id
  // Your Avatar Agent Id
  avatarAgentId: 'b5cf1dd8d9be4843ab8602692c3ff11a',
  
  // 您的视觉智能体id
  // Your Vision Agent Id
  visionAgentId: '5a6fb3c71bda4faf865bca00918d0c92',
  
  // 您的视频通话智能体id
  // Your Video Agent Id
  videoAgentId: '70ae3d527be24fb4ae9e2879f9b6c24d',

  // 您的消息通话智能体id
  // Your Chat Agent Id
  chatAgentId: '70ae3d527be24fb4ae9e2879f9b6c24d',

  callAgentConfig: callAgentConfig,
};

export default runConfig;

설치한 클라이언트의 /AUIAICall-main/Web/React/src 디렉토리에서 'npm run dev' 커맨드로 로컬호스트에 클라이언트를 구동하여 브라우저에서 연다.

react_client_run

기동된 브라우저 앱에서는 AI Voice call, Avatar Call, Vision Call 등의 UI가 준비되어 있으며, IMS의agentID 가 등록되어 있으면 바로 사용할 수 있다.

AI Voice call의 입장화면이며, 타입스크립트를 수정하여, 입장시, 들을때, 말할때, 감정표현 등의 애니메이션을 json과 이미지 파일을 조합하여 사용가능하다. 에이전트에게 말을 건네면 텍스트로 인식하여 사용자가 지정한 음성으로 답변을 하는 과정이 매우 낮은 레이턴시로 수행되는 것을 확인할 수 있다.



아바타 콜
아바타 콜은 IMS에서 Avatar Call Workflow를 생성할 때 플러그인을 입력하면 사용할 수 있다. 현재 지원하는 플러그인은 시중에서 판매되는 FaceUnity (https://www.faceunity.com/en) 의 플러그인과, 알리바바 클라우드에서 제공하는 아바타 플러그인을 임베딩 하여 사용할 수 있다. 아래 예시는 알리바바 클라우드의 LingJing 아바타 플러그인을 사용한 예시이며, 플러그인 구입에 대한 문의는 메일 주소로 연락 바랍니다.


마치며

이 외에도 Vision Call, Video Call 등의 시나리오에서 적용 예시가 있으며, 실 서비스 환경에서 고객사의 환경에 필요 에이전트를 호출하여 간단하게 구현할 수 있다. 여러분이 계획중인 이커머스 플랫폼, 라이브쇼 등에 리얼타임 디지털 휴먼 에이전트를 단 하루의 시간으로 도입하여, 24시간 무중단 운영하는 에이전트로 고객의 접점을 넓히는데 AI를 적극 활용하시기를 바랍니다.

• 사용방법 및 비지니스 협업에 대한 질문은 메일로 바랍니다 : junho.l@alibaba-inc.com

0 0 0
Share on

James Lee

9 posts | 0 followers

You may also like

Comments

James Lee

9 posts | 0 followers

Related Products