Page History
...
| Widget Connector | ||||||
|---|---|---|---|---|---|---|
|
영상요약
이 컨텐츠는 agentic ai 서비스를 프로덕션 환경에서 산업화하고 확장 가능하며 탄력적으로 만드는 방법에 대한 실용적인 접근 방식을 제시합니다. LLM의 한계를 극복하고 내구적인 실행, 오케스트레이션, 메모리 관리를 통해 실제 사용 사례에 적용하는 방법을 코드 데모와 함께 보여줍니다.
1. 발표 소개 1
발표자는 Alan이며, akka의 수석 솔루션 아키텍트이다. 13
오늘의 주제는 agentic ai에 대한 내용이다. 8
발표자는 어제 Duncan의 발표를 간단히 요약할 예정이다. 12
2. AI의 현재와 필요성 15
AI는 우리의 삶을 변화시키고 있으며, AI 어시스턴트는 자연어를 이해하고 대화형으로 작업을 해결하는 데 도움을 준다. 15
AI의 장점을 활용하기 위해서는 프로세스를 자동화할 필요가 있으며, 이를 위해 AI 에이전트가 필요하다. 18
LLM(대형 언어 모델)은 정적 지식을 가지고 있으며, 상태를 유지하지 않기 때문에 대화 기록을 관리할 수 없다. 20
LLM은 비결정적이며, 현재는 처리량이 낮고 비용이 많이 든다.
3. 소프트웨어 엔지니어링 원칙 27
프로세스를 최적화하기 위해 소프트웨어 엔지니어링 원칙과 솔루션을 사용해야 한다. 28
Agentic 서비스는 LLM의 지식을 확장하고, 다양한 도구를 호출할 수 있는 패턴을 제공한다. 29
4. Agentic 서비스의 특징 31
Agentic 시스템은 대화 세션을 관리하고, 실패를 수용해야 한다. 31
시스템 설계 시 실패를 모델링하는 것이 중요하다. 32
5. Agentic 서비스의 패턴 34
RAG(검색 증강 생성): LLM에 추가 정보를 검색하여 보완하는 패턴이다. 35
워크플로우: 정적 패턴으로, LLM이 비즈니스 프로세스를 조정하지 않는다. 37
에이전트: 동적 패턴으로, LLM이 조정을 수행한다. 39
6. 산업화의 요구사항 49
산업화된 시스템을 만들기 위해서는 보안, 확장성, 복원력, 관찰 가능성에 집중해야 한다. 49
에이전트 생애 주기를 관리하고, 자동으로 확장할 수 있어야 한다. 52
7. 오케스트레이션과 상태 관리 60
오케스트레이션은 상태를 유지하는 패턴을 구현해야 하며, 각 단계의 실행을 저장해야 한다. 60
통신의 느림을 고려하여 이를 처리할 수 있는 방법이 필요하다. 72
8. akka의 솔루션 76
akka는 AI 전문가가 아니지만, 10년 이상 분산 시스템을 구현해왔다. 76
akka는 내구성 있는 실행을 위한 플랫폼을 제공하며, 개발자에게 SDK를 통해 다양한 구성 요소를 제공한다. 84
9. 첫 번째 사용 사례: 인스턴스 해결 시스템 101
고객의 인스턴스 해결 시스템을 예로 들어, 결제 시스템에서 발생한 문제를 LLM을 통해 해결하는 방법을 설명한다. 101
LLM은 시스템 프롬프트와 대화 기록을 사용하여 문제를 해결하고, 필요한 도구를 호출한다. 108
10. 두 번째 사용 사례: RAG 기반 챗봇 217
내부 문서에 대한 질문을 처리하는 챗봇을 구현하는 방법을 설명한다. 219
시스템 프롬프트와 대화 기록을 사용하여 사용자 질문에 답변한다. 226
11. 세 번째 사용 사례: 실시간 비디오 271
미국 수화 인식 시스템을 실시간으로 구현하는 방법을 설명한다. 271
비디오 스트리밍과 LLM을 결합하여 실시간으로 피드백을 제공한다. 274
1. 🤖 에이전틱 AI 서비스의 산업화
에이전틱 AI 서비스의 산업화를 위해서는 생산으로의 전환에 필요한 요구사항과 청사진이 중요하다 11.
AI 기술은 우리의 삶을 변화시키고 있으며, AI 어시스턴트는 자연어를 이해하고 대화형으로 작업을 해결하는 역할을 한다 15.
LLM(대형 언어 모델)은 정적인 일반 지식을 가지고 있으며, 상태가 없고 비결정적이어서 세션 대화 기록을 유지할 수 없다 20.
...
특정 콘텐츠를 통한 챗봇 어시스턴트 구축 사례를 다룬다. 이 경우, 공공 정보 대신 비공식 정보를 사용하여 오픈 정보를 제공하지 않아야 한다. [218]
사용자 요청에 따라 문서에서 정보를 검색하기 위해서는 전문적 데이터베이스와 대화 기록을 포함한 자원을 제공해야 하며, 이에 대한 시스템 프롬프트가 필요하다. [225]
임베딩을 통해 프롬프트를 향상시키고, 사용자의 요청을 수용할 수 있는 에이전트를 구축하여 산출과 리턴을 관리한다. [230]
각 세션에 대해 인메모리 데이터베이스 인스턴스를 유지하고, 요청 및 응답을 스트리밍할 수 있는 HTTP 스트리밍 엔드포인트를 설정한다. [237]
구축한 챗봇 'Ask AKAakka'를 통해 정보 검색을 수행하는 실습을 진행하며, 제한된 정보에 대한 요청이 있을 경우 적절한 응답을 제공하기 어려운 상황을 시뮬레이션한다. [240]
...
프로덕션 그레이드 플랫폼이 필요하며, AI 패턴을 구현하기 위해 서로 다른 도구를 사용할 수 있어야 한다. [301]
실패를 수용하고, 실패를 모델링해야 하며, 플랫폼이 해결해야 할 회복력의 수준을 고려해야 한다. [304]
24-48시간 내에 개념 증명을 제공하며, 흥미로운 사례가 있다면 연락하라고 권장한다. [307]
백프레셔는 사용하는 스트리밍 라이브러리 내에서 구축되며, 여러 상태 기반 클라이언트를 통해 요청을 큐잉할 수 있다. [312]
LLM이 응답을 바탕으로 호출해야 할 도구를 오케스트레이션하며, 이를 통해 동적 실행이 가능하다. [347]
보너스
이 동영상의 내용중 AkkaStream과 GRPC와 연동하는 순수 코드 구현체만 따로 코드생성 시도해보았습니다.
GTPC와 연결된 AkkaStream를 통해 액터모델 상태관리를 하는 느낌정도 살펴볼수 있습니다.
| Info |
|---|
akka stream을 이용 grpc와 상호연동하면서 llm을 이용하는 샘플코드작성 |
🧩 목표 아키텍처
| Code Block | ||
|---|---|---|
| ||
gRPC Server (LLM Proxy)
▲
│ ← Akka Stream (Source.queue → Flow → Sink)
│
Pekko Actor (LLMProcessorActor)
▲
│ ← HelloActor / Router 에서 메시지 전달
│
Client (gRPC 요청 송신자)
|
1. gRPC 프로토 정의 (예: llm.proto)
| Code Block | ||
|---|---|---|
| ||
syntax = "proto3";
service LLMService {
rpc Ask (LLMRequest) returns (LLMReply);
}
message LLMRequest {
string prompt = 1;
}
message LLMReply {
string response = 1;
} |
2. LLM Stream Client 구성 (LLMClientStream.kt)
| Code Block | ||
|---|---|---|
| ||
package org.example.grpc
import org.apache.pekko.stream.javadsl.*
import org.apache.pekko.stream.OverflowStrategy
import org.apache.pekko.actor.typed.ActorSystem
import org.apache.pekko.Done
import java.util.concurrent.CompletionStage
class LLMClientStream(system: ActorSystem<*>, private val grpcStub: LLMServiceStub) {
private val materializer = Materializer.createMaterializer(system)
private val sourceQueue =
Source.queue<LLMRequest>(10, OverflowStrategy.backpressure())
.via(Flow.fromFunction { req: LLMRequest ->
grpcStub.ask(req).toCompletableFuture().get()
})
.toMat(Sink.foreach { reply ->
println(">> LLM 응답: ${reply.response}")
}, Keep.left())
.run(materializer)
fun askLLM(prompt: String): CompletionStage<Done> {
return sourceQueue.offer(LLMRequest.newBuilder().setPrompt(prompt).build())
}
}
|
3. Actor에서 gRPC 스트림 호출 (LLMProcessorActor.kt)
| Code Block | ||
|---|---|---|
| ||
package org.example.actor.llm
import org.apache.pekko.actor.typed.*
import org.apache.pekko.actor.typed.javadsl.*
import org.example.grpc.LLMClientStream
sealed class LLMCommand
data class AskPrompt(val prompt: String) : LLMCommand()
class LLMProcessorActor(
context: ActorContext<LLMCommand>,
private val llmClient: LLMClientStream
) : AbstractBehavior<LLMCommand>(context) {
companion object {
fun create(llmClient: LLMClientStream): Behavior<LLMCommand> {
return Behaviors.setup { ctx -> LLMProcessorActor(ctx, llmClient) }
}
}
override fun createReceive(): Receive<LLMCommand> {
return newReceiveBuilder()
.onMessage(AskPrompt::class.java) { onAskPrompt(it) }
.build()
}
private fun onAskPrompt(command: AskPrompt): Behavior<LLMCommand> {
llmClient.askLLM(command.prompt)
return this
}
}
|
4. 예시 Actor에서 LLM 호출 (HelloActor.kt 연동)
| Code Block | ||
|---|---|---|
| ||
helloActor.tell(AskPrompt("Explain actor model in 2 lines"))
|
5. gRPC 서버는 Bufstream 혹은 일반 gRPC 서버로 구동 (Bufstream 호환 구성 가능)
...
✅ 특징 요약
Akka Streams + gRPC 조합으로 gRPC 요청을 backpressure-aware하게 처리.
LLMProcessorActor는queue에 LLM 요청을 넣고 결과는 비동기 처리.HelloActor혹은RouterActor에서AskPrompt메시지로 연동 가능.Bufstream과도 동일한 원리로 적용 가능 (gRPC 기반이므로 호환).
