<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Coder's Cattitude</title>
    <link>https://hardworkingini.tistory.com/</link>
    <description> 발자 말고  발자 할거야</description>
    <language>ko</language>
    <pubDate>Sat, 18 Jul 2026 19:04:29 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>말하는 알감자</managingEditor>
    <image>
      <title>Coder's Cattitude</title>
      <url>https://tistory1.daumcdn.net/tistory/5476684/attach/4053878369c741ab8908b932ccd7d67b</url>
      <link>https://hardworkingini.tistory.com</link>
    </image>
    <item>
      <title>[Drone] MAVLink - 드론과 지상이 통신하는 언어</title>
      <link>https://hardworkingini.tistory.com/206</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;목표: 드론이 MQTT로 보내는 raw MAVLink 데이터를 받아 디코딩 및 처리하는 시스템 만들기위해서 그 데이터인 MAVLink 프로토콜 자체를 정리한다. (이전 글에서 &quot;펌웨어가 데이터의 생산자&quot;라고 했는데, 그 데이터가 바로 MAVLink 메시지!)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;0. 용어 정리 (프로토콜 / Protobuf / 페이로드)&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로토콜(protocol)이란&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;통신 규칙(약속)이다. &quot;이런 순서로, 이런 형식으로 데이터를 주고받자&quot;는 합의.&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비유: 편지 봉투에 &quot;왼쪽 위 = 보내는 사람, 오른쪽 위 = 우표&quot; 같은 약속. 양쪽이 같은 약속을 지켜야 배달된다.&lt;/li&gt;
&lt;li&gt;HTTP, TCP, MAVLink 모두 각자의 &quot;주고받는 규칙&quot;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로토콜은 층(layer)으로 쌓인다 &amp;mdash; TCP/UDP와의 관계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 수업에서 배운 계층 개념 그대로다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;TCP/UDP&lt;/b&gt; = &quot;데이터를 &lt;b&gt;어떻게 실어 나를까&lt;/b&gt;&quot;를 담당하는 운송 계층. 트럭. 안에 뭐가 실렸는지는 신경 쓰지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MAVLink&lt;/b&gt; = 그 트럭에 실리는 &lt;b&gt;상자의 내용물 규격&lt;/b&gt;. &quot;이 상자엔 위도&amp;middot;경도&amp;middot;고도를 이 순서로 담는다&quot;는 약속. 즉 TCP/UDP보다 &lt;b&gt;위층&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;[ MAVLink 메시지 ]   &amp;larr; 상자 내용물 규격 (뭘 담을지) &amp;larr; 내가 디코딩하는 대상
        &amp;darr; 이걸 실어서
[ TCP / UDP / MQTT ] &amp;larr; 운송 계층 (어떻게 나를지)
        &amp;darr;
[ IP, 무선 링크 ]    &amp;larr; 실제 물리적 배달
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 시스템의 흐름: 드론이 MAVLink 메시지(내용물)를 만든다 &amp;rarr; MQTT/TCP(트럭)에 실어 보낸다 &amp;rarr; 내가 받아 트럭에서 상자를 꺼낸다(MQTT 수신) &amp;rarr; &lt;b&gt;상자 내용물(MAVLink)을 규격대로 뜯는 게 디코딩&lt;/b&gt;.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;페이로드(payload)란&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;포장&amp;middot;주소&amp;middot;검증용 부가정보를 뺀 진짜 알맹이 데이터&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비유: 택배에서 송장&amp;middot;완충재&amp;middot;테이프를 뺀 &lt;b&gt;안의 진짜 물건&lt;/b&gt;. 편지로 치면 봉투가 아니라 &lt;b&gt;편지 본문&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;네트워크 수업의 &quot;헤더 빼고 남는 게 페이로드&quot;와 정확히 같은 개념&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Protobuf(Protocol Buffers)란&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;구글이 만든 데이터 직렬화 포맷&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;직렬화(serialize): 프로그램 안의 데이터를 네트워크로 보내려고 &lt;b&gt;한 줄의 바이트로 쭉 펴는 것&lt;/b&gt;. 받아서 되돌리는 게 역직렬화.&lt;/li&gt;
&lt;li&gt;JSON도 직렬화 포맷이지만, 사람이 읽으라고 글자로 편다({&quot;latitude&quot;: 37.12}) &amp;rarr; 편하지만 무겁다.&lt;/li&gt;
&lt;li&gt;Protobuf는 가독성을 포기하고 &lt;b&gt;바이너리로 빽빽하게&lt;/b&gt; 편다. 대신 &lt;b&gt;미리 스키마(필드 타입&amp;middot;순서 정의서)를 양쪽이 공유&lt;/b&gt;해야 복원 가능하다. 글자 라벨을 안 보내고 순서로만 구분하기 때문.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;MAVLink가 Protobuf 같다&quot;&lt;/b&gt;는 건 같은 발상이라는 뜻이다: 라벨 없이 바이너리로 빽빽하게, 미리 정한 스키마(= dialect의 메시지 정의)로만 해독&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. MAVLink란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;M&lt;/b&gt;icro &lt;b&gt;A&lt;/b&gt;ir &lt;b&gt;V&lt;/b&gt;ehicle &lt;b&gt;Link&lt;/b&gt;의 약자. 소형 무인기와 통신하기 위한 프로토콜이다. &lt;br /&gt;성격은 우리가 아는 것 중 &lt;b&gt;Protobuf(protocol buffers)에 가장 가깝다.&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;왜 Protobuf와 비슷한가&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사람이 읽는 JSON이 아니라, &lt;b&gt;바이너리로 빽빽하게 압축된 포맷&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;미리 정해진 &lt;b&gt;스키마(메시지 정의)&lt;/b&gt;가 있어야 디코딩 가능&lt;/li&gt;
&lt;li&gt;필드마다 타입과 순서가 정해져 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;왜 JSON을 안 쓰고 이렇게 만들었나&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드론은 &lt;b&gt;대역폭과 자원이 부족한 환경&lt;/b&gt;이다. MAVLink는 자원 및 대역폭이 제한된 소형 무인기와 통신하기 위한 효율적 텔레메트리 프로토콜 무선 링크로 초당 수십~수백 개 메시지를 날려야 하는데, {&quot;latitude&quot;: 37.1234567} 같은 텍스트를 매번 보내면 너무 무겁고 느리다. &lt;br /&gt;&amp;rarr; 그래서 &quot;위도&quot;를 4바이트 정수 하나에 욱여넣는 식으로 극한까지 압축했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 메시지가 &quot;종류별로&quot; 나뉜다는 것&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAVLink 통신은 한 덩어리로 흐르지 않는다. &lt;b&gt;종류가 정해진 메시지들이 각자 따로 날아오는&lt;/b&gt; 구조다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비유: 드론이 지상국에 여러 종류의 &lt;b&gt;엽서&lt;/b&gt;를 계속 부친다. 엽서마다 종류(양식)가 정해져 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;메시지&lt;/td&gt;
&lt;td&gt;뜻&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HEARTBEAT&lt;/td&gt;
&lt;td&gt;&quot;나 살아있어요&quot; (심장박동)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GLOBAL_POSITION_INT&lt;/td&gt;
&lt;td&gt;&quot;제 현재 위경도/고도는 이거예요&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ATTITUDE&lt;/td&gt;
&lt;td&gt;&quot;제가 지금 이만큼 기울어져 있어요&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SYS_STATUS&lt;/td&gt;
&lt;td&gt;&quot;배터리 잔량, 센서 상태는 이래요&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPS_RAW_INT&lt;/td&gt;
&lt;td&gt;&quot;GPS 원시 데이터예요&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 메시지(엽서)에는 &lt;b&gt;고유 번호(message ID)&lt;/b&gt;와 &lt;b&gt;정해진 칸(필드)&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HEARTBEAT: ID &lt;b&gt;0번&lt;/b&gt;. &quot;기체 타입, 자동조종 종류, 비행 모드, 시스템 상태&quot; 등의 칸.&lt;/li&gt;
&lt;li&gt;GLOBAL_POSITION_INT: ID &lt;b&gt;33번&lt;/b&gt;. &quot;타임스탬프, 위도, 경도, 고도, 속도&quot; 등의 칸.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;raw MAVLink를 디코딩한다는 건: &quot;날아온 바이트 덩어리 &amp;rarr; 몇 번 엽서인지 알아내고 &amp;rarr; 그 양식에 맞춰 칸을 하나씩 꺼내는&quot; 작업 Protobuf 메시지를 .proto 스키마로 파싱하는 것과 같은 개념&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 메시지 하나가 실제로 어떻게 생겼나 (프레임 구조)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엽서 하나(= 한 메시지)는 이런 봉투에 담겨 날아온다. 아래는 &lt;b&gt;MAVLink v2.0&lt;/b&gt; 기준. 앞부분(STX~CHECKSUM)은 항상 있고, 맨 뒤 &lt;b&gt;SIGNATURE는 옵션&lt;/b&gt;(서명 켠 경우에만 붙음)이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1395&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egZHs9/dJMb991q6wX/lpoCKwoFwCkTU1blivofM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egZHs9/dJMb991q6wX/lpoCKwoFwCkTU1blivofM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egZHs9/dJMb991q6wX/lpoCKwoFwCkTU1blivofM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FegZHs9%2FdJMb991q6wX%2FlpoCKwoFwCkTU1blivofM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1395&quot; height=&quot;100&quot; data-origin-width=&quot;1395&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;순서&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;필드&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;크기&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;비유&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;역할&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;STX&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;봉투 시작 표시&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;&quot;여기서부터 새 엽서 시작&quot;. v2 = 0xFD (v1 = 0xFE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;LEN&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;내용물 분량&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;PAYLOAD가 몇 바이트인지 (0~255)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;INC FLAGS &lt;br /&gt;(incompatible)&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;봉인 방식 표시&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;모르면 &lt;b&gt;메시지를 버려야&lt;/b&gt; 하는 플래그. 서명 여부 등이 여기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;CMP FLAGS &lt;br /&gt;(compatible)&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;참고용 메모&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;몰라도 &lt;b&gt;무시하고 읽으면&lt;/b&gt; 되는 부가 정보&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;SEQ&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;엽서 일련번호&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;0~255 순환. 건너뛴 번호로 유실 감지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;SYS ID&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;보낸 기체 주소&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;어느 시스템(드론)이 보냈나&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;COMP ID&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;보낸 부품 주소&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;그 기체 안 어느 부품(FC, 카메라 등)이 보냈나&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;MSG ID&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;3 bytes&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;엽서 종류 번호&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;HEARTBEAT(0)인지 GLOBAL_POSITION_INT(33)인지. v2에서 3바이트로 확장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;9&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;&lt;b&gt;PAYLOAD&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;0~255 bytes&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;&lt;b&gt;엽서 본문&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;&lt;b&gt;실제 데이터(위도, 고도 등) = 알맹이&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;CHECKSUM&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;2 bytes&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;봉인 도장&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;중간에 깨지지 않았는지 검증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5.5814%;&quot;&gt;11&lt;/td&gt;
&lt;td style=&quot;width: 17.6745%;&quot;&gt;SIGNATURE (옵션)&lt;/td&gt;
&lt;td style=&quot;width: 12.6743%;&quot;&gt;13 bytes&lt;/td&gt;
&lt;td style=&quot;width: 12.5582%;&quot;&gt;인감 도장&lt;/td&gt;
&lt;td style=&quot;width: 51.2791%;&quot;&gt;위조 방지 전자 서명. link id(1) + timestamp(6) + signature(6)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심: &lt;b&gt;메시지 ID를 봐야 페이로드를 어떻게 해석할지 결정된다.&lt;/b&gt; ID가 33번이면 &quot;페이로드를 GLOBAL_POSITION_INT 양식으로 읽어야겠다&quot;가 된다. 봉투를 뜯기 전엔 안쪽 바이트는 그냥 의미 없는 숫자 뭉치다.&lt;/p&gt;
&lt;h4 data-sourcepos=&quot;122:1-122:43;3790-3832&quot; data-ke-size=&quot;size20&quot;&gt;INC FLAGS vs CMP FLAGS (v2에서 새로 생긴 부분)&lt;/h4&gt;
&lt;p data-sourcepos=&quot;124:1-124:49;3834-3882&quot; data-ke-size=&quot;size16&quot;&gt;둘 다 &quot;이 플래그를 &lt;b&gt;모르는 디코더&lt;/b&gt;가 만났을 때 어떻게 할래?&quot;에 대한 답이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;126:1-127:62;3884-4027&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;126:1-126:82;3884-3965&quot;&gt;&lt;b&gt;INC&lt;/b&gt;ompatible flags &amp;rarr; 모르면 &lt;b&gt;메시지를 버려라.&lt;/b&gt; (모른 채 읽으면 잘못 읽음. 서명이 붙었다는 표시가 대표 예시)&lt;/li&gt;
&lt;li data-sourcepos=&quot;127:1-127:62;3966-4027&quot;&gt;&lt;b&gt;COM&lt;/b&gt;patible flags &amp;rarr; 모르면 &lt;b&gt;무시하고 읽어라.&lt;/b&gt; (몰라도 본문 해석엔 지장 없음)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-sourcepos=&quot;129:1-129:74;4029-4102&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-sourcepos=&quot;129:3-129:74;4031-4102&quot; data-ke-size=&quot;size16&quot;&gt;비유(HTTP 헤더): &quot;이해 못 하면 요청 자체를 거부해야 하는 헤더&quot; vs &quot;몰라도 그냥 무시하면 되는 부가 헤더&quot;의 차이.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-sourcepos=&quot;131:1-131:29;4104-4132&quot; data-ke-size=&quot;size20&quot;&gt;SIGNATURE (맨 뒤 옵션 13바이트)&lt;/h4&gt;
&lt;p data-sourcepos=&quot;133:1-134:53;4134-4238&quot; data-ke-size=&quot;size16&quot;&gt;메시지 위조 방지용 전자 서명. &quot;진짜 우리 드론이 보냈고 중간 조작이 없었다&quot;를 보증한다. 서명 기능을 켠 경우에만 붙고(그림에서 점선), 안 쓰면 CHECKSUM에서 메시지가 끝난다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;136:1-137:89;4240-4368&quot; data-ke-size=&quot;size16&quot;&gt;핵심: &lt;b&gt;메시지 ID를 봐야 페이로드를 어떻게 해석할지 결정된다.&lt;/b&gt; ID가 33번이면 &quot;페이로드를 GLOBAL_POSITION_INT 양식으로 읽어야겠다&quot;가 된다. 봉투를 뜯기 전엔 안쪽 바이트는 그냥 의미 없는 숫자 뭉치다.&lt;/p&gt;
&lt;h4 data-sourcepos=&quot;139:1-139:18;4370-4387&quot; data-ke-size=&quot;size20&quot;&gt;실무에서 디코딩되는 순서&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-sourcepos=&quot;141:1-145:25;4389-4557&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-sourcepos=&quot;141:1-141:37;4389-4425&quot;&gt;&lt;b&gt;STX&lt;/b&gt;로 메시지 시작을 찾는다 (0xFD면 v2)&lt;/li&gt;
&lt;li data-sourcepos=&quot;142:1-142:39;4426-4464&quot;&gt;&lt;b&gt;INC FLAGS&lt;/b&gt;로 서명 여부 등 해석 가능 여부를 확인&lt;/li&gt;
&lt;li data-sourcepos=&quot;143:1-143:33;4465-4497&quot;&gt;&lt;b&gt;MSG ID&lt;/b&gt;(3바이트)로 어떤 메시지인지 판별&lt;/li&gt;
&lt;li data-sourcepos=&quot;144:1-144:35;4498-4532&quot;&gt;&lt;b&gt;PAYLOAD&lt;/b&gt;를 해당 dialect 스키마로 해석&lt;/li&gt;
&lt;li data-sourcepos=&quot;145:1-145:25;4533-4557&quot;&gt;&lt;b&gt;CHECKSUM&lt;/b&gt;으로 무결성 검증&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-sourcepos=&quot;147:1-149:51;4559-4724&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-sourcepos=&quot;147:3-149:51;4561-4724&quot; data-ke-size=&quot;size16&quot;&gt;실제로는 pymavlink 같은 라이브러리가 이 프레임 해체를 &lt;b&gt;자동으로&lt;/b&gt; 해준다. 바이트를 손으로 자를 일은 거의 없고, 라이브러리가 &quot;MSG ID는 33, 필드는 이거&quot;라고 객체로 건네준다. 다만 구조를 알아야 에러(서명 파싱 실패, v1/v2 혼동 등) 원인을 짚을 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;여기서 dialect가 다시 등장&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지 ID &amp;harr; 양식의 대응표(어느 ID가 무슨 메시지고 칸이 뭔지)가 바로 &lt;b&gt;dialect&lt;/b&gt;에 정의돼 있다. 표준 MAVLink에 공통 메시지가 있고, ardupilotmega 방언에 ArduPilot 고유 메시지가 추가돼 있다. &amp;rarr; 디코더에게 방언을 알려줘야 ID&amp;rarr;양식 대응표를 갖고 제대로 파싱할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한 줄 요약(실무 연결):&lt;/b&gt; MAVLink 디코딩이란 &quot;바이너리 봉투에서 메시지 ID를 읽고, 해당 dialect 스키마로 페이로드 칸을 꺼내는 일&quot;이며, 이게 내 시스템의 심장부다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Q&amp;amp;A&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q. MAVLink를 JSON이 아니라 Protobuf 같은 바이너리 스키마 포맷으로 만든 이유는?&lt;/b&gt; &lt;br /&gt;드론은 자원이 부족한 환경이라 JSON처럼 무거운 텍스트를 쓸 수 없어서, 바이너리 스키마 포맷으로 최대한 경량화했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q. &quot;메시지가 종류별로 나뉜다&quot;는 게 무슨 뜻? (HEARTBEAT / GLOBAL_POSITION_INT)&lt;br /&gt;&lt;/b&gt; 메시지마다 고유 ID가 있어 구별된다. ID가 0이면 HEARTBEAT 정보가, 다른 ID면 GLOBAL_POSITION_INT 등 해당 메시지의 데이터가 들어온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q. 디코딩할 때 왜 메시지 ID를 먼저 봐야 하나? &lt;br /&gt;&lt;/b&gt;메시지마다 담긴 데이터(필드)가 다르기 때문에, ID를 먼저 봐야 어떤 양식으로 칸을 꺼낼지 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q. INC FLAGS와 CMP FLAGS의 차이는? (v2)&lt;br /&gt;&lt;/b&gt;둘 다 &quot;이 플래그를 모르는 디코더가 만났을 때 어떻게 할지&quot;를 정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;174:1-175:40;5538-5633&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;174:1-174:56;5538-5593&quot;&gt;INC(incompatible): 모르면 메시지를 &lt;b&gt;버려야&lt;/b&gt; 한다. (서명 여부 등이 여기)&lt;/li&gt;
&lt;li data-sourcepos=&quot;175:1-175:40;5594-5633&quot;&gt;CMP(compatible): 몰라도 &lt;b&gt;무시하고 읽으면&lt;/b&gt; 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고 자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MAVLink 공식 문서: &lt;a href=&quot;https://mavlink.io/en/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mavlink.io/en/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MAVLink 메시지 정의(common): &lt;a href=&quot;https://mavlink.io/en/messages/common.html&quot;&gt;https://mavlink.io/en/messages/common.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MAVLink 메시지 정의(ArduPilot 방언): &lt;a href=&quot;https://mavlink.io/en/messages/ardupilotmega.html&quot;&gt;https://mavlink.io/en/messages/ardupilotmega.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;pymavlink: &lt;a href=&quot;https://github.com/ArduPilot/pymavlink&quot;&gt;https://github.com/ArduPilot/pymavlink&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Protocol Buffers 개요: &lt;a href=&quot;https://protobuf.dev/overview/&quot;&gt;https://protobuf.dev/overview/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/206</guid>
      <comments>https://hardworkingini.tistory.com/206#entry206comment</comments>
      <pubDate>Tue, 14 Jul 2026 13:27:38 +0900</pubDate>
    </item>
    <item>
      <title>[Drone] FC와 Ardupilot/PX4</title>
      <link>https://hardworkingini.tistory.com/205</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;드론 제어 시스템을 구축하는데 드론에 대한 공부가 부족한 것 같아서 스스로 이해하고 있는 내용을 적어보고 계속해서 보완해 볼 예정입니다. 회사에서 선배님들께 들은 용어들 적어놓고 추가적으로 공부해서 계속해서 업데이트 할 예정.&amp;nbsp; 제품개발부에서 들은 하드웨어 용어도 다시 점검할 예정!&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. FC (Flight Controller) 란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드론 안에는 비행 컨트롤러 (Flight Controller, FC)라는 손바닥보다 작은 회로 기판(보드)가 들어있다.&lt;br /&gt;자이로, 가속도계, 기압계, GPS와 같은 센서가 여기에 연결되고, 모터로 나가는 출력도 여기서 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 비유 : FC는 드론의 소뇌와 가깝다. &quot;기체가 3도 기울었다. -&amp;gt; 왼쪽 모터 출력을 살짝 높인다.&quot; 와 같은 판단을 초당 수백 번씩 자동으로 한다.&lt;br /&gt;- 사람이 걸을 때 넘어지지 않으려고 무의식적으로 균형을 잡는 일을 FC가 대신 해준다고 생각하면 된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;캐리어 보드 (carrier board)란?&lt;br /&gt;Pixhawk 같은 FC는 보통 캐리어 보드 (베이스 보드) 위에 꽂힌다. &lt;br /&gt;FC 본체 = 센서 및 연산 담당 핵심 모듈, carrier board = 전원 분배와 각종 포트 (GPS, 텔레메트리, 모터 신호선) 연결 담당&lt;br /&gt;비유하자면 FC = CPU 모듈, carrier board = 메인 보드 같은 느낌&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;FC vs 펌웨어&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FC는 하드웨어 (보드)이고 그 위에서 도는 소프트웨어 (펌웨어)가 따로 있다.&lt;/p&gt;
&lt;div data-sourcepos=&quot;25:1-28:68;792-934&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;구분&lt;/td&gt;
&lt;td&gt;비유&lt;/td&gt;
&lt;td&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FC 보드&lt;/td&gt;
&lt;td&gt;서버(물리 머신)&lt;/td&gt;
&lt;td&gt;센서&amp;middot;연산&amp;middot;출력을 담당하는 하드웨어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;펌웨어&lt;/td&gt;
&lt;td&gt;그 서버에 설치하는 OS&lt;/td&gt;
&lt;td&gt;하드웨어를 직접 제어하는 소프트웨어 = &lt;b&gt;ArduPilot / PX4&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 보드에 ArduPilot을 깔 수도, PX4를 깔 수도 있다. 마치 같은 서버에 Ubuntu를 깔 수도, Debian을 깔 수도 있는 것처럼.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;펌웨어(firmware)란? software(무른)와 hardware(딱딱한)의 중간(firm). 일반 앱은 OS 위에 여러 계층을 두고 돌지만, 펌웨어는 그 계층이 거의 없이 하드웨어에 딱 붙어 센서 값을 직접 읽고 모터 신호를 직접 만든다. 특정 하드웨어에 맞춰져 있고, 웬만해선 자주 안 바꾼다.&lt;/blockquote&gt;
&lt;h4 data-sourcepos=&quot;38:1-38:13;1206-1218&quot; data-ke-size=&quot;size20&quot;&gt;Pixhawk란&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;40:1-42:42;1220-1346&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;40:1-40:44;1220-1263&quot;&gt;&lt;b&gt;FC&lt;/b&gt; = 카테고리 (드론의 뇌 역할을 하는 보드 일반, &quot;노트북&quot;)&lt;/li&gt;
&lt;li data-sourcepos=&quot;41:1-41:41;1264-1304&quot;&gt;&lt;b&gt;Pixhawk&lt;/b&gt; = 그 카테고리의 대표 제품 브랜드 (&quot;맥북&quot;)&lt;/li&gt;
&lt;li data-sourcepos=&quot;42:1-42:42;1305-1346&quot;&gt;&lt;b&gt;ArduPilot / PX4&lt;/b&gt; = 그 위에 까는 펌웨어(OS 격)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;44:1-45:101;1348-1497&quot; data-ke-size=&quot;size16&quot;&gt;Pixhawk가 사실상 표준처럼 자리 잡아서, FC를 말할 때 대명사처럼 쓰이곤 한다. (이름이 비슷한 PX4 펌웨어와 Pixhawk 보드는 초기 같은 프로젝트에서 갈라져 나온 형제지만, 지금은 별개다. Pixhawk 보드에 ArduPilot도 얼마든지 설치 가능.)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Ardupilot vs PX4&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 다 오픈소스 autopilot 펌웨어이다. 같은 FC 보드에 골라서 설치한다.&lt;/p&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;ArduPilot&lt;/td&gt;
&lt;td&gt;PX4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;성격&lt;/td&gt;
&lt;td&gt;오래됨, 기능 방대, 커뮤니티 중심&lt;/td&gt;
&lt;td&gt;상대적으로 모던, 기업/연구 친화, 구조가 깔끔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;라이선스&lt;/td&gt;
&lt;td&gt;GPLv3 (강한 카피레프트)&lt;/td&gt;
&lt;td&gt;BSD (상업적으로 부담 적음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;지원 기체&lt;/td&gt;
&lt;td&gt;멀티콥터&amp;middot;고정익&amp;middot;로버&amp;middot;잠수정 등 매우 광범위&lt;/td&gt;
&lt;td&gt;주로 드론(멀티콥터&amp;middot;VTOL) 중심&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;개발자 관점&lt;/td&gt;
&lt;td&gt;설정 옵션이 많고 &quot;뭐든 된다&quot; 스타일&lt;/td&gt;
&lt;td&gt;코드가 모듈화되어 있고 정돈된 스타일&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Ardupilot =&amp;nbsp; 방대한 기능, 뭐든 되고 옵션이 많음&lt;br /&gt;-&amp;nbsp; &amp;nbsp; &amp;nbsp; PX4&amp;nbsp; &amp;nbsp; &amp;nbsp;= 구조가 깔끔한 잘 설계된 프레임워크&lt;/p&gt;
&lt;p data-sourcepos=&quot;63:1-63:23;1895-1917&quot; data-ke-size=&quot;size16&quot;&gt;+) 라이선스가 왜 실무적으로 중요한가?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;65:1-66:64;1919-2037&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;65:1-65:55;1919-1973&quot;&gt;&lt;b&gt;ArduPilot(GPL)&lt;/b&gt;: 소스를 수정하면 그 수정 사항을 오픈소스로 공개해야 한다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;66:1-66:64;1974-2037&quot;&gt;&lt;b&gt;PX4(BSD)&lt;/b&gt;: 수정 내용을 공개하지 않아도 된다 &amp;rarr; 상업적으로 부담이 적어 기업이 선호하기도 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;68:1-68:58;2039-2096&quot; data-ke-size=&quot;size16&quot;&gt;즉, 라이선스는 단순 표기가 아니라 &lt;b&gt;회사가 어느 펌웨어를 고르느냐에 실제로 영향을 주는 요소&lt;/b&gt;다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-sourcepos=&quot;72:1-72:31;2103-2133&quot; data-ke-size=&quot;size23&quot;&gt;3. 데이터를 단순히 받기만 하는 내가 왜 FC/펌웨어를 알아야 할까&lt;/h3&gt;
&lt;p data-sourcepos=&quot;74:1-75:64;2135-2301&quot; data-ke-size=&quot;size16&quot;&gt;핵심: &lt;b&gt;나는 FC 펌웨어를 직접 수정하지 않는다.&lt;/b&gt; ArduPilot/PX4는 이미 완성된 펌웨어이고, 나는 그게 내보내는 데이터를 받는 &lt;b&gt;소비자(consumer)&lt;/b&gt; 쪽이다. (백엔드로 치면, 남이 운영하는 외부 API의 응답을 파싱하는 입장. API 서버 코드를 고치는 입장이 아니다.)&lt;/p&gt;
&lt;p data-sourcepos=&quot;77:1-77:21;2303-2323&quot; data-ke-size=&quot;size16&quot;&gt;그럼에도 이 둘을 알아야 하는 이유:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-sourcepos=&quot;79:1-81:73;2325-2577&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-sourcepos=&quot;79:1-79:110;2325-2434&quot;&gt;&lt;b&gt;MAVLink 데이터를 만들어내는 주체가 바로 이 펌웨어다.&lt;/b&gt; 데이터의 출처이자 생산자. 어느 펌웨어인지에 따라 보내는 메시지 종류&amp;middot;주기&amp;middot;&lt;b&gt;dialect&lt;/b&gt;가 미묘하게 다를 수 있다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;80:1-80:70;2435-2504&quot;&gt;&lt;b&gt;SITL로 가짜 드론을 띄울 때&lt;/b&gt; ArduPilot 계열이냐 PX4 계열이냐를 골라야 한다. (시뮬레이터가 다름)&lt;/li&gt;
&lt;li data-sourcepos=&quot;81:1-81:73;2505-2577&quot;&gt;&lt;b&gt;비행 모드 번호, 파라미터 이름&lt;/b&gt;이 펌웨어마다 조금씩 다르다. 디코딩한 값을 해석할 때 해당 펌웨어 문서를 봐야 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-sourcepos=&quot;83:1-87:74;2579-2786&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-sourcepos=&quot;83:3-87:74;2581-2786&quot; data-ke-size=&quot;size16&quot;&gt;dialect(방언)란? MAVLink는 드론&amp;harr;지상의 공통 언어(프로토콜) = 표준어. 그 위에 특정 진영이 얹은 추가 어휘 묶음이 방언이다. (영어는 공통이지만 미국식엔 영국엔 없는 단어가 있는 것과 같다.) ArduPilot의 방언 이름은 ardupilotmega. 나중에 pymavlink로 디코딩할 때 이 방언을 지정하게 된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-sourcepos=&quot;89:1-89:24;2788-2811&quot; data-ke-size=&quot;size23&quot;&gt;참고: MAVLink는 펌웨어 공통&lt;/h3&gt;
&lt;p data-sourcepos=&quot;91:1-94:65;2813-3025&quot; data-ke-size=&quot;size16&quot;&gt;MAVLink 프로토콜 자체는 ArduPilot&amp;middot;PX4 &lt;b&gt;공통&lt;/b&gt;이다. 그래서 &quot;ArduPilot이냐 PX4냐&quot;를 지금 급하게 정할 필요는 없다. (다만 회사가 ArduPilot을 쓴다면, 실습과 문서는 ArduPilot 기준으로 몰아서 배우는 게 효율적이다.) 또한 둘 다 MAVLink를 쓰기 때문에 QGroundControl 같은 지상국 소프트웨어가 양쪽 모두와 호환된다.&lt;/p&gt;
&lt;blockquote data-sourcepos=&quot;96:1-97:49;3027-3134&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-sourcepos=&quot;96:3-97:49;3029-3134&quot; data-ke-size=&quot;size16&quot;&gt;참고: MAVLink에는 v1.0 / v2.0 두 버전이 있고, v2는 v1과 하위 호환된다. 나중에 디코더가 어느 버전을 파싱하는지가 실무에서 중요해진다.&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-sourcepos=&quot;101:1-101:18;3141-3158&quot; data-ke-size=&quot;size23&quot;&gt;이해 점검 (셀프 Q&amp;amp;A)&lt;/h3&gt;
&lt;p data-sourcepos=&quot;103:1-104:67;3160-3262&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Q. FC 하드웨어와 펌웨어의 관계를 서버/OS 비유로?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;103:1-104:67;3160-3262&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;보드 = 서버, 펌웨어 = 서버에 설치하는 OS. Windows/Linux를 고르듯 ArduPilot/PX4를 고른다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;106:1-107:47;3264-3343&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Q. 나는 펌웨어 코드를 수정하나, 데이터를 받나?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;106:1-107:47;3264-3343&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;받는 쪽. ArduPilot/PX4는 완성된 펌웨어이고, 나는 그 출력을 소비한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;109:1-110:42;3345-3424&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;Q. ArduPilot/PX4를 지금 안 정해도 되는 이유?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;109:1-110:42;3345-3424&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;MAVLink 프로토콜이 공통이라, 펌웨어별 차이는 나중에 생각해도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-sourcepos=&quot;121:1-121:9;3568-3576&quot; data-ke-size=&quot;size23&quot;&gt;참고 자료&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;123:1-128:141;3578-4044&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;123:1-123:52;3578-3629&quot;&gt;ArduPilot 공식 문서: &lt;a href=&quot;https://ardupilot.org/ardupilot/&quot;&gt;https://ardupilot.org/ardupilot/&lt;/a&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;124:1-124:34;3630-3663&quot;&gt;PX4 공식 문서: &lt;a href=&quot;https://docs.px4.io/&quot;&gt;https://docs.px4.io/&lt;/a&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;125:1-125:40;3664-3703&quot;&gt;MAVLink 공식 문서: &lt;a href=&quot;https://mavlink.io/en/&quot;&gt;https://mavlink.io/en/&lt;/a&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;126:1-126:72;3704-3775&quot;&gt;pymavlink (파이썬 MAVLink 라이브러리): &lt;a href=&quot;https://github.com/ArduPilot/pymavlink&quot;&gt;https://github.com/ArduPilot/pymavlink&lt;/a&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;127:1-127:128;3776-3903&quot;&gt;Intro to ArduPilot and PX4 (Circuit Cellar): &lt;a href=&quot;https://circuitcellar.com/research-design-hub/intro-to-ardupilot-and-px4-part-1/&quot;&gt;https://circuitcellar.com/research-design-hub/intro-to-ardupilot-and-px4-part-1/&lt;/a&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;128:1-128:141;3904-4044&quot;&gt;PX4 vs ArduPilot 비교 (ThinkRobotics): &lt;a href=&quot;https://thinkrobotics.com/blogs/learn/px4-vs-ardupilot-complete-comparison-guide-for-drone-developers&quot;&gt;https://thinkrobotics.com/blogs/learn/px4-vs-ardupilot-complete-comparison-guide-for-drone-developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/205</guid>
      <comments>https://hardworkingini.tistory.com/205#entry205comment</comments>
      <pubDate>Mon, 13 Jul 2026 17:58:27 +0900</pubDate>
    </item>
    <item>
      <title>[NLP] NLP란?</title>
      <link>https://hardworkingini.tistory.com/204</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 자연어 처리란?&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;자연어(Natural Language)&lt;/b&gt; 란 우리가 일상생활에서 사용하는 언어를 말한다.&lt;br /&gt;&lt;b&gt;자연어 처리(Natural Language Processing, NLP)&lt;/b&gt; 란 이러한 자연어의 의미를 분석하여 컴퓨터가 처리할 수 있도록 하는 일을 말한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NLP는 다음과 같은 다양한 분야에서 사용된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;음성 인식&lt;/li&gt;
&lt;li&gt;내용 요약&lt;/li&gt;
&lt;li&gt;번역&lt;/li&gt;
&lt;li&gt;사용자의 감성 분석&lt;/li&gt;
&lt;li&gt;텍스트 분류 (스팸 메일 분류, 뉴스 기사 카테고리 분류 등)&lt;/li&gt;
&lt;li&gt;질의 응답 시스템&lt;/li&gt;
&lt;li&gt;챗봇&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한마디로 NLP는 &lt;b&gt;기계에게 인간의 언어를 이해시키기 위한 분야&lt;/b&gt;라고 할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 머신 러닝 워크플로우&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 수집하고 머신 러닝을 수행하는 과정은 크게 &lt;b&gt;6단계&lt;/b&gt;로 나눌 수 있다. &lt;br /&gt;(딥 러닝 또한 머신 러닝의 한 갈래이므로 딥 러닝 워크플로우도 같은 흐름으로 볼 수 있다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dy3y72/dJMcaixbWfa/C9B1kfbu6V7aDxVSXPKoBK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dy3y72/dJMcaixbWfa/C9B1kfbu6V7aDxVSXPKoBK/img.webp&quot; data-alt=&quot;출처 : https://wikidocs.net/31947&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dy3y72/dJMcaixbWfa/C9B1kfbu6V7aDxVSXPKoBK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdy3y72%2FdJMcaixbWfa%2FC9B1kfbu6V7aDxVSXPKoBK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;829&quot; height=&quot;237&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://wikidocs.net/31947&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 수집 (Acquisition)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머신 러닝을 하려면 먼저 기계에 학습시킬 &lt;b&gt;데이터&lt;/b&gt;가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연어 처리에서는 이 자연어 데이터를 &lt;b&gt;말뭉치&lt;/b&gt; 또는 &lt;b&gt;코퍼스(corpus)&lt;/b&gt; 라고 부른다. 코퍼스란 조사나 연구 목적에 의해 특정 도메인으로부터 수집된 텍스트 집합을 의미한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;파일 형식&lt;/b&gt;: &lt;code&gt;.txt&lt;/code&gt;, &lt;code&gt;.csv&lt;/code&gt;, &lt;code&gt;.xml&lt;/code&gt; 등 다양&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출처&lt;/b&gt;: 음성 데이터, 웹 크롤러로 수집한 데이터, 영화 리뷰 등 다양&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 점검 및 탐색 (Inspection and Exploration)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터가 수집되었다면 이제 데이터를 &lt;b&gt;점검하고 탐색&lt;/b&gt;하는 단계다. 데이터의 구조, 노이즈, 어떻게 정제해야 할지 등을 파악한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 단계를 &lt;b&gt;탐색적 데이터 분석(Exploratory Data Analysis, EDA)&lt;/b&gt; 단계라고도 부른다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;독립 변수, 종속 변수, 변수 유형, 데이터 타입 등을 점검&lt;/li&gt;
&lt;li&gt;데이터의 특징과 내재하는 구조적 관계를 파악&lt;/li&gt;
&lt;li&gt;이 과정에서 &lt;b&gt;시각화&lt;/b&gt;와 간단한 &lt;b&gt;통계 테스트&lt;/b&gt;를 진행하기도 함&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) 전처리 및 정제 (Preprocessing and Cleaning)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터에 대한 파악이 끝났다면, 워크플로우에서 &lt;b&gt;가장 까다로운 작업 중 하나&lt;/b&gt;인 데이터 전처리 과정에 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연어 처리라면 다음과 같은 단계를 포함한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;토큰화 (Tokenization)&lt;/li&gt;
&lt;li&gt;정제 (Cleaning)&lt;/li&gt;
&lt;li&gt;정규화 (Normalization)&lt;/li&gt;
&lt;li&gt;불용어 제거 (Stopword Removal)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빠르고 정확한 전처리를 위해서는 사용하는 툴(파이썬 등)의 다양한 &lt;b&gt;라이브러리에 대한 지식&lt;/b&gt;이 필요하다. 정말 까다로운 경우에는 전처리 과정에서 머신 러닝이 사용되기도 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) 모델링 및 훈련 (Modeling and Training)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전처리가 끝났다면 머신 러닝 코드를 작성하는 &lt;b&gt;모델링&lt;/b&gt; 단계에 들어간다. 적절한 알고리즘을 선택해 모델링이 끝나면, 전처리된 데이터를 알고리즘에 넣어 기계를 &lt;b&gt;학습(training)&lt;/b&gt; 시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습이 제대로 되면 기계는 번역, 음성 인식, 텍스트 분류 등 우리가 원하는 작업을 수행할 수 있게 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;⚠️ 주의: 모든 데이터를 학습에 쓰면 안 된다!&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 일부는 &lt;b&gt;테스트용&lt;/b&gt;으로 남겨두고 &lt;b&gt;훈련용 데이터만&lt;/b&gt; 훈련에 사용해야 한다. 그래야 학습 후 테스트용 데이터로 성능을 측정할 수 있고, &lt;b&gt;과적합(overfitting)&lt;/b&gt; 을 막을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 최선은 두 가지가 아니라 &lt;b&gt;세 가지&lt;/b&gt;로 나누는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cys0rB/dJMcaazaL37/hkmYqiXNibQSfAbnW0DjE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cys0rB/dJMcaazaL37/hkmYqiXNibQSfAbnW0DjE1/img.png&quot; data-alt=&quot;출처 : https://wikidocs.net/31947&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cys0rB/dJMcaazaL37/hkmYqiXNibQSfAbnW0DjE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcys0rB%2FdJMcaazaL37%2FhkmYqiXNibQSfAbnW0DjE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;346&quot; height=&quot;175&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://wikidocs.net/31947&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;검증용 vs 테스트용의 차이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수능 시험에 비유하면 이해가 쉽다.&lt;/p&gt;
&lt;table style=&quot;height: 125px;&quot; width=&quot;566&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;데이터&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;비유&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;역할&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;b&gt;훈련용 (Train)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;학습지&lt;/td&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;기계를 학습시키는 데 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;검증용 (Validation)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;모의고사&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;학습이 얼마나 됐는지 판단하고 &lt;b&gt;성능을 개선&lt;/b&gt;하는 데 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;테스트용 (Test)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;수능 시험&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;모델의 &lt;b&gt;최종 성능을 수치화하여 평가&lt;/b&gt; (채점 단계)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검증용 데이터는 모델의 성능을 개선하는 데 쓰고, 테스트용 데이터는 개선이 아니라 평가에만 쓴다는 점이 핵심이다. &lt;br /&gt;현업에서 최선은 검증용 데이터까지 사용하는 것이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5) 평가 (Evaluation)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습이 완료되면 &lt;b&gt;테스트용 데이터&lt;/b&gt;로 성능을 평가한다. 평가 방법은 기계가 예측한 값이 테스트용 데이터의 &lt;b&gt;실제 정답과 얼마나 가까운지&lt;/b&gt;를 측정하는 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6) 배포 (Deployment)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평가 단계에서 성공적으로 훈련된 것으로 판단되면, 완성된 모델을 &lt;b&gt;배포&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 배포 후 전체적인 피드백으로 인해 모델을 업데이트해야 하는 상황이 오면, 다시 &lt;b&gt;수집 단계로 돌아갈 수 있다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>개발</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/204</guid>
      <comments>https://hardworkingini.tistory.com/204#entry204comment</comments>
      <pubDate>Mon, 6 Jul 2026 11:19:06 +0900</pubDate>
    </item>
    <item>
      <title>[데이터베이스] 1. 데이터베이스의 기본</title>
      <link>https://hardworkingini.tistory.com/202</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;데이터베이스란?&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;데이터베이스(DB, DataBase) 는 일정한 규칙, 혹은 규약을 통해 구조화되어 저장되는 데이터의 모음이다.&lt;br /&gt;해당 데이터베이스를 제어, 관리하는 통합 시스템을 DBMS(DataBase Management System) 라고 한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 안에 있는 데이터들은 특정 DBMS마다 정의된 쿼리 언어(query language)를 통해 삽입, 삭제, 수정, 조회 등을 수행할 수 있다. 또한, 데이터베이스는 실시간 접근과 동시 공유가 가능하다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;응용 프로그램
    ↕
  DBMS
    ↕
데이터베이스
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 위에 DBMS가 있고 그 위에 응용 프로그램이 있으며, 이러한 구조를 기반으로 데이터를 주고받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 MySQL이라는 DBMS가 있고 그 위에 응용 프로그램에 속하는 Node.js나 PHP에서 해당 데이터베이스 안에 있는 데이터를 끄집어내 관련 로직을 구축할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.1. 엔터티 (Entity)&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;엔터티는 사람, 장소, 물건, 사건, 개념 등 여러 개의 속성을 지닌 명사를 의미한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 '회원'이라는 엔터티가 있다고 해보자. 회원은 다음과 같은 속성을 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이름&lt;/li&gt;
&lt;li&gt;아이디&lt;/li&gt;
&lt;li&gt;주소&lt;/li&gt;
&lt;li&gt;전화번호&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 이보다 많은 속성이 있지만 서비스의 요구 사항에 맞춰 속성이 정해진다. 주소라는 속성이 서비스의 요구 사항과 무관하다면 주소라는 속성은 사라지게 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;약한 엔터티와 강한 엔터티&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;약한 엔터티&lt;/b&gt;: 혼자서는 존재하지 못하고 다른 엔터티에 종속적인 엔터티&lt;/li&gt;
&lt;li&gt;&lt;b&gt;강한 엔터티&lt;/b&gt;: 단독으로 존재할 수 있는 엔터티&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예: '방'은 '건물' 안에만 존재하므로 &lt;b&gt;방은 약한 엔터티&lt;/b&gt;, &lt;b&gt;건물은 강한 엔터티&lt;/b&gt;.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.2. 릴레이션 (Relation)&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;릴레이션은 데이터베이스에서 정보를 구분하여 저장하는 기본 단위다. 엔터티에 관한 데이터를 데이터베이스는 릴레이션 하나에 담아서 관리한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부르는 이름 데이터베이스 종류&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;테이블(Table)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;관계형 데이터베이스 (MySQL 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;컬렉션(Collection)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;NoSQL 데이터베이스 (MongoDB 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;테이블과 컬렉션의 구조&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MySQL&lt;/b&gt;: 레코드 &amp;rarr; 테이블 &amp;rarr; 데이터베이스&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MongoDB&lt;/b&gt;: 도큐먼트 &amp;rarr; 컬렉션 &amp;rarr; 데이터베이스&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레코드(또는 도큐먼트)가 쌓여서 테이블(또는 컬렉션)이 되고, 그것들이 쌓여 데이터베이스가 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.3. 속성 (Attribute)&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;속성은 릴레이션에서 관리하는 구체적이며 고유한 이름을 갖는 정보다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 '차'라는 엔터티의 속성을 뽑아보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;차 넘버&lt;/li&gt;
&lt;li&gt;바퀴 수&lt;/li&gt;
&lt;li&gt;차 색깔&lt;/li&gt;
&lt;li&gt;차종&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중에서 서비스의 요구 사항을 기반으로 관리해야 할 필요가 있는 속성들만 엔터티의 속성이 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.4. 도메인 (Domain)&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;도메인&lt;/b&gt;이란 릴레이션에 포함된 각각의 속성들이 가질 수 있는 값의 집합을 말한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 '성별'이라는 속성이 있다면 이 속성이 가질 수 있는 값은 {남, 여}라는 집합이 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.5. 필드와 레코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 개념들을 기반으로 데이터베이스에서 필드와 레코드로 구성된 테이블을 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;member 테이블 예시&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;name&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ID&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;address&lt;/td&gt;
&lt;td&gt;phonenumber&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;큰돌&lt;/td&gt;
&lt;td&gt;kundol&lt;/td&gt;
&lt;td&gt;서울&lt;/td&gt;
&lt;td&gt;112&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;가영&lt;/td&gt;
&lt;td&gt;kay&lt;/td&gt;
&lt;td&gt;대전&lt;/td&gt;
&lt;td&gt;114&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;빅뱅&lt;/td&gt;
&lt;td&gt;big&lt;/td&gt;
&lt;td&gt;카이루&lt;/td&gt;
&lt;td&gt;119&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;필드(field)&lt;/b&gt;: 컬럼(name, ID, address, phonenumber)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;레코드(record) = 튜플(tuple)&lt;/b&gt;: 행 단위의 데이터&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;필드 타입&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;필드는 타입을 갖는다. 이름은 문자열이고 전화번호는 숫자다. 이러한 타입들은 DBMS마다 다르다. (이하 MySQL 기준)&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;숫자 타입&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;타입&lt;/td&gt;
&lt;td&gt;용량(바이트)&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;최솟값(부호 있음)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;최댓값(부호 있음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TINYINT&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;-128&lt;/td&gt;
&lt;td&gt;127&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMALLINT&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;-32,768&lt;/td&gt;
&lt;td&gt;32,767&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEDIUMINT&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;-8,388,608&lt;/td&gt;
&lt;td&gt;8,388,607&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INT&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;-2,147,483,648&lt;/td&gt;
&lt;td&gt;2,147,483,647&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BIGINT&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;-2⁶&amp;sup3;&lt;/td&gt;
&lt;td&gt;2⁶&amp;sup3;-1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;날짜 타입&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;DATE&lt;/b&gt;: 날짜 부분은 있지만 시간 부분은 없는 값. 1000-01-01 ~ 9999-12-31. 3바이트.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DATETIME&lt;/b&gt;: 날짜 및 시간 부분을 모두 포함. 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59. 8바이트.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TIMESTAMP&lt;/b&gt;: 날짜 및 시간 부분을 모두 포함. 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07. 4바이트.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;문자 타입&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;CHAR&lt;/b&gt;: 고정 길이 문자열, 0~255 사이. 선언한 길이로 '고정' 저장. CHAR(100)으로 선언 후 10글자를 저장해도 100바이트로 저장.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;VARCHAR&lt;/b&gt;: 가변 길이 문자열, 0~65,535 사이. 입력된 데이터에 따라 용량 가변. 10글자 이메일 저장 시 &amp;rarr; 10바이트 + 길이기록용 1바이트.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TEXT&lt;/b&gt;: 큰 문자열 저장 (게시판 본문 등).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;BLOB&lt;/b&gt;: 이미지, 동영상 등 큰 데이터 저장. 보통은 S3 같은 외부에 파일을 올리고 그 경로를 VARCHAR로 저장.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ENUM&lt;/b&gt;: ENUM('x-small', 'small', 'medium', 'large', 'x-large') 형태. 단일 선택. 최대 65,535개 요소. 메모리 절약 가능.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SET&lt;/b&gt;: ENUM과 비슷하지만 여러 개 선택 가능, 비트 단위 연산. 최대 64개 요소.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;CHAR vs VARCHAR&lt;/b&gt;: 유동적이지 않은 길이의 데이터는 CHAR, 유동적인 길이는 VARCHAR가 효율적.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.6. 관계 (Relationship)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에 테이블은 하나만 있는 것이 아니다. 여러 개의 테이블이 있고, 이러한 테이블은 서로 관계가 정의되어 있다. 이 관계를 &lt;b&gt;관계화살표&lt;/b&gt;로 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계 의미&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;1:1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;하나의 A는 하나의 B로 구성되어 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;1:N&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;하나의 A는 하나 이상의 B로 구성되어 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;1:0~1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;하나의 A는 하나 이하의 B로 구성되어 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;1:0~N&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;하나의 A는 0 또는 하나 이상의 B로 구성되어 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1:1 관계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저당 유저 이메일은 한 개씩 있는 경우. &lt;b&gt;테이블을 두 개의 테이블로 나눠 구조를 더 이해하기 쉽게&lt;/b&gt; 만들어준다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1:N 관계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쇼핑몰에서 한 유저당 여러 개의 상품을 장바구니에 넣는 경우. 한 개체가 다른 많은 개체를 포함하는 관계.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;N:M 관계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학생과 강의의 관계처럼 양쪽 모두 다수가 다수에 속하는 경우. &lt;b&gt;N:M은 테이블 두 개를 직접 연결해서 구축하지 않고 1:N, 1:M 관계를 갖는 테이블 두 개로 나눠서 설정한다&lt;/b&gt;. (학생, 강의 사이에 학생_강의 테이블이 끼게 된다.)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.7. 키 (Key)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 간의 관계를 명확하게 하고 테이블 자체의 인덱스를 위해 설정된 장치. 다음 다섯 가지가 있다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;           ┌─ 슈퍼키 (유일성) ─┐
           │                │
           │  ┌─ 후보키 ─┐    │
           │  │ (최소성) │    │
           │  │ ┌────┐ │     │
           │  │ │기본키│ │     │ &amp;larr; 대체키
           │  │ └────┘  │    │
           │  └─────────┘    │
           └─────────────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;유일성&lt;/b&gt;: 중복되는 값이 없음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최소성&lt;/b&gt;: 필드를 조합하지 않고 최소 필드만 써서 키를 형성&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 기본키 (Primary Key, PK)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유일성과 최소성을 만족하는 키. &lt;b&gt;자연키 또는 인조키 중에 골라 설정&lt;/b&gt;한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- 자연키 (Natural Key)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자연스럽게 뽑아내는 키. 예: 주민등록번호. &lt;b&gt;언젠가는 변하는 속성&lt;/b&gt;을 가진다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- 인조키 (Surrogate Key)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인위적으로 부여한 고유 식별자. 오라클은 sequence, MySQL은 auto_increment 등으로 설정. &lt;b&gt;변하지 않음&lt;/b&gt;. &lt;br /&gt;따라서 보통 기본키는 인조키로 설정한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 외래키 (Foreign Key, FK)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 테이블의 기본키를 그대로 참조하는 값으로, 개체와의 관계를 식별. &lt;b&gt;중복되어도 괜찮다&lt;/b&gt;.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) 후보키 (Candidate Key)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키가 될 수 있는 후보들이며 유일성과 최소성을 동시에 만족하는 키&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) 대체키 (Alternate Key)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후보키가 두 개 이상일 경우 어느 하나를 기본키로 지정하고 남은 후보키들&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5) 슈퍼키 (Super Key)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 레코드를 유일하게 식별할 수 있는 유일성을 갖춘 키&lt;/p&gt;</description>
      <category>CS</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/202</guid>
      <comments>https://hardworkingini.tistory.com/202#entry202comment</comments>
      <pubDate>Tue, 12 May 2026 16:41:39 +0900</pubDate>
    </item>
    <item>
      <title>[운영체제] 2. 메모리</title>
      <link>https://hardworkingini.tistory.com/201</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;2.1 메모리 계층&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;메모리 계층은 &lt;b&gt;레지스터 &amp;rarr; 캐시 &amp;rarr; 메모리(RAM) &amp;rarr; 저장장치(HDD/SDD)&lt;/b&gt; 순으로 구성됨&lt;/blockquote&gt;
&lt;pre id=&quot;code_1777708733567&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;     속도 빠름, 용량 작음, 가격 비쌈
             ▲
             │   ┌─────────────┐
             │   │   레지스터    │  &amp;larr; CPU 안에 있는 작은 메모리
             │   ├─────────────┤
             │   │  캐시(L1,L2) │  &amp;larr; 빠른 임시 저장소
             │   ├─────────────┤
             │   │  메모리(RAM)  │  &amp;larr; 주기억장치
             │   ├─────────────┤
             │   │  HDD / SSD  │  &amp;larr; 보조기억장치
             ▼   └─────────────┘
    속도 느림, 용량 많음&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;계층별 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 53.1395%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.3953%;&quot;&gt;&lt;b&gt;계층&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.2326%;&quot;&gt;&lt;b&gt;휘발성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.9302%;&quot;&gt;&lt;b&gt;속도&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.5814%;&quot;&gt;&lt;b&gt;용량&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.3953%;&quot;&gt;&lt;b&gt;레지스터&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.2326%;&quot;&gt;휘발성&lt;/td&gt;
&lt;td style=&quot;width: 10.9302%;&quot;&gt;가장 빠름&lt;/td&gt;
&lt;td style=&quot;width: 10.5814%;&quot;&gt;가장 적음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.3953%;&quot;&gt;&lt;b&gt;캐시 (L1, L2)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.2326%;&quot;&gt;휘발성&lt;/td&gt;
&lt;td style=&quot;width: 10.9302%;&quot;&gt;빠름&lt;/td&gt;
&lt;td style=&quot;width: 10.5814%;&quot;&gt;적음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.3953%;&quot;&gt;&lt;b&gt;주기억장치 (RAM)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.2326%;&quot;&gt;휘발성&lt;/td&gt;
&lt;td style=&quot;width: 10.9302%;&quot;&gt;보통&lt;/td&gt;
&lt;td style=&quot;width: 10.5814%;&quot;&gt;보통&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.3953%;&quot;&gt;&lt;b&gt;보조기억장치 (HDD/SDD)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.2326%;&quot;&gt;비휘발성&lt;/td&gt;
&lt;td style=&quot;width: 10.9302%;&quot;&gt;느림&lt;/td&gt;
&lt;td style=&quot;width: 10.5814%;&quot;&gt;많음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;왜 계층 구조가 존재하는가?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계층 구조가 있는 이유는 &lt;b&gt;경제성&lt;/b&gt;과 &lt;b&gt;캐시&lt;/b&gt; 때문&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;16GB RAM &amp;rarr; 약 8만 원&lt;/li&gt;
&lt;li&gt;16GB SDD &amp;rarr; 훨씬 더 싼 가격&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계층 위로 올라갈수록 가격을 비싸지는데 용량은 작아지고 속도는 빨라지는 특징이 있음&lt;br /&gt;이러한 경제성 때문에 계층을 둬서 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; &lt;/span&gt; &lt;b&gt;&lt;span data-token-index=&quot;1&quot;&gt;로딩 중&lt;/span&gt; 메시지&lt;/b&gt; = HDD/SSD(보조기억장치) &amp;rarr; RAM(주기억장치)으로 데이터를 전송하는 과정이 아직 끝나지 않음을 의미&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1.1 캐시 (Cache)&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;캐시는 데이터를 미리 복사해 놓는 임시 저장소이자 빠른 장치와 느린 장치에서 속도 차이에 따른 병목 현상을 줄이기 위한 메모리를 말함&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 메모리와 CPU 사이의 속도 차이가 너무 크기 때문에, 그 중간에 레지스터 계층을 두어 속도 차이를 해결&lt;br /&gt;이렇게 속도 차이를 해결하기 위해 계층과 계층 사이에 있는 계층을 캐싱 계층이라고 함&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;지역성의 원리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시를 직접 설정할 때는 자주 사용하는 데이터를 기반으로 설정해야 함&lt;br /&gt;자주 사용하는 데이터의 근거가 되는 것이 바로 &lt;b&gt;지역성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;시간 지역성 (Temporal Locality)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 사용한 데이터에 다시 접근하려는 특성&lt;/p&gt;
&lt;pre id=&quot;code_1777709959090&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 변수 i는 매 반복마다 계속 접근됨 &amp;rarr; 시간 지역성
for (let i = 0; i &amp;lt; 10; i += 1) {
    arr[i] = i;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공간 지역성 (Spatial Locality)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 접근한 데이터를 이루고 있는 공간이나 그 가까운 공간에 접근하려는 특성&lt;/p&gt;
&lt;pre id=&quot;code_1777709967950&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 배열 arr의 각 요소에 순서대로 연속 접근 &amp;rarr; 공간 지역성
for (let i = 0; i &amp;lt; 10; i += 1) {
    arr[i] = i;  // arr[0], arr[1], arr[2]... 연속된 공간 접근
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1.2 캐시히트와 캐시 미스&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 57.2093%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.53488%;&quot;&gt;용어&lt;/td&gt;
&lt;td style=&quot;width: 47.6744%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.53488%;&quot;&gt;캐시히트&lt;/td&gt;
&lt;td style=&quot;width: 47.6744%;&quot;&gt;캐시에서 원하는 데이터를 찾은 경우&lt;br /&gt;CPU 내부 버스를 기반으로 작동하여 빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 9.53488%;&quot;&gt;캐시미스&lt;/td&gt;
&lt;td style=&quot;width: 47.6744%;&quot;&gt;해당 데이터가 캐시에 없어 주 메모리로 가서 데이터를 찾아오는 것&lt;br /&gt;시스템 버스를 기반으로 작동하여 느림&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;캐시매핑&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;캐시매핑이란 캐시가 히트되기 위해 매핑하는 방법을 말함&lt;br /&gt;CPU 레지스터와 주 메모리(RAM) 간에 데이터를 주고받을 때를 기반으로 설명&lt;/blockquote&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 76px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 35%; height: 19px;&quot;&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 65%; height: 19px;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 35%; height: 19px;&quot;&gt;&lt;b&gt;직접 매핑 (Diredted Mapping)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 65%; height: 19px;&quot;&gt;메모리 1 ~ 100이 있고 캐시가 1 ~ 10이 있다면 1 : 1~10, 2 : 20~30 이런 식으로 매핑&lt;br /&gt;처리가 빠르지만 충돌 발생이 잦음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 35%; height: 19px;&quot;&gt;&lt;b&gt;연관 매핑 (Associative Mapping)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 65%; height: 19px;&quot;&gt;순서를 일치시키지 않고 관련 있는 캐시와 메모리를 매핑&lt;br /&gt;충돌이 적지만 모든 블록을 탐색해야 해서 속도가 느림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 35%; height: 19px;&quot;&gt;&lt;b&gt;직접 연관 매핑 (Set Associative Mapping)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 65%; height: 19px;&quot;&gt;직접 매핑과 연관 매핑을 합쳐놓은 것&lt;br /&gt;캐시 1~5에는 1~50의 데이터를 무작위로 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;웹 브라우저의 캐시&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소프트웨어적인 대표적인 캐시로는 웹 브라우저의 작은 저장소 쿠키, 로컬 스토리지, 세션 스토리지가 있음&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.9535%;&quot;&gt;&lt;b&gt;저장소&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 9.18603%;&quot;&gt;&lt;b&gt;만료 기한&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 6.8605%;&quot;&gt;&lt;b&gt;용량&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 70%;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.9535%;&quot;&gt;&lt;b&gt;쿠키&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 9.18603%;&quot;&gt;있음&lt;/td&gt;
&lt;td style=&quot;width: 6.8605%;&quot;&gt;4KB&lt;/td&gt;
&lt;td style=&quot;width: 70%;&quot;&gt;same site 옵션을 strict로 설정하지 않으면 다른 도메인에서 요청 시 자동 전송&lt;br /&gt;httponly 옵션을&amp;nbsp;&lt;br /&gt;서버, 클라이언트 어디에서도 수정 가능하지만 보통 서버에서 정함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.9535%;&quot;&gt;&lt;b&gt;로컬 스토리지&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 9.18603%;&quot;&gt;없음&lt;/td&gt;
&lt;td style=&quot;width: 6.8605%;&quot;&gt;10MB&lt;/td&gt;
&lt;td style=&quot;width: 70%;&quot;&gt;웹 브라우저를 닫아도 유지됨&lt;br /&gt;도메인 단위로 저장&lt;br /&gt;클라이언트에서만 수정 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.9535%;&quot;&gt;&lt;b&gt;세션 스토리지&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 9.18603%;&quot;&gt;없음&lt;/td&gt;
&lt;td style=&quot;width: 6.8605%;&quot;&gt;5MB&lt;/td&gt;
&lt;td style=&quot;width: 70%;&quot;&gt;탭 단위로 생성&lt;br /&gt;탭을 닫을 때 데이터 삭제&lt;br /&gt;클라이언트에서만 수정 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; &lt;/span&gt; &lt;b&gt;&lt;span data-token-index=&quot;1&quot;&gt;데이터베이스의 캐싱 계층&lt;/span&gt;&lt;/b&gt; : 메인 데이터베이스 위에 &lt;span data-token-index=&quot;3&quot;&gt;레디스(redis)&lt;/span&gt; 데이터베이스 계층을 '캐싱 계층'으로 두어 성능을 향상하기도 함&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;2.2 메모리 관리&lt;b&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;운영체제의 대표적인 할 일 중 하나. 컴퓨터 내의 한정된 메모리를 극한으로 활용&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.1 가상 메모리 (Virtual Memory)&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;가상 메모리는 메모리 관리 기법의 하나로 컴퓨터가 실제로 이용 가능한 메모리 자원을 추상화하여 이를 사용하는 사용자들에게 매우 큰 메모리로 보이게 만드는 것&lt;/blockquote&gt;
&lt;pre id=&quot;code_1777770595733&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; 프로세스 A    프로세스 B    프로세스 C
가상 0x0000  가상 0x0000  가상 0x0000
    &amp;darr;           &amp;darr;            &amp;darr;
   ┌─────────────────────────┐
   │     MMU (메모리관리장치)    │
   └─────────────────────────┘
    &amp;darr;           &amp;darr;            &amp;darr;
RAM 0x1000  RAM 0x5000  RAM 0x9000
        (실제로는 서로 다른 공간)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 프로세스는 &quot;혼자 메모리 전체를 사용하는&quot; 착각을 하게 됨&lt;br /&gt;개발자는 실제 메모리의 물리적 위치를 신경 쓰지 않고 프로그램을 구축할 수 있게 됨&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;가상 주소 VS 실제 주소&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.7209%;&quot;&gt;용어&lt;/td&gt;
&lt;td style=&quot;width: 76.2791%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.7209%;&quot;&gt;가상 주소 (logical address)&lt;/td&gt;
&lt;td style=&quot;width: 76.2791%;&quot;&gt;프로세스가 바라보는 주소. 각 프로세스에게 독립적으로 부여&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.7209%;&quot;&gt;실제 주소 (physical address)&lt;/td&gt;
&lt;td style=&quot;width: 76.2791%;&quot;&gt;RAM 위에 실제로 존재하는 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상 주소는 MMU(메모리 관리 장치)에 의해 실제 주소로 변환됨&lt;br /&gt;가살 메모리는 가상 주소와 실제 주소가 매핑되어 있는 페이지 테이블로 관리됨&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TLB&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;TLB는 메모리와 CPU 사이에 있는 주소 변환을 위한 캐시&lt;br /&gt;페이지 테이블에 있는 리스트를 보관하며, CPU가 페이지 테이블까지 가지 않아도 되도록 속도를 향상하는 캐시 계층&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;스와핑 (Swapping)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;가상 메모리에는 존재하지만 실제 메모리인 RAM에는 현재 없는 데이터나 코드에 접근할 경우 페이지 폴트가 발생&lt;br /&gt;이때 메모리에서 당장 사용하지 않는 영역을 HDD/SSD로 옮기고, HDD/SDD의 일부분을 마치 메모리처럼 불러와 쓰는 것이 스와핑&lt;br /&gt;이를 통해 마치 페이지 폴트가 일어나지 않은 것처럼 만듦&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;페이지 폴트 (Page Fault)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;프로세스의 주소 공간에는 존재하지만 지금 이 컴퓨터의 RAM에는 없는 데이터에 접근했을 경우 발생&lt;/blockquote&gt;
&lt;pre id=&quot;code_1777772051200&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;프로세스 가상 주소 공간 (페이지 테이블)
        &amp;darr;
   RAM에 있음? ────YES───&amp;rarr; 정상 접근
        &amp;darr; NO
   페이지 폴트 발생
        &amp;darr;
  HDD/SSD(스왑 영역)에서 RAM으로 불러옴
        &amp;darr;
    스와핑 발동&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;페이지 폴트 처리 과정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. CPU가 물리 메모리를 확인하여 해당 페이지가 없으면 트랩을 발생시켜 운영체제에 알림&lt;br /&gt;2. 운영체제는 CPU 동작을 잠시 멈춤&lt;br /&gt;3. 운영체제가 페이지 테이블을 확인하여 가상 메모리에 페이지가 존재하는지 확인&lt;br /&gt;&amp;nbsp; &amp;nbsp; 없으면 프로세스를 중단하고 물리 메모리에 비어있는 프레임을 찾음&lt;br /&gt;&amp;nbsp; &amp;nbsp; 물리 메모리에도 없다면 스와핑 발동&lt;br /&gt;4. 비어있는 프레임에 해당 페이지를 로드하고 페이지 테이블 최신화&lt;br /&gt;5. 중단되었던 CPU를 다시 시작&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  페이지(page)와 프레임(frame)&lt;br /&gt;페이지는 가상 메모리를 사용하는 최소 크기 단위&lt;br /&gt;프레임은 실제 메모리를 사용하는 최소 크기 단위&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.2 스레싱(Thrashing)&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;메모리의 페이지 폴트율이 높은 것을 의미하며, 컴퓨터의 심각한 성능 저하를 초래&amp;nbsp;&lt;br /&gt;드레싱의 근본 원인은 RAM이 부족해서 프로세스들이 서로 페이지를 차지하려고 경쟁하는 것&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;스레싱 발생 원인 (악순환)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1777773512259&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;너무 많은 프로세스가 메모리에 올라옴
        &amp;darr;
스와핑이 빈번하게 발생
        &amp;darr;
페이지 폴트 발생 &amp;rarr; CPU 이용률 낮아짐
        &amp;darr;
운영체제: &quot;CPU가 한가한가?&quot; &amp;rarr; 더 많은 프로세스를 메모리에 올림
        &amp;darr;
다시 스와핑 증가...   (악순환)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 페이지 폴트가 너무 자주 발생해서 CPU가 실제 연산을 못하게 되는 상황&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;스레싱 해결 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① 작업 세트 (working set)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&quot;자주 쓸 페이지를 미리 RAM에 올려놓자&quot; &amp;rarr; &quot;예방&quot;&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;프로세스의 과거 사용 이력인 지역성(locality)을 통해 결정된 페이지 집합을 만들어서 미리 메모리에 로드하는 방법&lt;br /&gt;미리 메모리에 로드하면 탐색에 드는 비용을 줄일 수 있고 스와핑 또한 줄일 수 있음&lt;/blockquote&gt;
&lt;pre id=&quot;code_1777774449435&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;미리 RAM에 올려둠
    &amp;darr;
페이지 폴트 자체가 안 발생
    &amp;darr;
스와핑 횟수 감소 &amp;rarr; 스레싱 완화 ✅&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② PFF (Page Fault Frequency)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&quot;페이지 폴트 빈도 자체를 직접 조절하자&quot; &amp;rarr; &quot;실시간 모니터링 및 조절&quot;&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;페이지 폴트 빈도를 조절하는 방법으로 &lt;b&gt;상한선&lt;/b&gt;과 &lt;b&gt;하한선&lt;/b&gt;을 만드는 방법&lt;br /&gt;상한선에 도달하면 프레임을 늘리고, 하한선에 도달하면 프레임을 줄임&lt;/blockquote&gt;
&lt;pre id=&quot;code_1777774520683&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;페이지 폴트율이 상한선 초과
    &amp;darr; 프레임 수 늘림
해당 프로세스에 RAM 더 할당
    &amp;darr;
페이지 폴트 감소 ✅&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1777774531262&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;페이지 폴트율이 하한선 미달
    &amp;darr; 프레임 수 줄임
RAM을 다른 프로세스에 양보
    &amp;darr;
전체 메모리 효율 증가 ✅&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;③ 메모리를 늘림&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&quot;근본적인 원인인 메모리 부족 자체를 해결하자&quot; &amp;rarr; 가장 직접적이고 비용이 드는 물리적 해결책&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777775072503&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RAM 부족
    &amp;darr;
여러 프로세스가 RAM 자리를 두고 경쟁
    &amp;darr;
페이지 폴트 폭발 &amp;rarr; 스레싱

RAM을 늘리면
    &amp;darr;
모든 프로세스가 충분한 프레임 확보
    &amp;darr;
페이지 폴트 자체가 줄어듦 ✅&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;④ HDD를 SDD로 바꿈&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&quot;스와핑 자체는 피할 수 없다면, 스와핑 속도를 빠르게 하자&quot;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777775100541&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HDD 스와핑 속도: 매우 느림  
    &amp;darr;
페이지 폴트 발생 시 HDD에서 가져오는 데 오래 걸림
    &amp;darr;
CPU가 오래 대기 &amp;rarr; 이용률 급감 &amp;rarr; 스레싱 심화
────────────────────────────────────────────
SSD로 교체하면
    &amp;darr;
스와핑 속도가 훨씬 빨라짐
    &amp;darr;
페이지 폴트 처리 시간 단축
    &amp;darr;
CPU 대기 시간 감소 &amp;rarr; 스레싱 완화 ✅&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.3 메모리 할당&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;메모리에 프로그램을 할당할 때는 시작 메모리 위치, 메모리의 할당 크기를 기반으로 할당&lt;br /&gt;연속 할당과 불연속 할당으로 나뉨&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;연속 할당&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에 '연속적으로' 공간을 할당하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;① 고정 분할 방식 (Fixed Partition Allocation)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리를 미리 나누어 관리하는 방식&lt;/li&gt;
&lt;li&gt;융통성 없음&lt;/li&gt;
&lt;li&gt;내부 단편화 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;② 가변 분할 방식 (Variable Partition Allocation)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매 시점 프로그램의 크기에 맞게 동적으로 메모리를 나눠 사용&lt;/li&gt;
&lt;li&gt;외부 단편화 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 76px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20.1163%; height: 19px;&quot;&gt;방식&lt;/td&gt;
&lt;td style=&quot;width: 79.8837%; height: 19px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20.1163%; height: 19px;&quot;&gt;최초 적합 (First Fit)&lt;/td&gt;
&lt;td style=&quot;width: 79.8837%; height: 19px;&quot;&gt;위쪽이나 아래쪽부터 시작해서 홀을 찾으면 바로 할당&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20.1163%; height: 19px;&quot;&gt;최적 적합 (Best Fit)&lt;/td&gt;
&lt;td style=&quot;width: 79.8837%; height: 19px;&quot;&gt;프로세스의 크기 이상인 공간 중 가장 작은 홀부터 할당&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20.1163%; height: 19px;&quot;&gt;최악 적합 (Worst Fit)&lt;/td&gt;
&lt;td style=&quot;width: 79.8837%; height: 19px;&quot;&gt;프로세스의 크기와 가장 많이 차이나는 홀에 할당&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;단편화 용어 정리&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.7209%;&quot;&gt;&lt;b&gt;용어&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 76.2791%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.7209%;&quot;&gt;&lt;b&gt;내부 단편화&lt;/b&gt;&lt;br /&gt;&lt;b&gt;(Internal Fragmentation)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 76.2791%;&quot;&gt;메모리를 나눈 크기보다 프로그램이 작아서 들어가지 못하는 공간이 많이 발생하는 현상&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.7209%;&quot;&gt;&lt;b&gt;외부 단편화&lt;/b&gt;&lt;br /&gt;&lt;b&gt;(External Fragmentation)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 76.2791%;&quot;&gt;메모리를 나눈 크기보다 프로그램이 커서 들어가지 못하는 현상&lt;br /&gt;ex) 100MB를 55MB, 45MB로 나눴지만 프로그램이 70MB일 때&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.7209%;&quot;&gt;&lt;b&gt;홀 (Hole)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 76.2791%;&quot;&gt;할당할 수 있는 비어 있는 메모리 공간&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;불연속할당&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리를 연속적으로 할당하지 않는 현대 운영체제가 쓰는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;① 페이징 (Paging)&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;동일한 크기의 페이지 단위로 나누어 메모리의 서로 다른 위치(RAM의 빈 프레임 아무 곳에나)에 프로세스를 할당&lt;br /&gt;홀의 크기가 균일하지 않은 문제가 없어지지만 주소 변환이 복잡해짐&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 주소 변환이 복잡해지는 이유 : 페이징이 주소 변환이 복잡한 이유는 프로세스가 &lt;b&gt;연속된 공간이 아닌 흩어진 프레임에 저장&lt;/b&gt;되기 때문에, CPU가 데이터에 접근할 때마다 &lt;b&gt;&quot;이 페이지가 RAM의 어느 프레임에 있는지&quot;를 페이지 테이블에서 반드시 조회해야 하기 때문&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;rarr; 조회 비용을 줄이기 위해 TLB(주소 변환 캐시) 등장&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;② 세그멘테이션 (Segmentation)&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;페이지 단위가 아닌 의미 단위인 세그먼트(Segment)로 나누는 방식&lt;br /&gt;프로세스를 이루는 메모리는 코드 영역, 데이터 영역, 스택 영역, 힙 영역으로 이루어지는데, 코드와 데이터로 나누거나 코드 내의 작은 함수를 세그먼트로 나눌 수도 있음&lt;br /&gt;공유와 보안 측면에서 장점을 가지지만 홀 크기가 균일하지 않은 단점이 있음&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;③ 페이지 세그멘테이션 (Page Segmentation)&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;프로그램을 의미 단위인 세그먼트로 나눠 공유나 보안 측면에서 장점을 두고, 임의의 길이가 아닌 동일한 크기의 페이지 단위로 나누는 것&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.4 페이지 교체 알고리즘&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;메모리는 한정되어 있기 때문에 스와핑이 자주 발생&lt;br /&gt;스와핑은 많이 일어나지 않도록 설계되어야 하며, 이는 페이지 교체 알고리즘을 기반으로 함&lt;/blockquote&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7287%;&quot;&gt;알고리즘&lt;/td&gt;
&lt;td style=&quot;width: 41.589%;&quot;&gt;설명&lt;/td&gt;
&lt;td style=&quot;width: 43.6822%;&quot;&gt;특징&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7287%;&quot;&gt;오프라인 알고리즘&lt;/td&gt;
&lt;td style=&quot;width: 41.589%;&quot;&gt;먼 미래에 참조되는 페이지와 현재 할당하는 페이지를 &lt;br /&gt;바꾸는 방법&lt;/td&gt;
&lt;td style=&quot;width: 43.6822%;&quot;&gt;가장 좋지만 미래를 알 수 없어 사용 불가&lt;br /&gt;다른 알고리즘의 상한기준 (upper_bound)제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7287%;&quot;&gt;FIFO&lt;/td&gt;
&lt;td style=&quot;width: 41.589%;&quot;&gt;가장 먼저 온 페이지를 교체 영역에 가장 먼저 놓는 방법&lt;/td&gt;
&lt;td style=&quot;width: 43.6822%;&quot;&gt;구현 단순&lt;br /&gt;자주 쓰는 페이지도 오래됐다는 이유로 교체될 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7287%;&quot;&gt;LRU&lt;/td&gt;
&lt;td style=&quot;width: 41.589%;&quot;&gt;참조가 가장 오래된 페이지를 바꿈&lt;/td&gt;
&lt;td style=&quot;width: 43.6822%;&quot;&gt;각 페이지마다 계수기, 스택을 두어야하는 문제점 존재&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7287%;&quot;&gt;NUR &lt;br /&gt;(clock 알고리즘)&lt;/td&gt;
&lt;td style=&quot;width: 41.589%;&quot;&gt;0과 1의 비트를 두고 시계 방향으로 돌면서0을 찾아 &lt;br /&gt;교체하고 1로 바꿈&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 43.6822%;&quot;&gt;LRU에서 발전한 방식&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.7287%;&quot;&gt;LFU&lt;/td&gt;
&lt;td style=&quot;width: 41.589%;&quot;&gt;가장 참조 횟수가 적은 페이지를 교체&lt;/td&gt;
&lt;td style=&quot;width: 43.6822%;&quot;&gt;많이 사용되지 않은 것을 교체&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LRU 구현 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LRU를 프로그래밍으로 구현할 때는 보통 &lt;span data-token-index=&quot;1&quot;&gt;해시 테이블 + 이중 연결 리스트&lt;/span&gt; 두 개의 자료구조로 구현&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.2093%;&quot;&gt;자료구조&lt;/td&gt;
&lt;td style=&quot;width: 82.7907%;&quot;&gt;역할&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.2093%;&quot;&gt;해시 테이블&lt;/td&gt;
&lt;td style=&quot;width: 82.7907%;&quot;&gt;이중 연결 리스트에서 특정 페이지를 &lt;span data-token-index=&quot;1&quot;&gt;O(1)&lt;/span&gt; 에 빠르게 찾을 수 있도록&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.2093%;&quot;&gt;이중 연결 리스트&lt;/td&gt;
&lt;td style=&quot;width: 82.7907%;&quot;&gt;한정된 메모리를 나타냄. 가장 최근에 사용된 순서 유지&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>CS</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/201</guid>
      <comments>https://hardworkingini.tistory.com/201#entry201comment</comments>
      <pubDate>Sun, 3 May 2026 12:05:07 +0900</pubDate>
    </item>
    <item>
      <title>[운영체제] 1. 운영체제와 컴퓨터</title>
      <link>https://hardworkingini.tistory.com/200</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;1.1 운영체제&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;운영체제 (OS, Operating System)은 사용자가 컴퓨터를 쉽게 다루게 해 주는 인터페이스&lt;br /&gt;한정된 메모리나 시스템 자원을 효율적으로 분배하는 일꾼&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; &lt;/span&gt; &lt;b&gt;&lt;span data-token-index=&quot;1&quot;&gt;펌웨어(firmware)&lt;/span&gt;&lt;/b&gt; : 운영체제와 유사하지만 소프트웨어를 추가로 설치할 수 없는 것&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1.1 운영체제의 역할&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7674%;&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75.2326%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7674%;&quot;&gt;&lt;b&gt;CPU 스케줄링과 프로세스 관리&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75.2326%;&quot;&gt;CPU 소유권을 어떤 프로세스에 할당할 지, 프로세스의 생성, 삭제, 자원 할당 및 반환 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7674%;&quot;&gt;&lt;b&gt;메모리 관리&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75.2326%;&quot;&gt;한정된 메모리를 어떤 프로세스에 얼마큼 할당해야 하는지 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7674%;&quot;&gt;&lt;b&gt;디스크 파일 관리&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75.2326%;&quot;&gt;디스크 파일을 어떠한 방법으로 보관할지 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7674%;&quot;&gt;&lt;b&gt;I/O 디바이스 관리&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75.2326%;&quot;&gt;I/O 디바이스인 마우스, 키보드, 컴퓨터 간에 데이터를 주고받는 것을 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1.2 운영체제의 구조&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1777705855272&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;유저 프로그램
    &amp;darr;
   GUI          &amp;larr; 사용자가 보는 화면            ┐
    &amp;darr;                                       
 시스템콜         &amp;larr; 커널에 접근하기 위한 인터페이스   │  
    &amp;darr;                                         운영체제
   커널          &amp;larr; 운영체제의 핵심               │ 
    &amp;darr;                                        
 드라이버         &amp;larr; 하드웨어를 제어하는 소프트웨어    ┘
    &amp;darr;
 하드웨어&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GUI : 사용자가 전자장치와 상호 작용할 수 있도록 하는 인터페이스&lt;/li&gt;
&lt;li&gt;CUI : 그래픽이 아닌 명령어로 처리하는 인터페이스 (ex. 리눅스 서버)&lt;/li&gt;
&lt;li&gt;시스템콜 : 운영체제가 커널에 접근하기 위한 인터페이스&lt;/li&gt;
&lt;li&gt;커널 : 운영체제의 핵심 부분, 시스템콜 인터페이스를 제공하며 운영체제의 중추적인 역할 수행&lt;/li&gt;
&lt;li&gt;드라이버 : 하드웨어를 제어하기 위한 소프트웨어&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;시스템콜&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;시스템콜이란 운영체제가 커널에 접근하기 위한 인터페이스&lt;br /&gt;유저 프로그램이 운영체제의 서비스를 받기 위해 커널 함수를 호출할 때 사용&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;시스템콜의 역할&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템콜은 &lt;b&gt;추상화 계층&lt;/b&gt;의 역할을 수행&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 통신, 데이터베이스 같은 낮은 단계의 처리를 직접 구현하지 않아도 됨&lt;/li&gt;
&lt;li&gt;fs.readfile()같은 함수 호출만으로 파일 시스템에 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;동작 흐름 (I/O 요청 예시)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777706113572&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;유저 프로그램이 fs.readFile() 호출
        &amp;darr;
    시스템콜 호출 (트랩 발생)
        &amp;darr;
  modebit 1 &amp;rarr; 0 (유저모드 &amp;rarr; 커널모드)
        &amp;darr;
    파일 시스템에서 파일 읽기 수행
        &amp;darr;
  modebit 0 &amp;rarr; 1 (커널모드 &amp;rarr; 유저모드)
        &amp;darr;
    이후 유저 프로그램 로직 수행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정을 통해 컴퓨터 자원에 대한 직접 접근을 차단하고, 프로그램을 다른 프로그램으로부터 보호할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;modebit&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;시스템콜이 작동될 때 modebit을 참고해서 유저 모드와 커널 모드를 구분&lt;br /&gt;modebit은 1또는 0의 값을 가지는 플래그 변수&lt;/blockquote&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 10.31%;&quot;&gt;modebit&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 11.2403%;&quot;&gt;mode&lt;/td&gt;
&lt;td style=&quot;width: 78.4496%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 10.31%;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 11.2403%;&quot;&gt;유저 모드&lt;/td&gt;
&lt;td style=&quot;width: 78.4496%;&quot;&gt;유저가 접근할 수 있는 영역을 제한적으로 두며, 컴퓨터 자원에 함부로 침범하지 못하는 모드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 10.31%;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 11.2403%;&quot;&gt;커널 모드&lt;/td&gt;
&lt;td style=&quot;width: 78.4496%;&quot;&gt;모든 컴퓨터 자원에 접근할 수 있는 모드&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;modebit이 필요한 이유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카메라, 키보드와 같은 I/O 디바이스는 반드시 운영체제를 통해서만 작동을 해야 함&lt;br /&gt;만약 유저 모드에서 직접 제어가 가능하다면, 공격자가 사용자의 동의 없이 카메라를 켜거나 키 입력을 가로채는 일이 가능해짐&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;1.2 컴퓨터의 요소&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터는 운영체제, CPU, DMA 컨트롤러, 메모리, 타이머, 디바이스 컨트롤러 등으로 이루어져 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;930&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PooVa/dJMcabqx8QM/kRklyZ3zsVsfM5nLUKg60K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PooVa/dJMcabqx8QM/kRklyZ3zsVsfM5nLUKg60K/img.png&quot; data-alt=&quot;컴퓨터의 요소&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PooVa/dJMcabqx8QM/kRklyZ3zsVsfM5nLUKg60K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPooVa%2FdJMcabqx8QM%2FkRklyZ3zsVsfM5nLUKg60K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;441&quot; height=&quot;267&quot; data-origin-width=&quot;930&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컴퓨터의 요소&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2.1 CPU&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;CPU (Central Processing Unit)은 산술논리연산장치, 제어장치, 레지스터로 구성되어 있는 컴퓨터 장치를 말함&lt;br /&gt;인터럽트에 의해 단순히 메모리에 존재하는 명령어를 해석해서 실행하는 일꾼&amp;nbsp;&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CPU의 구성요소&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.3256%;&quot;&gt;구성 요소&lt;/td&gt;
&lt;td style=&quot;width: 62.6744%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.3256%;&quot;&gt;제어 장치 (CU, Control Unit)&lt;/td&gt;
&lt;td style=&quot;width: 62.6744%;&quot;&gt;프로세스 조작을 지시하는 CPU의 한 부품&lt;br /&gt;입출력장치 간 통신을 제어하고 명령어를 읽고 해석하며 데이터 처리를 위한 순서 결정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.3256%;&quot;&gt;레지스터 (register)&lt;/td&gt;
&lt;td style=&quot;width: 62.6744%;&quot;&gt;CPU 안에 있는 매우 빠른 임시기억장치&lt;br /&gt;CPU와 직접 연결되어 있어 연산 속도가 메모리보다 수십 ~ 수백 배 빠름&lt;br /&gt;CPU는 자체적으로 데이터를 저장할 방법이 없기 때문에 레지스터를 거쳐 데이터를 전달&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.3256%;&quot;&gt;산술논리연산장치 (ALU, Arithmetic Logic Unit)&lt;/td&gt;
&lt;td style=&quot;width: 62.6744%;&quot;&gt;덧셈, 뺄셈 같은 두 숫자의 산술 연산과 배타적 논리합, 논리곱 같은 논리 연산을 계산하는 디지털 회로&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CPU 연산 처리 흐름&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1777706720737&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;① 제어장치가 메모리에 계산할 값을 로드 + 레지스터로 로드
② 제어장치가 레지스터에 있는 값을 계산하라고 산술논리연산장치에 명령
③ 제어장치가 계산된 값을 다시 '레지스터에서 메모리로' 저장&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;인터럽트(Interrupt)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;인터럽트란 어떤 신호가 들어왔을 때 CPU를 잠깐 정지시키는 것&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터럽트가 발생하면 인터럽트 벡터로 이동해 인터럽트 핸들러 함수가 실행됨&lt;br /&gt;인터럽트 간에는 우선순위가 있고, 그 우선순위에 따라 실행됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;인터럽트 종류&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.3333%;&quot;&gt;종류&lt;/td&gt;
&lt;td style=&quot;width: 43.3333%;&quot;&gt;설명&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;예시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.3333%;&quot;&gt;하드웨어 인터럽트&lt;/td&gt;
&lt;td style=&quot;width: 43.3333%;&quot;&gt;IO 디바이스에서 발생하는 인터럽트&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;키보드 연결, 마우스 클릭&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 23.3333%;&quot;&gt;소트트웨어 인터럽트 (= 트랩)&lt;/td&gt;
&lt;td style=&quot;width: 43.3333%;&quot;&gt;프로세스 오류 등으로 프로세스가 시스템콜을 호출할 때 발생&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;0으로 나누기, 프로세스 오류&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; &lt;/span&gt; &lt;b&gt;&lt;span data-token-index=&quot;1&quot;&gt;인터럽트 핸들러 함수 &lt;/span&gt;&lt;/b&gt;&lt;span data-token-index=&quot;1&quot;&gt;: &lt;/span&gt;인터럽트가 발생했을 때 이를 핸들링하기 위한 함수&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 커널 내부의 IRQ를 통해 호출되며 request_irq()를 통해 등록&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2.2 DMA 컨트롤러&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;DMA 컨트롤러는 I/O 디바이스가 메모리에 직접 접근할 수 있도록 하는 하드웨어 장치&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU에만 너무 많은 인터럽트 요청이 들어오기 때문에 CPU 부하를 막아주는 보조 일꾼&lt;/li&gt;
&lt;li&gt;하나의 작업을 CPU와 DMA 컨트롤러가 동시에 하는 것을 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2.3 메모리(Memory)&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;메모리(RAM)은 전자회로에서 데이터나 상태, 명령어 등을 기록하는 장치&lt;br /&gt;CPU는 계산을 담당하고 메모리는 기억을 담당&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공장에 비유하자면 CPU는 일꾼이고, 메모리는 작업장&lt;br /&gt;작업장이 클수록 창고에서 물건을 많이 가져다 놓고 많은 일을 할 수 있듯이, 메모리가 크면 클수록 많은 일을 동시에 할 수 있음&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2.4 타이머(Timer)&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;타이머는 몇 초 안에는 작업이 끝나야 한다는 것을 정하고 특정 프로그램에 시간 제한을 다는 역할&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시간이 많이 걸리는 프로그램이 작동할 때 제한을 걸기 위해 존재&lt;/li&gt;
&lt;li&gt;타이머가 없다 -&amp;gt; 하나의 프로그램이 CPU를 무한정 독점하는 상황 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.2.5 디바이스 컨트롤러 (Device Controller)&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;디바이스 컨트롤러는 컴퓨터와 연결되어 있는 IO 디바이스들의 작은 CPU&lt;br /&gt;옆에 붙어 있는 로컬 버퍼는 각 디바이스에서 데이터를 임시로 저장하기 위한 작은 메모리&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/200</guid>
      <comments>https://hardworkingini.tistory.com/200#entry200comment</comments>
      <pubDate>Sat, 2 May 2026 16:51:31 +0900</pubDate>
    </item>
    <item>
      <title>[Langflow] Langflow API Key 생성</title>
      <link>https://hardworkingini.tistory.com/199</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;API keys 와 authentication(인증)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow는 외부 요청과 내부 서비스 연결을 보호하기 위해 &lt;b&gt;인증 자격 증명(Authentication credentials)&lt;/b&gt; 을 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증 자격 증명의 종류는 다음 &lt;b&gt;3가지&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;LangFlow API Keys&lt;/b&gt;&amp;rarr; Flow 실행, 파일 업로드 등 &lt;b&gt;서버 측 작업 승인&lt;/b&gt;에 사용&lt;/li&gt;
&lt;li&gt;&amp;rarr; LangFlow 서버 자체를 호출하기 위한 인증 키&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Component API Keys&lt;/b&gt;&amp;rarr; 예: OpenAI, Gemini, 서드파티 API 등&lt;/li&gt;
&lt;li&gt;&amp;rarr; 모델 제공자 또는 외부 서비스(API)와 통신할 때 사용하는 키&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Authentication Environment Variables&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&amp;rarr; LangFlow 서버의 &lt;b&gt;사용자 인증(Authentication)&lt;/b&gt; 및 &lt;b&gt;권한 부여(Authorization)&lt;/b&gt; 동작을 설정하는 환경 변수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;+) ⚠️ 보안 관련 주의 사항&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow 포트를 &lt;b&gt;아무 보안 설정 없이 인터넷에 직접 노출하는 것은 권장되지 않음&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;다음 보안 설정을 함께 사용하는 것을 권장함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LANGFLOW_AUTO_LOGIN=False 설정&lt;/li&gt;
&lt;li&gt;기본값이 아닌 &lt;b&gt;커스텀 LANGFLOW_SECRET_KEY 사용&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;인증이 활성화된 &lt;b&gt;Reverse Proxy 뒤에 LangFlow 서버 배포&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. LangFlow API Keys&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow API Key는 &lt;b&gt;LangFlow를 코드나 외부 애플리케이션에서 프로그래밍 방식으로 사용&lt;/b&gt;하기 위해 사용됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow API Key를 사용하면 LangFlow 서버와 API를 통해 상호작용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;기본적으로 LangFlow의 &lt;b&gt;대부분 API 엔드포인트&lt;/b&gt;는 LangFlow API Key 인증이 필요합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: /api/v1/run/{FLOW_ID}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LangFlow API Key는 다음과 같은 &lt;b&gt;서버 측 작업&lt;/b&gt;을 승인합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Flow 실행&lt;/li&gt;
&lt;li&gt;파일 업로드&lt;/li&gt;
&lt;li&gt;기타 LangFlow API 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ LangFlow MCP 서버의 인증 설정에 대해서는 &lt;b&gt;Use Langflow as an MCP server&lt;/b&gt; 문서(&lt;a href=&quot;https://docs.langflow.org/mcp-server&quot;&gt;https://docs.langflow.org/mcp-server&lt;/a&gt;) 를 참고합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. API Key 권한&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본 동작 방식&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow API Key는 &lt;b&gt;생성한 사용자의 권한을 그대로 상속&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li&gt;즉, API Key는 별도의 권한을 가지지 않으며,&lt;/li&gt;
&lt;li&gt;&lt;b&gt;API Key를 만든 사용자와 동일한 권한과 접근 범위&lt;/b&gt;를 가집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API Key로 접근 가능한 범위는 다음을 포함합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;본인이 생성한 Flow&lt;/li&gt;
&lt;li&gt;사용 가능한 컴포넌트&lt;/li&gt;
&lt;li&gt;LangFlow 데이터베이스 리소스&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, LangFlow API Key는 &lt;b&gt;자신의 LangFlow 서버 외부 리소스에는 접근할 수 없습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;환경별 권한 동작 차이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① 싱글 유저 환경 (Single-user)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버 사용자는 항상 &lt;b&gt;슈퍼유저(superuser)&lt;/b&gt; 로 동작&lt;/li&gt;
&lt;li&gt;생성한 LangFlow API Key 역시 항상 &lt;b&gt;슈퍼유저 권한&lt;/b&gt;을 가짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② 멀티 유저 환경 (Multi-user)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;슈퍼유저가 아닌 사용자는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;다른 사용자의 리소스에 접근할 수 없음&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용자 관리 및 일반 사용자 계정을 사용하려면
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow 서버를 &lt;b&gt;authentication enabled 상태로 실행해야 함&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. LangFlow API Key 생성 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow API Key는 다음 &lt;b&gt;두 가지 방법&lt;/b&gt;으로 생성할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow &lt;b&gt;Settings(UI)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;LangFlow &lt;b&gt;CLI&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4.1 LangFlow Settings에서 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow 프론트엔드(UI)가 실행 중인 경우 사용할 수 있는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;생성 절차&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. LangFlow 상단 헤더에서 &lt;b&gt;프로필 아이콘 클릭&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LCUCr/dJMcachmsrj/bklM3EhegSaNjmappRWCOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LCUCr/dJMcachmsrj/bklM3EhegSaNjmappRWCOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LCUCr/dJMcachmsrj/bklM3EhegSaNjmappRWCOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLCUCr%2FdJMcachmsrj%2FbklM3EhegSaNjmappRWCOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;320&quot; height=&quot;411&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;Settings&lt;/b&gt; 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3014&quot; data-origin-height=&quot;1900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpAhwx/dJMcadmY2av/myi9WaKOWikTCKxEakC1hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpAhwx/dJMcadmY2av/myi9WaKOWikTCKxEakC1hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpAhwx/dJMcadmY2av/myi9WaKOWikTCKxEakC1hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpAhwx%2FdJMcadmY2av%2Fmyi9WaKOWikTCKxEakC1hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3014&quot; height=&quot;1900&quot; data-origin-width=&quot;3014&quot; data-origin-height=&quot;1900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;LangFlow API Keys&lt;/b&gt; 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3016&quot; data-origin-height=&quot;1892&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLVDBb/dJMcahJKVv4/ZgQJlICLSzUCILxRzP1tlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLVDBb/dJMcahJKVv4/ZgQJlICLSzUCILxRzP1tlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLVDBb/dJMcahJKVv4/ZgQJlICLSzUCILxRzP1tlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLVDBb%2FdJMcahJKVv4%2FZgQJlICLSzUCILxRzP1tlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3016&quot; height=&quot;1892&quot; data-origin-width=&quot;3016&quot; data-origin-height=&quot;1892&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;b&gt;Add New&lt;/b&gt; 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1322&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PZhw0/dJMcafE98qc/5b3ROyCe6fJcfzOpToDLLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PZhw0/dJMcafE98qc/5b3ROyCe6fJcfzOpToDLLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PZhw0/dJMcafE98qc/5b3ROyCe6fJcfzOpToDLLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPZhw0%2FdJMcafE98qc%2F5b3ROyCe6fJcfzOpToDLLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1322&quot; height=&quot;630&quot; data-origin-width=&quot;1322&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. API Key 이름 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcl8bW/dJMcagqwSN8/fPo3cMKbdBgycns0agvnQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcl8bW/dJMcagqwSN8/fPo3cMKbdBgycns0agvnQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcl8bW/dJMcagqwSN8/fPo3cMKbdBgycns0agvnQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcl8bW%2FdJMcagqwSN8%2FfPo3cMKbdBgycns0agvnQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1244&quot; height=&quot;548&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.&lt;b&gt; Create API Key&lt;/b&gt; 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccSUNp/dJMcaiPnhXR/jQfKgEvK5kJuNLeeK2pGN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccSUNp/dJMcaiPnhXR/jQfKgEvK5kJuNLeeK2pGN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccSUNp/dJMcaiPnhXR/jQfKgEvK5kJuNLeeK2pGN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccSUNp%2FdJMcaiPnhXR%2FjQfKgEvK5kJuNLeeK2pGN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1242&quot; height=&quot;564&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 생성된 API Key를 &lt;b&gt;복사하여 안전하게 저장&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ API Key는 &lt;b&gt;생성 직후에만 전체 값을 확인할 수 있으므로 반드시 저장해야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4.2 LangFlow CLI에서 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow 서버가 --backend-only=true 모드로 실행 중인 경우에는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드가 없기 때문에 &lt;b&gt;Settings UI에서 API Key를 생성할 수 없습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 &lt;b&gt;LangFlow CLI를 사용해야 합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CLI 생성이 필요한 경우&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow 서버가 --backend-only=true 모드로 실행 중인 경우&lt;/li&gt;
&lt;li&gt;프론트엔드(UI)가 실행되지 않는 환경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;API Key 생성 명령어&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;uv run langflow api-key
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4.3 인증 활성화 권장 사항 (추천)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow 팀은 &lt;b&gt;보안상의 이유로 인증을 활성화한 상태로 서버를 실행할 것을 권장&lt;/b&gt;합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인증이 활성화된 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;무단 API Key 생성 방지 가능&lt;/li&gt;
&lt;li&gt;슈퍼유저 계정 관리 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인증이 비활성화된 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 사용자가 사실상 &lt;b&gt;슈퍼유저&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;누구나 CLI를 통해 API Key 생성 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(LANGFLOW_AUTO_LOGIN=True)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 &lt;b&gt;운영(Production) 환경&lt;/b&gt;에서는 인증 활성화가 권장됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4.4 CLI로 생성된 API Key의 권한&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow CLI로 생성된 API Key는 &lt;b&gt;항상 슈퍼유저 권한&lt;/b&gt;을 가짐&lt;/li&gt;
&lt;li&gt;이유:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;langflow api-key 명령은 &lt;b&gt;슈퍼유저 인증을 필요로 함&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;LangFlow API Key는 &lt;b&gt;생성한 사용자의 권한을 그대로 상속&lt;/b&gt;함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. LangFlow API Key 사용 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow API 요청 시 인증을 위해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LangFlow API Key를 헤더 또는 쿼리 파라미터로 전달&lt;/b&gt;해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5.1 HTTP Header 방식 (권장)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;julia&quot;&gt;&lt;code&gt;curl -X POST \\
  &quot;http://$LANGFLOW_SERVER_ADDRESS/api/v1/run/$FLOW_ID?stream=false&quot; \\
  -H &quot;Content-Type: application/json&quot; \\
  -H &quot;x-api-key: $LANGFLOW_API_KEY&quot; \\
  -d '{&quot;inputs&quot;: {&quot;text&quot;:&quot;&quot;}, &quot;tweaks&quot;: {}}'
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;x-api-key 헤더에 LangFlow API Key 전달&lt;/li&gt;
&lt;li&gt;공식 문서에서 기본 예제로 사용하는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5.2 Query Parameter 방식 (대안)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;julia&quot;&gt;&lt;code&gt;curl -X POST \\
  &quot;http://$LANGFLOW_SERVER_ADDRESS/api/v1/run/$FLOW_ID?x-api-key=$LANGFLOW_API_KEY&quot; \\
  -H &quot;Content-Type: application/json&quot; \\
  -d '{&quot;inputs&quot;: {&quot;text&quot;:&quot;&quot;}, &quot;tweaks&quot;: {}}'
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;URL 쿼리 파라미터로 API Key 전달&lt;/li&gt;
&lt;li&gt;헤더 사용이 어려운 경우의 대안&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. API Key 사용 기록(Tracking)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본적으로 LangFlow는 API Key 사용 정보를 DB에 기록함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;total_uses&lt;/li&gt;
&lt;li&gt;last_used_at&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용 기록 비활성화&lt;/h3&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_DISABLE_TRACK_APIKEY_USAGE=True
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;높은 동시성 환경에서
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB 경합(Database contention)을 줄이기 위한 용도&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. LangFlow API Key 삭제(Revoke)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API Key를 삭제하면 &lt;b&gt;즉시 무효화&lt;/b&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;삭제 절차&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. LangFlow 상단 헤더 &amp;rarr; 프로필 아이콘 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LCUCr/dJMcachmsrj/bklM3EhegSaNjmappRWCOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LCUCr/dJMcachmsrj/bklM3EhegSaNjmappRWCOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LCUCr/dJMcachmsrj/bklM3EhegSaNjmappRWCOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLCUCr%2FdJMcachmsrj%2FbklM3EhegSaNjmappRWCOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;320&quot; height=&quot;411&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;Settings&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3014&quot; data-origin-height=&quot;1900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpAhwx/dJMcadmY2av/myi9WaKOWikTCKxEakC1hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpAhwx/dJMcadmY2av/myi9WaKOWikTCKxEakC1hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpAhwx/dJMcadmY2av/myi9WaKOWikTCKxEakC1hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpAhwx%2FdJMcadmY2av%2Fmyi9WaKOWikTCKxEakC1hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3014&quot; height=&quot;1900&quot; data-origin-width=&quot;3014&quot; data-origin-height=&quot;1900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;LangFlow API Keys&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;1896&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nzPet/dJMcajtYkRz/vn4u8GztdRGWOq5gXNuLKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nzPet/dJMcajtYkRz/vn4u8GztdRGWOq5gXNuLKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nzPet/dJMcajtYkRz/vn4u8GztdRGWOq5gXNuLKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnzPet%2FdJMcajtYkRz%2Fvn4u8GztdRGWOq5gXNuLKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3024&quot; height=&quot;1896&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;1896&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 삭제할 Key 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2392&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TxkWG/dJMcaiV8Lyz/Haxk5li4tuJKxpgo6ZIJcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TxkWG/dJMcaiV8Lyz/Haxk5li4tuJKxpgo6ZIJcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TxkWG/dJMcaiV8Lyz/Haxk5li4tuJKxpgo6ZIJcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTxkWG%2FdJMcaiV8Lyz%2FHaxk5li4tuJKxpgo6ZIJcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2392&quot; height=&quot;480&quot; data-origin-width=&quot;2392&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. &lt;b&gt;Delete(쓰레기통 아이콘)&lt;/b&gt;&amp;nbsp;클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2382&quot; data-origin-height=&quot;1490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOVz6A/dJMcagjK91O/YLlo24GCdXtMZY0ZoCMUUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOVz6A/dJMcagjK91O/YLlo24GCdXtMZY0ZoCMUUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOVz6A/dJMcagjK91O/YLlo24GCdXtMZY0ZoCMUUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOVz6A%2FdJMcagjK91O%2FYLlo24GCdXtMZY0ZoCMUUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2382&quot; height=&quot;1490&quot; data-origin-width=&quot;2382&quot; data-origin-height=&quot;1490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8. Component API Keys&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개념&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Component API Key는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Flow 내 컴포넌트가 호출하는 &lt;b&gt;외부 서비스 인증용 키&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LangFlow API Key와는 &lt;b&gt;완전히 별개&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 예&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LLM 모델 제공자 (OpenAI, Gemini 등)&lt;/li&gt;
&lt;li&gt;데이터베이스&lt;/li&gt;
&lt;li&gt;서드파티 API&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관리 방식&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Component API Key는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;서비스 제공자 플랫폼에서 직접 생성&amp;middot;관리&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LangFlow는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;암호화된 키 값 또는&lt;/li&gt;
&lt;li&gt;외부 저장소의 안전한 참조만 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ LangFlow에서 변수를 삭제해도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; &lt;b&gt;실제 서비스 제공자의 API Key는 삭제되지 않음&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 반드시 제공자 측에서 직접 삭제 또는 회전 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보안 옵션&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_REMOVE_API_KEYS=True
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Flow 데이터 DB에서
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API Key / Token 제거&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Flow JSON Export 시
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API Key 제외 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;9. Authentication Environment Variables&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow 인증 동작을 제어하는 환경 변수들입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.env.example 파일을 템플릿으로 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;9.1 LANGFLOW_AUTO_LOGIN&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow 서버 접근 시 &lt;b&gt;인증 요구 여부&lt;/b&gt;를 제어합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;LANGFLOW_AUTO_LOGIN=False&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자동 로그인 비활성화&lt;/li&gt;
&lt;li&gt;요구 사항
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시각적 에디터 로그인 필요&lt;/li&gt;
&lt;li&gt;CLI 일부 명령은 슈퍼유저 인증 필요&lt;/li&gt;
&lt;li&gt;API 요청 시 LangFlow API Key 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;권장 설정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LANGFLOW_SUPERUSER&lt;/li&gt;
&lt;li&gt;LANGFLOW_SUPERUSER_PASSWORD 명시적 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;LANGFLOW_AUTO_LOGIN=True (기본값)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시각적 에디터가 비밀번호 없이 슈퍼유저로 자동 로그인&lt;/li&gt;
&lt;li&gt;모든 사용자가 슈퍼유저로 동작&lt;/li&gt;
&lt;li&gt;CLI 명령 슈퍼유저 권한으로 실행 가능&lt;/li&gt;
&lt;li&gt;API 요청은 &lt;b&gt;여전히 LangFlow API Key 필요&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 운영 환경에서는 권장되지 않음&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;10. 기본 인증 정책 및 버전별 변화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LangFlow v1.6 기준&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본값
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LANGFLOW_AUTO_LOGIN=True&lt;/li&gt;
&lt;li&gt;LANGFLOW_SKIP_AUTH_AUTO_LOGIN=False&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;API 요청에 대해서만 인증 강제&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이전 버전 호환성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;v1.5
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API 인증 강제 도입&lt;/li&gt;
&lt;li&gt;하위 호환을 위해 LANGFLOW_SKIP_AUTH_AUTO_LOGIN 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;v1.5 이전
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API 요청 인증 없음&lt;/li&gt;
&lt;li&gt;모든 사용자가 슈퍼유저&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ 향후 버전에서는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LANGFLOW_AUTO_LOGIN=False 기본값 예정&lt;/li&gt;
&lt;li&gt;LANGFLOW_SKIP_AUTH_AUTO_LOGIN 제거 예정&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;11. 인증 및 슈퍼유저 관련 환경 변수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;11.1 LANGFLOW_ENABLE_SUPERUSER_CLI&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow CLI에서 langflow superuser 명령 사용 가능 여부를 제어&lt;/li&gt;
&lt;li&gt;기본값: True&lt;/li&gt;
&lt;li&gt;보안상 권장값: False&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;True일 경우:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;누구든지 CLI를 통해 슈퍼유저 계정 생성 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;False일 경우:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;무제한 슈퍼유저 생성 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관련 문서: langflow superuser&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;11.2 LANGFLOW_SUPERUSER / LANGFLOW_SUPERUSER_PASSWORD&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow 서버의 &lt;b&gt;슈퍼유저 계정 정보&lt;/b&gt;를 지정하는 환경 변수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_SUPERUSER=administrator
LANGFLOW_SUPERUSER_PASSWORD=securepassword
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동작 조건&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LANGFLOW_AUTO_LOGIN=False 인 경우 &lt;b&gt;필수&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;LANGFLOW_AUTO_LOGIN=True 인 경우에는 의미 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주의 사항&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인증이 활성화된 상태에서 해당 값이 설정되지 않으면:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본값 langflow / langflow 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이 기본값은
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;langflow superuser CLI 명령에는 적용되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;11.3 LANGFLOW_SECRET_KEY&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API Key 등 &lt;b&gt;민감한 데이터를 암호화&lt;/b&gt;하는 데 사용되는 비밀 키&lt;/li&gt;
&lt;li&gt;LangFlow는 &lt;b&gt;Fernet 라이브러리&lt;/b&gt;를 사용하여 암호화 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본 동작&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;값이 설정되지 않으면 LangFlow가 자동으로 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;운영 환경 권장 사항&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Production 환경에서는 &lt;b&gt;반드시 직접 생성하여 명시적으로 설정 권장&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Kubernetes 등 &lt;b&gt;멀티 인스턴스 환경&lt;/b&gt;에서는
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 인스턴스가 동일한 키를 사용해야 암호화 일관성 유지 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LANGFLOW_SECRET_KEY 생성 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;macOS / Linux&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;python3 -c &quot;from secrets import token_urlsafe; print(f'LANGFLOW_SECRET_KEY={token_urlsafe(32)}')&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(macOS는 pbcopy, Linux는 xclip을 사용해 클립보드 복사 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Windows&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;llvm&quot;&gt;&lt;code&gt;python -c &quot;from secrets import token_urlsafe; print(f'LANGFLOW_SECRET_KEY={token_urlsafe(32)}')&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 값을 .env 파일에 추가:&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_SECRET_KEY=생성된_값
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Docker 사용 시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;haml&quot;&gt;&lt;code&gt;environment:
  - LANGFLOW_SECRET_KEY=${LANGFLOW_SECRET_KEY}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;11.4 LANGFLOW_NEW_USER_IS_ACTIVE&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신규 사용자 계정의 &lt;b&gt;자동 활성화 여부&lt;/b&gt;를 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기본값&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_NEW_USER_IS_ACTIVE=False
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동작 방식&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;False:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;슈퍼유저가 신규 사용자를 &lt;b&gt;직접 활성화해야 로그인 가능&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;True:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신규 사용자 계정이 자동으로 활성화됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추가 설명&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 관리 기능은
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow 서버에서 &lt;b&gt;인증이 활성화된 경우에만 의미 있음&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용자 활성화/비활성화는 &lt;b&gt;슈퍼유저만 가능&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;12. CORS 설정 (LANGFLOW_CORS_*)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CORS(Cross-Origin Resource Sharing) 설정은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LangFlow 프론트엔드와 백엔드가 서로 다른 Origin에서 제공될 때&lt;/b&gt;,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증 정보(쿠키, 인증 헤더 등)를 어떻게 처리할지 제어합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;12.1 CORS 관련 환경 변수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 기본값 설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LANGFLOW_CORS_ALLOW_CREDENTIALS&lt;/td&gt;
&lt;td&gt;True&lt;/td&gt;
&lt;td&gt;쿠키, Authorization 헤더 등 인증 정보 허용 여부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LANGFLOW_CORS_ALLOW_HEADERS&lt;/td&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;허용할 HTTP 헤더 목록&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LANGFLOW_CORS_ALLOW_METHODS&lt;/td&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;허용할 HTTP 메서드 목록&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LANGFLOW_CORS_ORIGINS&lt;/td&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;허용할 Origin 목록&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;12.2 기본 CORS 설정 (Default)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 설정은 모든 Origin, Header, Method를 허용합니다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_CORS_ORIGINS=*
LANGFLOW_CORS_ALLOW_CREDENTIALS=True
LANGFLOW_CORS_ALLOW_HEADERS=*
LANGFLOW_CORS_ALLOW_METHODS=*
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;⚠️ 보안 주의 사항&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본 CORS 설정은 &lt;b&gt;운영 환경에서 보안 위험&lt;/b&gt;이 될 수 있음&lt;/li&gt;
&lt;li&gt;어떤 웹사이트든 LangFlow API 호출 가능&lt;/li&gt;
&lt;li&gt;인증 쿠키 및 Authorization 헤더도 포함 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;12.3 운영 환경 권장 CORS 설정 예시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 환경에서는 &lt;b&gt;명시적인 Origin만 허용&lt;/b&gt;하는 것이 권장됩니다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_CORS_ORIGINS=https://yourdomain.com,&amp;lt;https://app.yourdomain.com&amp;gt;
LANGFLOW_CORS_ALLOW_CREDENTIALS=True
LANGFLOW_CORS_ALLOW_HEADERS=Content-Type,Authorization
LANGFLOW_CORS_ALLOW_METHODS=GET,POST,PUT
&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;13. 인증이 활성화된 LangFlow 서버 실행&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 설정은 다음과 같은 환경에 권장됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow가 &lt;b&gt;공용 또는 공유 네트워크&lt;/b&gt;에 노출되는 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;여러 사용자가 하나의 LangFlow 서버&lt;/b&gt;를 사용하는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;13.1 인증 활성화 시 동작&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 사용자는 &lt;b&gt;시각적 에디터 로그인 필요&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;API 요청은 &lt;b&gt;LangFlow API Key 인증 필수&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;사용자 관리 및 슈퍼유저 작업은 &lt;b&gt;슈퍼유저 로그인 필요&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;13.2 .env 파일 설정 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;LANGFLOW_AUTO_LOGIN=False
LANGFLOW_SUPERUSER=administrator
LANGFLOW_SUPERUSER_PASSWORD=securepassword
LANGFLOW_SECRET_KEY=dBuu...2kM2_fb
LANGFLOW_NEW_USER_IS_ACTIVE=False
LANGFLOW_ENABLE_SUPERUSER_CLI=False
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시는 인증 관련 변수만 포함&lt;/li&gt;
&lt;li&gt;실제 환경에서는 강력한 자격 증명 사용 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;13.3 LangFlow 서버 실행&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;uv run langflow run --env-file .env
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.env 파일에 정의된 설정으로 LangFlow 실행&lt;/li&gt;
&lt;li&gt;실행 시 자동으로 슈퍼유저로 인증됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;13.4 서버 실행 확인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본 접속 주소&lt;/li&gt;
&lt;li&gt;&amp;lt;http://localhost:7860&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;14. 사용자 관리 (관리자 / 슈퍼유저)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;14.1 슈퍼유저 최초 로그인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;접속 주소&lt;/li&gt;
&lt;li&gt;&amp;lt;http://localhost:7860/login&amp;gt;&lt;/li&gt;
&lt;li&gt;.env에 설정한 슈퍼유저 계정으로 로그인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;14.2 관리자 페이지 접근&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주소 예시&lt;/li&gt;
&lt;li&gt;&amp;lt;http://localhost:7860/admin&amp;gt;&lt;/li&gt;
&lt;li&gt;또는 프로필 아이콘 &amp;rarr; &lt;b&gt;Admin Page&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;14.3 사용자 관리 기능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슈퍼유저는 다음 작업을 수행할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 추가&lt;/li&gt;
&lt;li&gt;권한 설정&lt;/li&gt;
&lt;li&gt;비밀번호 재설정&lt;/li&gt;
&lt;li&gt;계정 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;14.4 사용자 추가 절차&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;New User&lt;/b&gt; 클릭&lt;/li&gt;
&lt;li&gt;사용자 정보 입력
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Username&lt;/li&gt;
&lt;li&gt;Password&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;계정 활성화 여부 설정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Active 체크 시 즉시 로그인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;슈퍼유저 권한 여부 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Save&lt;/b&gt; 클릭&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;14.5 권한 확인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 사용자는 /admin 접근 불가&lt;/li&gt;
&lt;li&gt;접근 시 /flows 페이지로 리다이렉트됨&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발/Langflow</category>
      <category>langflow</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/199</guid>
      <comments>https://hardworkingini.tistory.com/199#entry199comment</comments>
      <pubDate>Wed, 17 Dec 2025 15:33:38 +0900</pubDate>
    </item>
    <item>
      <title>[Langflow] OpenAI API key 생성</title>
      <link>https://hardworkingini.tistory.com/198</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;LLM 지원 목록 정리&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;LangFlow 기본 지원 LLM Provider&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OpenAI (GPT 계열)&lt;/li&gt;
&lt;li&gt;Google Gemini&lt;/li&gt;
&lt;li&gt;Anthropic (Claude)&lt;/li&gt;
&lt;li&gt;Groq&lt;/li&gt;
&lt;li&gt;Azure OpenAI&lt;/li&gt;
&lt;li&gt;Hugging Face Inference API&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기타 LLM 연결 방식&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Connect other models 옵션 제공&lt;/li&gt;
&lt;li&gt;기본 Provider 목록에 없는 모델 직접 연결 가능&lt;/li&gt;
&lt;li&gt;자체 호스팅 LLM 서버 연동 가능&lt;/li&gt;
&lt;li&gt;사내 전용(private) LLM 연동 가능&lt;/li&gt;
&lt;li&gt;커스텀 REST API 형태의 LLM 연결 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LLM 외 연계 가능 요소&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Agent Tool로 외부 API 사용 가능&lt;/li&gt;
&lt;li&gt;MCP(Model Context Protocol) 서버 연결 가능&lt;/li&gt;
&lt;li&gt;LangFlow 자체를 MCP 서버로 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Langflow는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; LangFlow는 특정 LLM에 종속되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; OpenAI는 여러 선택지 중 하나임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 모델 선택 및 교체가 자유로운 구조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OpenAI API key 생성 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. OpenAI API Keys 페이지 접속&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://platform.openai.com/api-keys&quot;&gt;https://platform.openai.com/api-keys&lt;/a&gt; 에 접속합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 계정이 있다면 로그인, 계정이 없다면 회원가입을 진행합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1279&quot; data-origin-height=&quot;1292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPpeZa/dJMcaajxvqJ/VsB3N1UfCy7ZHMX62VKknK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPpeZa/dJMcaajxvqJ/VsB3N1UfCy7ZHMX62VKknK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPpeZa/dJMcaajxvqJ/VsB3N1UfCy7ZHMX62VKknK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPpeZa%2FdJMcaajxvqJ%2FVsB3N1UfCy7ZHMX62VKknK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1279&quot; height=&quot;1292&quot; data-origin-width=&quot;1279&quot; data-origin-height=&quot;1292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. API Keys 메뉴 이동&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인 후 좌측 메뉴에서 &lt;b&gt;API Keys&lt;/b&gt; 페이지로 이동합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1275&quot; data-origin-height=&quot;1292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byT7TG/dJMcadHivtd/GGjuidkjile0WT0aeKiC4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byT7TG/dJMcadHivtd/GGjuidkjile0WT0aeKiC4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byT7TG/dJMcadHivtd/GGjuidkjile0WT0aeKiC4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyT7TG%2FdJMcadHivtd%2FGGjuidkjile0WT0aeKiC4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1275&quot; height=&quot;1292&quot; data-origin-width=&quot;1275&quot; data-origin-height=&quot;1292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 새 API Key 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Create new secret key&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;버튼을 선택합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키 생성 팝업이 표시됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 목적이라면 기본 설정 그대로 생성해도 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ODcH5/dJMcaaqjiyN/pv3b9X9qteFYtsttwO7ACK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ODcH5/dJMcaaqjiyN/pv3b9X9qteFYtsttwO7ACK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ODcH5/dJMcaaqjiyN/pv3b9X9qteFYtsttwO7ACK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FODcH5%2FdJMcaaqjiyN%2Fpv3b9X9qteFYtsttwO7ACK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;510&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. API Key 복사 및 보관 ⭐️&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성된 &lt;b&gt;API Key는 이 시점에만 전체 문자열을 확인할 수 있습니다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;화면을 닫으면 &lt;b&gt;다시 전체 키를 확인할 수 없습니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 반드시 다음을 수행해야 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성 직후 &lt;b&gt;복사&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;안전한 장소에 &lt;b&gt;즉시 저장&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ 이미 생성된 키의 &lt;b&gt;전체 값을 다시 확인하는 공식적인 방법은 없습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(공식 콘솔에서는 재노출 기능을 제공하지 않습니다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DRkzY/dJMcaiaN8Iq/VNJBDfNQvvwXPNksvia6tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DRkzY/dJMcaiaN8Iq/VNJBDfNQvvwXPNksvia6tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DRkzY/dJMcaiaN8Iq/VNJBDfNQvvwXPNksvia6tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDRkzY%2FdJMcaiaN8Iq%2FVNJBDfNQvvwXPNksvia6tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;396&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. API Key 관리 (이름 및 권한)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 API Key 목록에서 &lt;b&gt;수정(연필) 아이콘&lt;/b&gt;을 통해 다음 작업이 가능합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Key 이름(Name) 변경&lt;/li&gt;
&lt;li&gt;권한(Permissions) 수정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용 가능한 API 범위 제한 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 키 자체의 값(secret)은 변경할 수 없으며, 필요 시 &lt;b&gt;기존 키를 삭제하고 새 키를 생성&lt;/b&gt;해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDyTNB/dJMcacBFo1M/KI55iR492zENxPtALUusm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDyTNB/dJMcacBFo1M/KI55iR492zENxPtALUusm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDyTNB/dJMcacBFo1M/KI55iR492zENxPtALUusm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDyTNB%2FdJMcacBFo1M%2FKI55iR492zENxPtALUusm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1063&quot; height=&quot;814&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. 보안 관련 공식 권장 사항&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenAI 공식 문서 기준 권장 사항은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API Key를 &lt;b&gt;소스 코드에 직접 하드코딩하지 말 것&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;.env 파일 또는 환경 변수로 관리&lt;/li&gt;
&lt;li&gt;GitHub 등 공개 저장소에 절대 커밋하지 말 것&lt;/li&gt;
&lt;li&gt;유출이 의심되면 즉시 &lt;b&gt;키 삭제 후 재발급&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. LangFlow에서 사용 시 참고 사항&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow Quickstart에서는:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OpenAI API Key를 &lt;b&gt;Agent 컴포넌트에 직접 입력&lt;/b&gt;하거나&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Global Variable / 환경 변수&lt;/b&gt;로 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI API Key는 LangFlow 내부에 저장되지 않으며, Flow 실행 시 모델 호출에만 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발/Langflow</category>
      <category>langflow</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/198</guid>
      <comments>https://hardworkingini.tistory.com/198#entry198comment</comments>
      <pubDate>Tue, 16 Dec 2025 15:35:58 +0900</pubDate>
    </item>
    <item>
      <title>[Langflow] Lanflow 설치하기</title>
      <link>https://hardworkingini.tistory.com/197</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. LangFlow란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LangFlow&lt;/b&gt;는 오픈소스, Python 기반의 &lt;b&gt;AI 애플리케이션 구축 프레임워크&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 특징을 공식적으로 지원합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 LLM에 종속되지 않음&lt;/li&gt;
&lt;li&gt;특정 Vector Store에 종속되지 않음&lt;/li&gt;
&lt;li&gt;Agent 기능 지원&lt;/li&gt;
&lt;li&gt;MCP(Model Context Protocol) 지원&lt;/li&gt;
&lt;li&gt;시각적 에디터 기반 워크플로우 설계&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.1 LangFlow의 핵심 목적&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AI 애플리케이션의 &lt;b&gt;워크플로우를 빠르게 설계&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;복잡한 로직을 &lt;b&gt;시각적으로 구성&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;실시간 테스트를 통해 &lt;b&gt;빠른 프로토타이핑&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;완성된 Flow를 &lt;b&gt;API 또는 서버 형태로 제공&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.2 주요 개념 정리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① Flow&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 &lt;b&gt;AI 애플리케이션 워크플로우&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;여러 컴포넌트(Component)로 구성&lt;/li&gt;
&lt;li&gt;LangFlow의 가장 핵심적인 단위&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② Component&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;워크플로우의 &lt;b&gt;단일 처리 단계&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;노드(Node) 형태로 연결됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 컴포넌트 예시&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Input / Output&lt;/li&gt;
&lt;li&gt;Prompt&lt;/li&gt;
&lt;li&gt;LLM&lt;/li&gt;
&lt;li&gt;Agent&lt;/li&gt;
&lt;li&gt;Tool&lt;/li&gt;
&lt;li&gt;Vector Store&lt;/li&gt;
&lt;li&gt;Embedding Provider&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 컴포넌트는 설정 가능한 파라미터를 가짐&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.3 시각적 에디터&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow는 &lt;b&gt;Drag &amp;amp; Drop 방식의 시각적 에디터&lt;/b&gt;를 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가능한 작업:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① 컴포넌트 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② 노드 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ 파라미터 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;④ 즉시 실행 및 테스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 코드 작성 없이도 워크플로우 구조를 빠르게 확인 가능&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.4 실시간 테스트 (Playground)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow는 &lt;b&gt;Playground 기능&lt;/b&gt;을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Playground에서 가능한 작업:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전체 Flow 실행 테스트&lt;/li&gt;
&lt;li&gt;개별 컴포넌트 단독 실행&lt;/li&gt;
&lt;li&gt;의존성 문제를 단계별로 검증&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 전체 애플리케이션을 만들기 전에 로직 검증 가능&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.5 Flow 실행 및 활용 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow에서 만든 Flow는 다음 방식으로 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① 프로토타입 용도&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아이디어 검증&lt;/li&gt;
&lt;li&gt;로직 테스트&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② API 연동&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow API를 통해 Flow 호출&lt;/li&gt;
&lt;li&gt;외부 애플리케이션에 임베드 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;③ 서버 배포&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow 서버 실행&lt;/li&gt;
&lt;li&gt;퍼블릭 인터넷 제공 가능&lt;/li&gt;
&lt;li&gt;Docker 컨테이너 배포 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.6 컴포넌트 확장성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow는 기본 컴포넌트 외에도 확장을 지원합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외부에서 만든 커스텀 컴포넌트 사용 가능&lt;/li&gt;
&lt;li&gt;Python으로 직접 커스텀 컴포넌트 개발 가능&lt;/li&gt;
&lt;li&gt;개인용 또는 공유용 컴포넌트 제작 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.7 Agent 및 MCP 지원&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow는 공식적으로 다음 기능을 지원합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow Agent 사용&lt;/li&gt;
&lt;li&gt;Flow를 Agent Tool로 사용&lt;/li&gt;
&lt;li&gt;LangFlow를 MCP 서버로 사용&lt;/li&gt;
&lt;li&gt;LangFlow를 MCP 클라이언트로 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; Agent 중심 AI 애플리케이션 구축 가능&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.8 활용 가능한 AI 애플리케이션 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서 기준으로 LangFlow는 다음과 같은 애플리케이션에 활용 가능합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;챗봇&lt;/li&gt;
&lt;li&gt;문서 분석 시스템&lt;/li&gt;
&lt;li&gt;콘텐츠 생성기&lt;/li&gt;
&lt;li&gt;Agent 기반 애플리케이션&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. LangFlow 설치 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangFlow는 &lt;b&gt;총 4가지 방식&lt;/b&gt;으로 설치할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 방식에 따라 목적과 사용 환경이 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 설치 방법이 궁금하다면 다음 링크를 참조해주세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.langflow.org/get-started-installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.langflow.org/get-started-installation&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설치 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 방식 설명 특징&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LangFlow Desktop&lt;/td&gt;
&lt;td&gt;데스크톱 앱 형태&lt;/td&gt;
&lt;td&gt;가장 간단한 설치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;컨테이너 실행&lt;/td&gt;
&lt;td&gt;환경 격리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python 패키지 (OSS)&lt;/td&gt;
&lt;td&gt;Python 라이브러리 설치&lt;/td&gt;
&lt;td&gt;환경 제어 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;소스 코드 설치&lt;/td&gt;
&lt;td&gt;GitHub 소스 사용&lt;/td&gt;
&lt;td&gt;기여 목적&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 모든 로컬 설치 방식은 &lt;b&gt;회원가입&amp;middot;로그인 없이 사용 가능&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 LangFlow Desktop (권장)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow를 데스크톱 애플리케이션으로 설치&lt;/li&gt;
&lt;li&gt;의존성 관리 및 업그레이드가 자동으로 처리됨&lt;/li&gt;
&lt;li&gt;가장 설정이 단순한 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일부 기능 미지원&lt;/li&gt;
&lt;li&gt;(Shareable Playground, Voice Mode 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지원 환경&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;macOS 13 이상&lt;/li&gt;
&lt;li&gt;Windows 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설치 절차 (macOS 기준)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. LangFlow Desktop 페이지 접속 (&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Langflow 홈페이지 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.langflow.org/&quot;&gt;https://www.langflow.org/&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;722&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m2bHL/dJMcagjKMBT/PB19bNiZQNYimKoGWhGVXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m2bHL/dJMcagjKMBT/PB19bNiZQNYimKoGWhGVXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m2bHL/dJMcagjKMBT/PB19bNiZQNYimKoGWhGVXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm2bHL%2FdJMcagjKMBT%2FPB19bNiZQNYimKoGWhGVXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1269&quot; height=&quot;722&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;722&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;Get Started for Free&lt;/b&gt;&amp;nbsp;클릭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 연락처 정보 입력 후 다운로드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;1165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DBZGr/dJMcafkQKhd/mUh3fBe8arBUIglg5PIkmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DBZGr/dJMcafkQKhd/mUh3fBe8arBUIglg5PIkmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DBZGr/dJMcafkQKhd/mUh3fBe8arBUIglg5PIkmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDBZGr%2FdJMcafkQKhd%2FmUh3fBe8arBUIglg5PIkmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1271&quot; height=&quot;1165&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;1165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;company의 경우는 그냥 다니는 대학 검색해서 넣었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 애플리케이션 설치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k09Qn/dJMcadUOTe9/ohZCryPWmB8tOXrPCEdEp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k09Qn/dJMcadUOTe9/ohZCryPWmB8tOXrPCEdEp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k09Qn/dJMcadUOTe9/ohZCryPWmB8tOXrPCEdEp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk09Qn%2FdJMcadUOTe9%2FohZCryPWmB8tOXrPCEdEp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1274&quot; height=&quot;853&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인 컴퓨터에 맞는 것으로 골라서 다운로드 받습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 맥북 유저니까 macOS(Apple Siicon)을 다운받습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;788&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yGDCX/dJMcacIrcGL/ZTPskLKgUWaNQ7G5SObcCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yGDCX/dJMcacIrcGL/ZTPskLKgUWaNQ7G5SObcCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yGDCX/dJMcacIrcGL/ZTPskLKgUWaNQ7G5SObcCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyGDCX%2FdJMcacIrcGL%2FZTPskLKgUWaNQ7G5SObcCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;378&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;788&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. LangFlow 실행&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;1192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z32f4/dJMcabvZbGC/w8nkeXokWEZvkR7Lz818Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z32f4/dJMcabvZbGC/w8nkeXokWEZvkR7Lz818Q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z32f4/dJMcabvZbGC/w8nkeXokWEZvkR7Lz818Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz32f4%2FdJMcabvZbGC%2Fw8nkeXokWEZvkR7Lz818Q1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1584&quot; height=&quot;1192&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;1192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;continue를 클릭하면 다운로드가 시작됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;1198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYlNQM/dJMcajncijG/17KtKZK1KPu9YHcikOU1lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYlNQM/dJMcajncijG/17KtKZK1KPu9YHcikOU1lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYlNQM/dJMcajncijG/17KtKZK1KPu9YHcikOU1lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYlNQM%2FdJMcajncijG%2F17KtKZK1KPu9YHcikOU1lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1588&quot; height=&quot;1198&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;1198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 완료 후 화면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3018&quot; data-origin-height=&quot;1898&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZvZ80/dJMcaaw4VlA/RjhYb7M4BwutTTpjFbjlxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZvZ80/dJMcaaw4VlA/RjhYb7M4BwutTTpjFbjlxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZvZ80/dJMcaaw4VlA/RjhYb7M4BwutTTpjFbjlxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZvZ80%2FdJMcaaw4VlA%2FRjhYb7M4BwutTTpjFbjlxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3018&quot; height=&quot;1898&quot; data-origin-width=&quot;3018&quot; data-origin-height=&quot;1898&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. &lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;create first flow&lt;/span&gt;&lt;/b&gt; 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2414&quot; data-origin-height=&quot;1258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/00K94/dJMb99LHw0s/koAOZdNJkWWUQ97W4s6Kc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/00K94/dJMb99LHw0s/koAOZdNJkWWUQ97W4s6Kc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/00K94/dJMb99LHw0s/koAOZdNJkWWUQ97W4s6Kc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F00K94%2FdJMb99LHw0s%2FkoAOZdNJkWWUQ97W4s6Kc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2414&quot; height=&quot;1258&quot; data-origin-width=&quot;2414&quot; data-origin-height=&quot;1258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2 Docker로 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow를 Docker 컨테이너로 실행&lt;/li&gt;
&lt;li&gt;실행 환경을 완전히 분리 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;회원가입 / 로그인 불필요&lt;/li&gt;
&lt;li&gt;서버 및 배포 환경에 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설치 및 실행&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 7860:7860 langflowai/langflow:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;1470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNWEaU/dJMcafd5qxO/KkXXWKUyO2Q6CWua6NxTk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNWEaU/dJMcafd5qxO/KkXXWKUyO2Q6CWua6NxTk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNWEaU/dJMcafd5qxO/KkXXWKUyO2Q6CWua6NxTk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNWEaU%2FdJMcafd5qxO%2FKkXXWKUyO2Q6CWua6NxTk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1506&quot; height=&quot;1470&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;1470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;접속 주소&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;&amp;lt;http://localhost:7860/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3018&quot; data-origin-height=&quot;1810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nVrLF/dJMcagjKNgD/KNDoLKkUSSn5kzDb8Xzt31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nVrLF/dJMcagjKNgD/KNDoLKkUSSn5kzDb8Xzt31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nVrLF/dJMcagjKNgD/KNDoLKkUSSn5kzDb8Xzt31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnVrLF%2FdJMcagjKNgD%2FKNDoLKkUSSn5kzDb8Xzt31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3018&quot; height=&quot;1810&quot; data-origin-width=&quot;3018&quot; data-origin-height=&quot;1810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.3 LangFlow OSS Python 패키지 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Python 환경에 LangFlow를 직접 설치&lt;/li&gt;
&lt;li&gt;환경&amp;middot;버전&amp;middot;의존성을 직접 제어 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필수 조건&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Python 버전
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;macOS / Linux: 3.10 ~ 3.13&lt;/li&gt;
&lt;li&gt;Windows: 3.10 ~ 3.12&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;uv 설치 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;권장 시스템 사양&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최소: Dual-core CPU, RAM 2GB&lt;/li&gt;
&lt;li&gt;권장: Multi-core CPU, RAM 4GB 이상&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설치&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;uv pip install langflow

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 버전 설치:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;uv pip install langflow==1.4.22

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;uv run langflow run

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;접속 주소&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;&amp;lt;http://127.0.0.1:7860&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.4 소스 코드에서 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LangFlow GitHub 소스를 직접 사용&lt;/li&gt;
&lt;li&gt;LangFlow 코드 또는 문서에 기여하기 위한 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 사용 목적에는 권장되지 않음&lt;/li&gt;
&lt;li&gt;개발자 및 기여자 대상&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;설치 방식 선택 정리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;처음 사용&lt;/b&gt; &amp;rarr; LangFlow Desktop&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서버&amp;middot;배포 환경&lt;/b&gt; &amp;rarr; Docker&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개발&amp;middot;커스터마이징&lt;/b&gt; &amp;rarr; Python 패키지&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기여 목적&lt;/b&gt; &amp;rarr; 소스 코드 설치&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발/Langflow</category>
      <category>langflow</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/197</guid>
      <comments>https://hardworkingini.tistory.com/197#entry197comment</comments>
      <pubDate>Tue, 16 Dec 2025 11:36:16 +0900</pubDate>
    </item>
    <item>
      <title>[Dify] Dify 내장 도구 소개</title>
      <link>https://hardworkingini.tistory.com/196</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Dify에는 검색, 번역, 데이터 변환, 음성 처리 등 다양한 기능을 수행할 수 있는 도구들이 연동되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 에이전트나 챗봇을 만들 때 이러한 도구들을 함께 사용하면, 단순한 대화 응답을 넘어 실제 작업을 수행하는 애플리케이션을 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 실무에서 자주 활용되는 Dify 도구들을 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Dify 상단 메뉴에서 도구를 클릭합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dH6L1r/dJMcafrBVvY/FSXGSGbP1PWmk0ZbbJpjQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dH6L1r/dJMcafrBVvY/FSXGSGbP1PWmk0ZbbJpjQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dH6L1r/dJMcafrBVvY/FSXGSGbP1PWmk0ZbbJpjQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdH6L1r%2FdJMcafrBVvY%2FFSXGSGbP1PWmk0ZbbJpjQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1268&quot; height=&quot;796&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도구 화면에서는 다음과 같은 항목들을 확인할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내장&lt;br /&gt;: Dify에 기본으로 포함되어 있거나 사용자가 설치한 도구들을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;커스텀&lt;br /&gt;: 사용자가 직접 정의한 커스텀 도구들을 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;워크플로우&lt;br /&gt;: Dify 워크플로우를 도구 형태로 만들어 재사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;Marketplace&lt;br /&gt;: Dify와 연동 가능한 다양한 외부 솔루션 도구들을 검색하고 설치할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. CurrentTime&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKhvDr/dJMcaiPmv5v/CwG2y9KRKbfbZ4KSVKsLAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKhvDr/dJMcaiPmv5v/CwG2y9KRKbfbZ4KSVKsLAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKhvDr/dJMcaiPmv5v/CwG2y9KRKbfbZ4KSVKsLAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKhvDr%2FdJMcaiPmv5v%2FCwG2y9KRKbfbZ4KSVKsLAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1269&quot; height=&quot;263&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;263&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2kbX1/dJMcad1zU55/kG9yJUM9krOeKKKjfxrvsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2kbX1/dJMcad1zU55/kG9yJUM9krOeKKKjfxrvsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2kbX1/dJMcad1zU55/kG9yJUM9krOeKKKjfxrvsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2kbX1%2FdJMcad1zU55%2FkG9yJUM9krOeKKKjfxrvsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;469&quot; data-origin-width=&quot;389&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CurrentTime은 현재 시간 정보를 가져오는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 시각 조회뿐 아니라, 특정 시간대를 다른 시간대로 변환하거나 특정 날짜가 무슨 요일인지 계산하는 기능도 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간 계산이 필요한 자동화 시나리오에서 유용하게 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Code Interpreter&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yGmMU/dJMcafynrxY/snrGjo3ckrUAiWM3XaDXj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yGmMU/dJMcafynrxY/snrGjo3ckrUAiWM3XaDXj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yGmMU/dJMcafynrxY/snrGjo3ckrUAiWM3XaDXj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyGmMU%2FdJMcafynrxY%2FsnrGjo3ckrUAiWM3XaDXj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1269&quot; height=&quot;265&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;227&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buDi8p/dJMcaajw4pX/hxewF9Q6iyGfK99KJuUc91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buDi8p/dJMcaajw4pX/hxewF9Q6iyGfK99KJuUc91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buDi8p/dJMcaajw4pX/hxewF9Q6iyGfK99KJuUc91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuDi8p%2FdJMcaajw4pX%2FhxewF9Q6iyGfK99KJuUc91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;373&quot; height=&quot;227&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;227&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Code Interpreter는 코드를 실행하고 그 결과를 반환해주는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM에게 코드를 작성하도록 요청한 뒤, 해당 코드를 실제로 실행하고 결과를 확인할 때 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 계산, 데이터 처리, 파일 변환 작업 등에 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. DALL-E&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj9MHx/dJMcadAvCyb/sVJ9cKKiKsftKw9zsg2qo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj9MHx/dJMcadAvCyb/sVJ9cKKiKsftKw9zsg2qo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj9MHx/dJMcadAvCyb/sVJ9cKKiKsftKw9zsg2qo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj9MHx%2FdJMcadAvCyb%2FsVJ9cKKiKsftKw9zsg2qo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1202&quot; height=&quot;298&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBzpvc/dJMcac9r4xg/05euP5cRshUsccetANikF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBzpvc/dJMcac9r4xg/05euP5cRshUsccetANikF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBzpvc/dJMcac9r4xg/05euP5cRshUsccetANikF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBzpvc%2FdJMcac9r4xg%2F05euP5cRshUsccetANikF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;302&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DALL-E는 OpenAI에서 개발한 이미지 생성 AI 도구로, 텍스트 프롬프트를 기반으로 이미지를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dify에서 사용하려면 외부 솔루션 플러그인을 설치해야 하며, OpenAI API 키 설정이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 생성이 필요한 챗봇이나 콘텐츠 제작 자동화에 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenAI API 키 설정&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ly3yM/dJMcahbS9nA/r9l0rCZDmMX5MECkHdTjh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ly3yM/dJMcahbS9nA/r9l0rCZDmMX5MECkHdTjh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ly3yM/dJMcahbS9nA/r9l0rCZDmMX5MECkHdTjh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fly3yM%2FdJMcahbS9nA%2Fr9l0rCZDmMX5MECkHdTjh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;371&quot; height=&quot;235&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OnJKQ/dJMcabCKhDu/QD2SkIy2g3Pe96EbO7fkZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OnJKQ/dJMcabCKhDu/QD2SkIy2g3Pe96EbO7fkZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OnJKQ/dJMcabCKhDu/QD2SkIy2g3Pe96EbO7fkZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOnJKQ%2FdJMcabCKhDu%2FQD2SkIy2g3Pe96EbO7fkZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;587&quot; height=&quot;578&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. Tavily&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G1Gqi/dJMcabbF0jM/ELJIBF4dd3TpYqAwUiuc81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G1Gqi/dJMcabbF0jM/ELJIBF4dd3TpYqAwUiuc81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G1Gqi/dJMcabbF0jM/ELJIBF4dd3TpYqAwUiuc81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG1Gqi%2FdJMcabbF0jM%2FELJIBF4dd3TpYqAwUiuc81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;303&quot; height=&quot;133&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAMVG5/dJMcaaRnqSD/Ye0SEKhbI7oG13gUuq5Wmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAMVG5/dJMcaaRnqSD/Ye0SEKhbI7oG13gUuq5Wmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAMVG5/dJMcaaRnqSD/Ye0SEKhbI7oG13gUuq5Wmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAMVG5%2FdJMcaaRnqSD%2FYe0SEKhbI7oG13gUuq5Wmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;382&quot; height=&quot;353&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tavily는 웹사이트에서 필요한 정보를 검색하고, 웹페이지의 내용을 구조화된 형태로 가져오는 AI 검색 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실시간 웹 검색과 요약에 강점이 있으며, 사용을 위해서는 플러그인 설치와 Tavily API 키 입력이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 키는 &lt;a href=&quot;https://app.tavily.com/home&quot;&gt;https://app.tavily.com/home&lt;/a&gt; 에서 회원가입 후 발급받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. Wikipedia&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QJxdG/dJMcah31Oua/UT3mwqlqbv9IhHOXkARQs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QJxdG/dJMcah31Oua/UT3mwqlqbv9IhHOXkARQs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QJxdG/dJMcah31Oua/UT3mwqlqbv9IhHOXkARQs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQJxdG%2FdJMcah31Oua%2FUT3mwqlqbv9IhHOXkARQs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;299&quot; height=&quot;132&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m1fWI/dJMcahwb68g/kLwdQ9fJgmnKGctDSaoM9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m1fWI/dJMcahwb68g/kLwdQ9fJgmnKGctDSaoM9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m1fWI/dJMcahwb68g/kLwdQ9fJgmnKGctDSaoM9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm1fWI%2FdJMcahwb68g%2FkLwdQ9fJgmnKGctDSaoM9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;373&quot; height=&quot;239&quot; data-origin-width=&quot;373&quot; data-origin-height=&quot;239&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Wikipedia 도구는 위키백과를 검색하여 필요한 정보를 가져오는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위키 문서에서 핵심 내용을 추출해 응답에 활용할 수 있어, 일반 지식 기반 질의응답에 적합합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. ArXiv&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zV4Gg/dJMcafd41Hu/dJu06rFJYfkyX8b0eJr12k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zV4Gg/dJMcafd41Hu/dJu06rFJYfkyX8b0eJr12k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zV4Gg/dJMcafd41Hu/dJu06rFJYfkyX8b0eJr12k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzV4Gg%2FdJMcafd41Hu%2FdJu06rFJYfkyX8b0eJr12k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;302&quot; height=&quot;134&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;227&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckp2k3/dJMcafrBWf3/Kgi8XvYR3YitZeLTjXfVck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckp2k3/dJMcafrBWf3/Kgi8XvYR3YitZeLTjXfVck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckp2k3/dJMcafrBWf3/Kgi8XvYR3YitZeLTjXfVck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fckp2k3%2FdJMcafrBWf3%2FKgi8XvYR3YitZeLTjXfVck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;371&quot; height=&quot;227&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;227&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArXiv는 과학 논문 저장소인 arXiv에서 연구 논문을 검색할 수 있는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 애플리케이션에서 학술 자료, 연구 동향, 논문 정보를 검색하고 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8. SearchApi&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xbjlc/dJMcaaDPJwq/ItFCMUcdcWfNQHsU346tkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xbjlc/dJMcaaDPJwq/ItFCMUcdcWfNQHsU346tkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xbjlc/dJMcaaDPJwq/ItFCMUcdcWfNQHsU346tkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXbjlc%2FdJMcaaDPJwq%2FItFCMUcdcWfNQHsU346tkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;301&quot; height=&quot;133&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dya9g0/dJMcaiokici/egCPZs2kWk0aT56p6Xwkn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dya9g0/dJMcaiokici/egCPZs2kWk0aT56p6Xwkn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dya9g0/dJMcaiokici/egCPZs2kWk0aT56p6Xwkn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdya9g0%2FdJMcaiokici%2FegCPZs2kWk0aT56p6Xwkn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;374&quot; height=&quot;489&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SearchApi는 구글 검색, 구글 채용 정보, 유튜브, 구글 뉴스 등 다양한 검색 서비스를 하나의 API로 제공하는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실시간 검색 결과를 구조화된 데이터 형태로 받아볼 수 있어 정보 수집 자동화에 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;9. Firecrawl&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2EHeo/dJMcachlDh0/y9JTJW1QpbxxmJBTtKnjnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2EHeo/dJMcachlDh0/y9JTJW1QpbxxmJBTtKnjnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2EHeo/dJMcachlDh0/y9JTJW1QpbxxmJBTtKnjnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2EHeo%2FdJMcachlDh0%2Fy9JTJW1QpbxxmJBTtKnjnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;132&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;479&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5kWBM/dJMcaiV7WRM/X4AoOce8tKTNLqJ3m8Lc2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5kWBM/dJMcaiV7WRM/X4AoOce8tKTNLqJ3m8Lc2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5kWBM/dJMcaiV7WRM/X4AoOce8tKTNLqJ3m8Lc2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5kWBM%2FdJMcaiV7WRM%2FX4AoOce8tKTNLqJ3m8Lc2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;374&quot; height=&quot;479&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;479&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firecrawl은 웹사이트의 내용을 자동으로 수집하고 정리해주는 웹 크롤링 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹페이지 주소를 입력하면 해당 사이트의 텍스트와 구조화된 콘텐츠를 추출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 키는 &lt;a href=&quot;https://www.firecrawl.dev/&quot;&gt;https://www.firecrawl.dev/&lt;/a&gt; 에서 회원가입 후 발급받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;10. AntV Visualization Chart&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfJtmy/dJMcaajw47N/RqFxKKcpBrALkkXGCuWhHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfJtmy/dJMcaajw47N/RqFxKKcpBrALkkXGCuWhHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfJtmy/dJMcaajw47N/RqFxKKcpBrALkkXGCuWhHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfJtmy%2FdJMcaajw47N%2FRqFxKKcpBrALkkXGCuWhHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;301&quot; height=&quot;133&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;1220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CemeY/dJMcacBEZSQ/rVzJQbUK1GqPSiDE2bDKx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CemeY/dJMcacBEZSQ/rVzJQbUK1GqPSiDE2bDKx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CemeY/dJMcacBEZSQ/rVzJQbUK1GqPSiDE2bDKx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCemeY%2FdJMcacBEZSQ%2FrVzJQbUK1GqPSiDE2bDKx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;361&quot; height=&quot;1220&quot; data-origin-width=&quot;361&quot; data-origin-height=&quot;1220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AntV Visualization Chart는 데이터를 시각화하여 표현하는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;막대 그래프, 선 그래프, 원 그래프 등 다양한 차트를 생성할 수 있어, 데이터 분석 결과를 직관적으로 전달할 때 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;11. Mistral OCR&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I6V7P/dJMcacaz3yr/5ffJKK6HUe5oCJq3mHVKC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I6V7P/dJMcacaz3yr/5ffJKK6HUe5oCJq3mHVKC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I6V7P/dJMcacaz3yr/5ffJKK6HUe5oCJq3mHVKC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI6V7P%2FdJMcacaz3yr%2F5ffJKK6HUe5oCJq3mHVKC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;129&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;367&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9wtr5/dJMcadAvDBj/TWiIkkizy0EvvezoKM6TyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9wtr5/dJMcadAvDBj/TWiIkkizy0EvvezoKM6TyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9wtr5/dJMcadAvDBj/TWiIkkizy0EvvezoKM6TyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9wtr5%2FdJMcadAvDBj%2FTWiIkkizy0EvvezoKM6TyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;367&quot; height=&quot;268&quot; data-origin-width=&quot;367&quot; data-origin-height=&quot;268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mistral OCR은 PDF나 이미지 파일에 포함된 텍스트를 추출하는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서의 레이아웃과 구조를 최대한 유지하면서 글자를 인식하여 텍스트로 변환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 키는 &lt;a href=&quot;https://console.mistral.ai/api-keys&quot;&gt;https://console.mistral.ai/api-keys&lt;/a&gt; 에서 회원가입 후 발급받을 수 있습니다.&lt;/p&gt;</description>
      <category>개발/Dify</category>
      <category>dify</category>
      <author>말하는 알감자</author>
      <guid isPermaLink="true">https://hardworkingini.tistory.com/196</guid>
      <comments>https://hardworkingini.tistory.com/196#entry196comment</comments>
      <pubDate>Mon, 15 Dec 2025 10:55:08 +0900</pubDate>
    </item>
  </channel>
</rss>