<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Replicated</title>
    <link>https://lagooneng.tistory.com/</link>
    <description>멀티플레이 게임 개발자</description>
    <language>ko</language>
    <pubDate>Fri, 14 Aug 2026 09:28:08 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>라구넹</managingEditor>
    <image>
      <title>Replicated</title>
      <url>https://tistory1.daumcdn.net/tistory/5449001/attach/8f2230f04d7b4129bebf05c99702148b</url>
      <link>https://lagooneng.tistory.com</link>
    </image>
    <item>
      <title>RasterizerState, SampleState, BlendState</title>
      <link>https://lagooneng.tistory.com/633</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. RasterizerState&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::CreateRasterizerState()
{
	D3D11_RASTERIZER_DESC desc;
	ZeroMemory(&amp;amp;desc, sizeof(desc));
	desc.FillMode = D3D11_FILL_SOLID;
	desc.CullMode = D3D11_CULL_BACK;
	desc.FrontCounterClockwise = false;

	HRESULT hr = _device-&amp;gt;CreateRasterizerState(&amp;amp;desc, _rasterizerState.GetAddressOf());
	CHECK(hr);
}&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;/p&gt;
&lt;pre class=&quot;&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;D3D11_FILL_WIREFRAME&lt;/code&gt;&lt;/pre&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;778&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxvXId/dJMcacYkSBU/h0UIleD6XqE4uPpRxLlPtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxvXId/dJMcacYkSBU/h0UIleD6XqE4uPpRxLlPtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxvXId/dJMcacYkSBU/h0UIleD6XqE4uPpRxLlPtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxvXId%2FdJMcacYkSBU%2Fh0UIleD6XqE4uPpRxLlPtk%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;778&quot; height=&quot;573&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;573&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CullMode는 안보이는 거 잘라내는 건데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BACK은 후면이면 잘라낸다는 거&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;D3D11_CULL_FRONT&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;771&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTv21W/dJMcadiHvWA/QALtylTEfJjbWuMf7ebeK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTv21W/dJMcadiHvWA/QALtylTEfJjbWuMf7ebeK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTv21W/dJMcadiHvWA/QALtylTEfJjbWuMf7ebeK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTv21W%2FdJMcadiHvWA%2FQALtylTEfJjbWuMf7ebeK1%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;771&quot; height=&quot;590&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;590&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞 뒤 판별은 어떻게 되느냐&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;FrontCounterClockwise&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카운터클록와이즈, 반시계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞방향이 반시계 방향이다 라는 설정이 false&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. SampleState&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;Texture2D texture0 : register(t0); 
SamplerState sampler0 : register(s0);

float4 PS(VS_OUTPUT input) : SV_Target
{
    float4 color = texture0.Sample(sampler0, input.uv);
    return color;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 썼던 건데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uv 좌표 따라서 샘플링 해주는 거와 관련&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;pre class=&quot;pgsql&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::CreateSamplerState()
{
	D3D11_SAMPLER_DESC desc;
	ZeroMemory(&amp;amp;desc, sizeof(desc));
	desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
	desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
	desc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
	desc.BorderColor[0] = 1;
	desc.BorderColor[1] = 0;
	desc.BorderColor[2] = 0;
	desc.BorderColor[3] = 1;
	desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
	desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	desc.MaxAnisotropy = 15;
	desc.MaxLOD = FLT_MAX;
	desc.MinLOD = FLT_MIN;
	desc.MipLODBias = 0.0f;

	_device-&amp;gt;CreateSamplerState(&amp;amp;desc, _samplerState.GetAddressOf());
}&lt;/code&gt;&lt;/pre&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;309&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1fdwm/dJMcahk7s3G/QVSLwDvq6hjnjZKOyKD5C1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1fdwm/dJMcahk7s3G/QVSLwDvq6hjnjZKOyKD5C1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1fdwm/dJMcahk7s3G/QVSLwDvq6hjnjZKOyKD5C1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1fdwm%2FdJMcahk7s3G%2FQVSLwDvq6hjnjZKOyKD5C1%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;467&quot; height=&quot;309&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;309&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버텍스 UV 수정 좀 해주면&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;768&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0ift9/dJMcahSNe4I/SUUYdLker1J1hiM2IAC8T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0ift9/dJMcahSNe4I/SUUYdLker1J1hiM2IAC8T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0ift9/dJMcahSNe4I/SUUYdLker1J1hiM2IAC8T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0ift9%2FdJMcahSNe4I%2FSUUYdLker1J1hiM2IAC8T0%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;768&quot; height=&quot;574&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 되는데&lt;/p&gt;
&lt;pre class=&quot;&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;D3D11_TEXTURE_ADDRESS_BORDER&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 때문&lt;/p&gt;
&lt;pre class=&quot;ini&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;desc.AddressU = D3D11_TEXTURE_ADDRESS_MIRROR;
desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
desc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;&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;793&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPN6HX/dJMcaa7mitv/cXabksoPGpgFzdotWKk5c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPN6HX/dJMcaa7mitv/cXabksoPGpgFzdotWKk5c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPN6HX/dJMcaa7mitv/cXabksoPGpgFzdotWKk5c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPN6HX%2FdJMcaa7mitv%2FcXabksoPGpgFzdotWKk5c0%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;793&quot; height=&quot;579&quot; data-origin-width=&quot;793&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;U만 미러하면 이런식&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;3. BlendState&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::CreateBlendState()
{
	D3D11_BLEND_DESC desc;
	ZeroMemory(&amp;amp;desc, sizeof(desc));
	desc.AlphaToCoverageEnable = false;
	desc.IndependentBlendEnable = false;

	desc.RenderTarget[0].BlendEnable = true;
	desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_DEST_ALPHA;
	desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

	HRESULT hr = _device-&amp;gt;CreateBlendState(&amp;amp;desc, _blendState.GetAddressOf());
	CHECK(hr);
}&lt;/code&gt;&lt;/pre&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;780&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IFd4A/dJMb99UO1pm/RNrO8BnGAL1R4jhKOecsn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IFd4A/dJMb99UO1pm/RNrO8BnGAL1R4jhKOecsn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IFd4A/dJMb99UO1pm/RNrO8BnGAL1R4jhKOecsn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIFd4A%2FdJMb99UO1pm%2FRNrO8BnGAL1R4jhKOecsn0%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;780&quot; height=&quot;571&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;571&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;</description>
      <category>DirectX 11</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/633</guid>
      <comments>https://lagooneng.tistory.com/633#entry633comment</comments>
      <pubDate>Sat, 1 Aug 2026 22:49:25 +0900</pubDate>
    </item>
    <item>
      <title>Constant Buffer</title>
      <link>https://lagooneng.tistory.com/632</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;결국 게임이니 버텍스 위치가 바뀌어야 하는데&lt;/p&gt;
&lt;pre class=&quot;&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;D3D11_USAGE_IMMUTABLE&lt;/code&gt;&lt;/pre&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;pre class=&quot;lua&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;cbuffer TransformData : register(b0)
{
    float4 offset;
}

VS_OUTPUT VS(VS_INPUT input)
{
    VS_OUTPUT output;
    output.position = input.position + offset;
    //output.color = input.color;
    output.uv = input.uv;
    
    return output;
}&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;버퍼 0번 슬롯에 연결해두고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::Update()
{
	_transformData.offset.x = 0.3f;
	_transformData.offset.y = 0.3f;

	D3D11_MAPPED_SUBRESOURCE subResource;
	ZeroMemory(&amp;amp;subResource, sizeof(D3D11_MAPPED_SUBRESOURCE));

	_deviceContext-&amp;gt;Map(_constantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;amp;subResource);
	::memcpy(subResource.pData, &amp;amp;_transformData, sizeof(_transformData));
	_deviceContext-&amp;gt;Unmap(_constantBuffer.Get(), 0 );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업데이트에서 CPU데이터인 트랜스폼 데이터를 콘스턴트 버퍼에 넣어두고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;_deviceContext-&amp;gt;VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;렌더에서 0번 버퍼 슬롯에 연결&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;794&quot; data-origin-height=&quot;595&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5997H/dJMcagzD9Uv/R9uFe2keyGHSCMyPYsyP41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5997H/dJMcagzD9Uv/R9uFe2keyGHSCMyPYsyP41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5997H/dJMcagzD9Uv/R9uFe2keyGHSCMyPYsyP41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5997H%2FdJMcagzD9Uv%2FR9uFe2keyGHSCMyPYsyP41%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;588&quot; height=&quot;441&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;595&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DirectX 11</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/632</guid>
      <comments>https://lagooneng.tistory.com/632#entry632comment</comments>
      <pubDate>Sat, 1 Aug 2026 21:47:04 +0900</pubDate>
    </item>
    <item>
      <title>텍스처, UV</title>
      <link>https://lagooneng.tistory.com/631</link>
      <description>&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;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1785572930917&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void Game::CreateGeometry()
{
	{
		_vertices.resize(4);

		/*
		* 13
		* 02
		*/

		_vertices[0].position = Vec3(-0.5f, -0.5f, 0.0f);
		_vertices[0].color = Color(1.0f, 0.0f, 0.0f, 1.0f);

		_vertices[1].position = Vec3(-0.5f, 0.5f, 0.0f);
		_vertices[1].color = Color(0.0f, 1.0f, 0.0f, 1.0f);

		_vertices[2].position = Vec3(0.5f, -0.5f, 0.0f);
		_vertices[2].color = Color(0.0f, 0.0f, 1.0f, 1.0f);

		_vertices[3].position = Vec3(0.5f, 0.5f, 0.0f);
		_vertices[3].color = Color(0.0f, 0.0f, 1.0f, 1.0f);
	}

	// Vertex Buffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&amp;amp;desc, sizeof(desc));
		desc.Usage = D3D11_USAGE_IMMUTABLE;	// GPU Read Only
		desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		desc.ByteWidth = static_cast&amp;lt;uint32&amp;gt;( sizeof(Vertex) * _vertices.size() );

		D3D11_SUBRESOURCE_DATA data;
		ZeroMemory(&amp;amp;data, sizeof(data));
		data.pSysMem = &amp;amp;_vertices[0];

		_device-&amp;gt;CreateBuffer(&amp;amp;desc, &amp;amp;data, _vertexBuffer.GetAddressOf());
	}

	// Index
	{
		_indices = { 0, 1, 2, 2, 1, 3 };

	}

	// Index Buffer
	{
		D3D11_BUFFER_DESC desc;
		ZeroMemory(&amp;amp;desc, sizeof(desc));
		desc.Usage = D3D11_USAGE_IMMUTABLE;	// GPU Read Only
		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
		desc.ByteWidth = static_cast&amp;lt;uint32&amp;gt;(sizeof(uint32) * _indices.size());

		D3D11_SUBRESOURCE_DATA data;
		ZeroMemory(&amp;amp;data, sizeof(data));
		data.pSysMem = &amp;amp;_indices[0];

		HRESULT hr = _device-&amp;gt;CreateBuffer(&amp;amp;desc, &amp;amp;data, _indexBuffer.GetAddressOf());
		CHECK(hr);
	}
}&lt;/code&gt;&lt;/pre&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;pre id=&quot;code_1785572956741&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void Game::Render()
{
	RenderBegin();

	{
		uint32 stride = sizeof(Vertex);
		uint32 offset = 0;

		// IA
		_deviceContext-&amp;gt;IASetVertexBuffers(0, 1, _vertexBuffer.GetAddressOf(), &amp;amp;stride, &amp;amp;offset);
		_deviceContext-&amp;gt;IASetIndexBuffer(_indexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
		_deviceContext-&amp;gt;IASetInputLayout(_inputLayout.Get());
		_deviceContext-&amp;gt;IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

		// VS
		_deviceContext-&amp;gt;VSSetShader(_vertexShader.Get(), nullptr, 0);

		// RS

		// PS
		_deviceContext-&amp;gt;PSSetShader(_pixelShader.Get(), nullptr, 0);

		// OM
		//_deviceContext-&amp;gt;Draw(_vertices.size(), 0);
		_deviceContext-&amp;gt;DrawIndexed(_indices.size(), 0, 0);
	}

	RenderEnd();
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;IASetIndexBuffer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 인덱스 버퍼 넣어주고&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;DrawIndexed&lt;/code&gt;&lt;/pre&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;610&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9yhEN/dJMcadXfeOQ/hvp0pFosfsUoJw0B1N2L4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9yhEN/dJMcadXfeOQ/hvp0pFosfsUoJw0B1N2L4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9yhEN/dJMcadXfeOQ/hvp0pFosfsUoJw0B1N2L4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9yhEN%2FdJMcadXfeOQ%2Fhvp0pFosfsUoJw0B1N2L4K%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;610&quot; height=&quot;458&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;458&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;결국 인덱스 버퍼는 정점 개수 메모리에 올라가는 거 줄일 수 있으니 이득&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 파일에서 좌표를 꺼내야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; uv 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uv는 0~1 사이의 값으로 이미지 매핑하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;_vertices[0].position = Vec3(-0.5f, -0.5f, 0.0f);
_vertices[0].uv = Vec2(0.0f, 1.0f);
//_vertices[0].color = Color(1.0f, 0.0f, 0.0f, 1.0f);
		
_vertices[1].position = Vec3(-0.5f, 0.5f, 0.0f);
_vertices[1].uv = Vec2(0.0f, 0.0f);
//_vertices[1].color = Color(0.0f, 1.0f, 0.0f, 1.0f);

_vertices[2].position = Vec3(0.5f, -0.5f, 0.0f);
_vertices[2].uv = Vec2(1.0f, 1.0f);
//_vertices[2].color = Color(0.0f, 0.0f, 1.0f, 1.0f);

_vertices[3].position = Vec3(0.5f, 0.5f, 0.0f);
_vertices[3].uv = Vec2(1.0f, 0.0f);
//_vertices[3].color = Color(0.0f, 0.0f, 1.0f, 1.0f);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UV 순서대로 맞춰서 넣고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;lua&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;VS_OUTPUT VS(VS_INPUT input)
{
    VS_OUTPUT output;
    output.position = input.position;
    //output.color = input.color;
    output.uv = input.uv;
    
    return output;
}

Texture2D texture0 : register(t0); 
SamplerState sampler0 : register(s0);

float4 PS(VS_OUTPUT input) : SV_Target
{
    float4 color = texture0.Sample(sampler0, input.uv);
    return color;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉐이더도 수정해주고&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::CreateSRV()
{
	DirectX::TexMetadata md;
	DirectX::ScratchImage img;

	HRESULT hr = ::LoadFromWICFile(L&quot;bubble.png&quot;, WIC_FLAGS_NONE, &amp;amp;md, img);
	CHECK(hr);

	hr = ::CreateShaderResourceView(_device.Get(), img.GetImages(), img.GetImageCount(), md, _shaderResourceView.GetAddressOf());
	CHECK(hr);


}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRV도 만들어주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;_deviceContext-&amp;gt;PSSetShaderResources(0, 1, _shaderResourceView.GetAddressOf());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRV 세팅해주면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJUesZ/dJMcab6crxX/G2FozvRjMpIwvS6Nenl3M0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJUesZ/dJMcab6crxX/G2FozvRjMpIwvS6Nenl3M0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJUesZ/dJMcab6crxX/G2FozvRjMpIwvS6Nenl3M0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJUesZ%2FdJMcab6crxX%2FG2FozvRjMpIwvS6Nenl3M0%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;536&quot; height=&quot;418&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;418&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;샘플러 스테이트 같은 걸 설정하면 uv 초과하거나 등등의 상황에 대해 옵션 지정 가능&lt;/p&gt;</description>
      <category>DirectX 11</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/631</guid>
      <comments>https://lagooneng.tistory.com/631#entry631comment</comments>
      <pubDate>Sat, 1 Aug 2026 18:08:27 +0900</pubDate>
    </item>
    <item>
      <title>삼각형 띄우기</title>
      <link>https://lagooneng.tistory.com/630</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;587&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1MrqN/dJMcacD6Rot/wyY6sCcUTQ2HULEmTFlMB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1MrqN/dJMcacD6Rot/wyY6sCcUTQ2HULEmTFlMB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1MrqN/dJMcacD6Rot/wyY6sCcUTQ2HULEmTFlMB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1MrqN%2FdJMcacD6Rot%2FwyY6sCcUTQ2HULEmTFlMB1%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;791&quot; height=&quot;587&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;587&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::Init(HWND hand)
{
	_hwnd = hand;
	_width = GWinSizeX;
	_height = GWinSizeY;

	CreateDeviceAndSwapChain();
	CreateRenterTargetView();
	SetViewPort();

	CreateGeometry();
	CreateVS();
	CreateInputLayout();
	CreatePS();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CreateGeometry : 정점 데이터 -&amp;gt; GPU 버퍼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CreateVS : 버텍스 쉐이더 로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CreateInputLayout..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;D3D11_BUFFER_DESC desc;
ZeroMemory(&amp;amp;desc, sizeof(desc));
desc.Usage = D3D11_USAGE_IMMUTABLE;	// GPU Read Only
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.ByteWidth = static_cast&amp;lt;uint32&amp;gt;( sizeof(Vertex) * _vertices.size() );

D3D11_SUBRESOURCE_DATA data;
ZeroMemory(&amp;amp;data, sizeof(data));
data.pSysMem = &amp;amp;_vertices[0];

_device-&amp;gt;CreateBuffer(&amp;amp;desc, &amp;amp;data, _vertexBuffer.GetAddressOf());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Usage : IMMUTABLE은 한 번 만들고 안바꿈 -&amp;gt; GPU 리드 온리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pSysMem은 초기 데이터의 출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::CreateInputLayout()
{
	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{ &quot;POSITION&quot;, 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ &quot;COLOR&quot;, 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	const int32 count = sizeof(layout) / sizeof(D3D11_INPUT_ELEMENT_DESC);
	_device-&amp;gt;CreateInputLayout(layout, count, _vsBlob-&amp;gt;GetBufferPointer(), _vsBlob-&amp;gt;GetBufferSize(), _inputLayout.GetAddressOf());
}&lt;/code&gt;&lt;/pre&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;pre class=&quot;cpp&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::CreateVS()
{
	LoadShaderFromFile(L&quot;Default.hlsl&quot;, &quot;VS&quot;, &quot;vs_5_0&quot;, _vsBlob);

	HRESULT hr = _device-&amp;gt;CreateVertexShader(_vsBlob-&amp;gt;GetBufferPointer(), _vsBlob-&amp;gt;GetBufferSize(), nullptr, _vertexShader.GetAddressOf());
	CHECK(hr);
}

void Game::CreatePS()
{
	LoadShaderFromFile(L&quot;Default.hlsl&quot;, &quot;PS&quot;, &quot;ps_5_0&quot;, _psBlob);

	HRESULT hr = _device-&amp;gt;CreatePixelShader(_psBlob-&amp;gt;GetBufferPointer(), _psBlob-&amp;gt;GetBufferSize(), nullptr, _pixelShader.GetAddressOf());
	CHECK(hr);
}

void Game::LoadShaderFromFile(const wstring&amp;amp; path, const string&amp;amp; name, const string&amp;amp; version, ComPtr&amp;lt;ID3DBlob&amp;gt;&amp;amp; blob)
{
	const uint32 compileFlag = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;

	HRESULT hr = ::D3DCompileFromFile(
		path.c_str(),
		nullptr,
		D3D_COMPILE_STANDARD_FILE_INCLUDE,
		name.c_str(),
		version.c_str(),
		compileFlag,
		0,
		blob.GetAddressOf(),
		nullptr
	);

	CHECK(hr);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ID2DBlob은 그냥 바이트 덩어리고 여기에 쉐이더 바이트 코드가 담김&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DirectX 11</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/630</guid>
      <comments>https://lagooneng.tistory.com/630#entry630comment</comments>
      <pubDate>Sat, 1 Aug 2026 01:33:29 +0900</pubDate>
    </item>
    <item>
      <title>장치 초기화</title>
      <link>https://lagooneng.tistory.com/629</link>
      <description>&lt;pre id=&quot;code_1785505611865&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ComPtr&amp;lt; ID3D11Device &amp;gt; _device;
ComPtr&amp;lt; ID3D11DeviceContext &amp;gt; _deviceContext;
ComPtr&amp;lt; IDXGISwapChain &amp;gt; _swapChain;&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;_device : 리소스 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_deviceContext : GPU에 명령 발행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_swapChain : 화면 출력&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; style=&quot;color: #000000;&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;void Game::Init(HWND hand)
{
	_hwnd = hand;
	_width = GWinSizeX;
	_height = GWinSizeY;

	CreateDeviceAndSwapChain();
	CreateRenterTargetView();
	SetViewPort();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기화 진입점.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서는 강제. 스왑체인이 있어야 백버퍼를 꺼낼 수 있고, 백버퍼가 있어야 RTV(Render Target View)를 만들 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1785505715321&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void Game::CreateDeviceAndSwapChain()
{
	DXGI_SWAP_CHAIN_DESC desc;
	ZeroMemory(&amp;amp;desc, sizeof(desc));

	{
		desc.BufferDesc.Width = _width;
		desc.BufferDesc.Height = _height;
		desc.BufferDesc.RefreshRate.Numerator = 60;
		desc.BufferDesc.RefreshRate.Denominator = 1;
		desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
		desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
		desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		desc.BufferCount = 1;
		desc.OutputWindow = _hwnd;
		desc.Windowed = true;
		desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	}

	HRESULT hr = ::D3D11CreateDeviceAndSwapChain(
		nullptr,
		D3D_DRIVER_TYPE_HARDWARE,
		nullptr,
		0,
		nullptr,
		0,
		D3D11_SDK_VERSION,
		&amp;amp;desc,
		_swapChain.GetAddressOf(),
		_device.GetAddressOf(),
		nullptr,
		_deviceContext.GetAddressOf()
	);

	CHECK(hr);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디바이스, 디바이스 컨텍스트, 스왑체인 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;desc 밀어버리는 건 DX가 쓰레기값 진짜값으로 오인하는 경우가 있음&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;DXGI_SWAP_CHAIN_DESC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인자용 구조체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Width, Height : 백버퍼 해상도로 창 크기와 별개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RefreshRate : 주사율, 전체 화면에서만 유효&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Format : 픽셀 저장 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Count : 픽셀 당 샘플 수로 1 = MSAA 끔. 안티 앨리어싱 관련 필드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- BufferUsage : 버퍼 용도 선언&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- BufferCount : 백버퍼 개수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- OutputWindow : 출력 대상 윈도우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SwapEffect : 프레젠트 후 백버퍼 처리 방식&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;span style=&quot;color: #333333; text-align: start;&quot;&gt;RefreshRate가 분수인건 실제 모니터가 59.94Hz ( 60000/1001 )같은 값이라..&lt;/span&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;span style=&quot;color: #333333; text-align: start;&quot;&gt;DXGI_FORMAT_R8G8B8A8_UNORM&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 채널당 8비트로 총 32비트&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;ini&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 버퍼는 렌더링 용이다 미리 정해놔야 GPU가 세팅함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;ini&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;&lt;/code&gt;&lt;/pre&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;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;D3D_DRIVER_TYPE_HARDWARE&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU 하드웨어 가속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::CreateRenterTargetView()
{
	HRESULT hr;

	ComPtr&amp;lt;ID3D11Texture2D&amp;gt; backBuffer = nullptr;
	hr = _swapChain-&amp;gt;GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)backBuffer.GetAddressOf());
	CHECK(hr);

	hr = _device-&amp;gt;CreateRenderTargetView(backBuffer.Get(), nullptr, _renderTargetView.GetAddressOf());
	CHECK(hr);

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 백버퍼(리소스) 꺼내기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스왑체인이 내부적으로 들고 있는 백버퍼를 꺼냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__uuidof는 이 인터페이스로 달라는 요청.&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;2. 뷰 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리소스는 뷰와 다름. GPU는 리소스에 직접 접근하지 않고 항상 뷰를 통해 접근&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 텍스처 하나를 이번 패스에선 그릴 대상(RTV)로, 다음 패스에선 셰이더가 읽는 텍스처(SRV)로 쓸 수 있음&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;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 style=&quot;width: 29.4961%;&quot;&gt;뷰&lt;/td&gt;
&lt;td style=&quot;width: 37.1705%;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 29.4961%;&quot;&gt;RTV (Render Target View)&lt;/td&gt;
&lt;td style=&quot;width: 37.1705%;&quot;&gt;여기다 그린다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 29.4961%;&quot;&gt;SRV (Shader Resource View)&lt;/td&gt;
&lt;td style=&quot;width: 37.1705%;&quot;&gt;셰이더에서 읽는다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 29.4961%;&quot;&gt;DSV (Depth Stencil View)&lt;/td&gt;
&lt;td style=&quot;width: 37.1705%;&quot;&gt;깊이, 스텐실 판정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 29.4961%;&quot;&gt;UAV (Unordered Accessn View)&lt;/td&gt;
&lt;td style=&quot;width: 37.1705%;&quot;&gt;셰이더에서 읽고 쓴다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::RenderBegin()
{
	_deviceContext-&amp;gt;OMSetRenderTargets(1, _renderTargetView.GetAddressOf(), nullptr);
	_deviceContext-&amp;gt;ClearRenderTargetView(_renderTargetView.Get(), _clearColor);
	_deviceContext-&amp;gt;RSSetViewports(1, &amp;amp;_viewport);
}&lt;/code&gt;&lt;/pre&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;&amp;nbsp;&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 style=&quot;width: 26.9767%;&quot;&gt;단계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;IA (Input Assembler)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;VS (Vertex Shader)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;RS (Rasterizer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;PS (Pixel Shader)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.9767%;&quot;&gt;OM (Output Shader)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;void Game::RenderEnd()
{
	HRESULT hr = _swapChain-&amp;gt;Present(1, 0);
	CHECK(hr);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완성된 백버퍼 화면과 교체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 인자는 VSync, 수직 동기화임&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DirectX 11</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/629</guid>
      <comments>https://lagooneng.tistory.com/629#entry629comment</comments>
      <pubDate>Sat, 1 Aug 2026 00:27:02 +0900</pubDate>
    </item>
    <item>
      <title>MatchMaking Svr #1 : UDP Hole Punching + Relay Fallback</title>
      <link>https://lagooneng.tistory.com/628</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Lagooneng/MatchMakingSvr&quot;&gt;https://github.com/Lagooneng/MatchMakingSvr&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776696279918&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - Lagooneng/MatchMakingSvr: C++ TURN-like matchmaking svr (UDP Hole-Punching + UDP relay fallback)&quot; data-og-description=&quot;C++ TURN-like matchmaking svr (UDP Hole-Punching + UDP relay fallback) - Lagooneng/MatchMakingSvr&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Lagooneng/MatchMakingSvr&quot; data-og-url=&quot;https://github.com/Lagooneng/MatchMakingSvr&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/KR2D9/dJMb9hC3nod/aaxKDvNLr34OYlJwGJnhf1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Lagooneng/MatchMakingSvr&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Lagooneng/MatchMakingSvr&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/KR2D9/dJMb9hC3nod/aaxKDvNLr34OYlJwGJnhf1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - Lagooneng/MatchMakingSvr: C++ TURN-like matchmaking svr (UDP Hole-Punching + UDP relay fallback)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;C++ TURN-like matchmaking svr (UDP Hole-Punching + UDP relay fallback) - Lagooneng/MatchMakingSvr&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언리얼 엔진 OSS 디버깅 안되는 거 너무 불편해서 그냥 매치메이킹 서버를 만들고자 시도 중이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UDP Hole Punching으로 직접 IP 알아내게 하고 실패 시 릴레이하게 해놨는데..&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;언리얼을 데디로 싹 뜯어 고치거나 아니면 언리얼 네트워크 계층을 뜯어 고치거나..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니면 다른 방법이 없나..? rnd를 좀 많이 해봐야겠다&lt;/p&gt;</description>
      <category>Game Svr/MatchMakingSvr</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/628</guid>
      <comments>https://lagooneng.tistory.com/628#entry628comment</comments>
      <pubDate>Mon, 20 Apr 2026 23:52:53 +0900</pubDate>
    </item>
    <item>
      <title>RAG, MCP</title>
      <link>https://lagooneng.tistory.com/627</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;검색 증강 생성(RAG)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Retrieval-Agumented Generation&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;/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;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 86.1613%; height: 209px;&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: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.9845%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 36.0077%; height: 17px;&quot;&gt;RAG&lt;/td&gt;
&lt;td style=&quot;width: 36.7944%; height: 17px;&quot;&gt;Fine-tuning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 64px;&quot;&gt;
&lt;td style=&quot;width: 12.9845%; height: 64px;&quot;&gt;정의&lt;/td&gt;
&lt;td style=&quot;width: 36.0077%; height: 64px;&quot;&gt;최신의 외부 데이터에서 적절한 문서 검색 및 답변을 생성해 LLM 모델의 정확성과 신뢰성을 향상시키는 방식&lt;/td&gt;
&lt;td style=&quot;width: 36.7944%; height: 64px;&quot;&gt;사전 학습된 모델에 각 개별 기업의 도메인 특화 데이터를 추가 학습시켜 맞춤형 모델로 업데이트 하는 방식&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 64px;&quot;&gt;
&lt;td style=&quot;width: 12.9845%; height: 64px;&quot;&gt;이점&lt;/td&gt;
&lt;td style=&quot;width: 36.0077%; height: 64px;&quot;&gt;외부 데이터에 대한 상시적 접근 가능&lt;br /&gt;데이터의 최신성 유지에 용이&lt;br /&gt;근거가 확실한 데이터를 기반으로 답변 생성&lt;/td&gt;
&lt;td style=&quot;width: 36.7944%; height: 64px;&quot;&gt;양질의 라벨링 데이터만 있다면 높은 품질의 모델 생성 가능&lt;br /&gt;업데이트가 빈번하지 않은 특정 도메인에서 유용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 12.9845%; height: 43px;&quot;&gt;도전과제&lt;/td&gt;
&lt;td style=&quot;width: 36.0077%; height: 43px;&quot;&gt;관련 없는 문서를 검색할 가능성이 있어 효율적인 검색 모델을 구축해야 함&lt;/td&gt;
&lt;td style=&quot;width: 36.7944%; height: 43px;&quot;&gt;충분한 데이터가 없거나 양질의 데이터가 아닌 경우 모델의 퀄리티가 낮아질 수 있음&lt;br /&gt;모델의 지식은 마지막 훈련 데이터까지만 한정됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 12.9845%; height: 21px;&quot;&gt;유스케이스&lt;/td&gt;
&lt;td style=&quot;width: 36.0077%; height: 21px;&quot;&gt;새로운 데이터가 자주 업데이트 되는 기업&lt;/td&gt;
&lt;td style=&quot;width: 36.7944%; height: 21px;&quot;&gt;특정 작업용 애플리케이션&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;Indexing&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAG 시스템 구축의 첫 단계, 프롬프트에게 제공할 지식 데이터베이스를 구축하는 단계&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;1. 문서 분할&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 임베딩&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 저장&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Retrieval&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 질문 임베딩&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;2. 유사성 비교&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;76&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5rJhw/dJMcai2Rnm5/W6BK9m3B1TD2yvWeb1MCKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5rJhw/dJMcai2Rnm5/W6BK9m3B1TD2yvWeb1MCKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5rJhw/dJMcai2Rnm5/W6BK9m3B1TD2yvWeb1MCKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5rJhw%2FdJMcai2Rnm5%2FW6BK9m3B1TD2yvWeb1MCKk%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;372&quot; height=&quot;76&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;76&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 관련 문서 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 유사도 점수를 바탕으로 가장 높은 상위 k개의 문서 청크를 선택&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;Generation&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAG의 종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Naive RAG&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Advanced RAG&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Modular RAG&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;* FAISS&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* RAG을 사용하면 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;/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;- LLM 로딩 최적화&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Vector database&lt;/b&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangChain의 문서 관리 도구&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Document Loader가 다양한 소스에서 문서를 불러오고 처리하는 과정을 담당&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;벡터 데이터베이스&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;- Pinecone, Chroma, Weviate, Milvus, Faiss, Qdrant..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Chroma는 LLM 앱을 위한 최적화가 있음&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;벡터 DB 선택 시 고려 사항&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;- 사용 편의성: 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;Chroma&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RAG 구축 시 많이 사용되는 오픈소스 벡터 데이터베이스&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;&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCP (Model Context Protocol)&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;- 기존의 API 연동 방식이 모델마다, 도구마다 개별적으로 필요했던 복잡성을 해소하고 llm 기반 애플리케이션 개발과 확장성과 신뢰성을 높이는 것을 목표로 함&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;MCP vs tool calling&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MCP는 도구의 발견, 연결, 호출, 보안을 위한 표준화된 통신 및 아키텍처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Tool Calling은 llm이 도구를 사용하도록 만드는 언어&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 98.7213%;&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: 15.0775%;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 44.5294%;&quot;&gt;Tool Calling&lt;/td&gt;
&lt;td style=&quot;width: 46.5683%;&quot;&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%;&quot;&gt;개념적 역할&lt;/td&gt;
&lt;td style=&quot;width: 44.5294%;&quot;&gt;llm의 의도 파악 및 도구 사용 결정 언어&lt;/td&gt;
&lt;td style=&quot;width: 46.5683%;&quot;&gt;llm과 외부 도구, 데이터 간 표준 통신 인프라&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%;&quot;&gt;핵심 기능&lt;/td&gt;
&lt;td style=&quot;width: 44.5294%;&quot;&gt;1. 모델이 호출할 함수의 JSONSchema 이해&lt;br /&gt;2. 사용자 요청에 따라 함수 호출 필요 여부 및 인수 결정&lt;/td&gt;
&lt;td style=&quot;width: 46.5683%;&quot;&gt;1. 외부 도구, 데이터의 발견 및 등록 표준화&lt;br /&gt;2. 보안, 인증, 전송 규격 정의&lt;br /&gt;3. 다양한 llm 간의 도구 재사용성 보장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%;&quot;&gt;구현 방식&lt;/td&gt;
&lt;td style=&quot;width: 44.5294%;&quot;&gt;llm 내부의 추론 과정에서 json 객체를 출력하여 호출 의도를 표현&lt;/td&gt;
&lt;td style=&quot;width: 46.5683%;&quot;&gt;Host - Client - Server 구조를 갖는 외부 프로토콜&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%;&quot;&gt;상호 운용성&lt;/td&gt;
&lt;td style=&quot;width: 44.5294%;&quot;&gt;모델 제공 업체에 의해 정의된 특정 json 스키마에 의존&lt;/td&gt;
&lt;td style=&quot;width: 46.5683%;&quot;&gt;개방형 표준이므로 llm 종류와 무관하게 모든 mcp 규격을 따르는 도구를 사용 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%;&quot;&gt;보안/인증&lt;/td&gt;
&lt;td style=&quot;width: 44.5294%;&quot;&gt;보통 툴 콜링 자체는 보안을 안다루고 실제 호출은 별도의 api 키나 인증 방식으로 처리&lt;/td&gt;
&lt;td style=&quot;width: 46.5683%;&quot;&gt;보안 및 인증 메커니즘을 내제&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCP의 기본 아키텍처&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;- 사용자의 요청을 받아서 llm에 전달하고 최종 응답을 사용자에게 보여줌&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;MCP 클라이언트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 호스트 애플리케이션 내부에 통합되어 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- llm과 mcp 서버 간의 통신을 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- llm이 도구를 사용해야 한다고 판단하면 이 클라이언트가 mcp 서버에 요청을 보냄&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;MCP 서버&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 실제 외부 기능이나 데이터 소스에 연결되는 로직을 포함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클라이언트로부터 mcp 규격에 맞는 요청을 받아 실제 작업을 수행하고 그 결과를 다시 클라이언트에 반환&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCP가 가져온 변화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;툴 재사용성 증가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 한 번 MCP 서버로 구현된 도구는 다양한 llm에서 코드 수정없이 재사용될 수 있음&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MCP는 보안, 접근 제어, 감사 기록 등에 대한 명확한 규약을 포함하고 있어 기업 환경에서 llm 에이전트를 안전하게 배포 가능&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- llm 에이전트가 RAG을 넘어 복잡한 업무 자동화를 수행할 수 있게 되어 llm의 유틸리티를 극대화&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCP 개발 프레임워크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토콜 표준을 중심으로 다양한 서버 및 클라이언트 구현체가 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangChain&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기존의 에이전트 프레임워크로 MCP 서버를 도구처럼 활용할 수 있는 어댑터를 제공&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;smolagent (Hugging Face)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 허깅 페이스의 LocalPythonExecutor와 함께 사용하여 MCP를 AI 어시스턴트와 통합 가능&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;GitHub MCP&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;FastAPI-MCP&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 개발자가 자신만의 MCP 서버를 쉽게 구축할 수 있도록 돕는 라이브러리&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;Cursor MCP Installer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 개발 편의성을 위해 Cursor IDE에 MCP 서버를 자동으로 추가하는 도구&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>학부/딥러닝</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/627</guid>
      <comments>https://lagooneng.tistory.com/627#entry627comment</comments>
      <pubDate>Wed, 10 Dec 2025 00:55:18 +0900</pubDate>
    </item>
    <item>
      <title>AI Agent, Context Engineering</title>
      <link>https://lagooneng.tistory.com/626</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AI 에이전트&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;- 능동형 AI&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;AI 에이전트의 주요 특징&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;/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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이전트의 종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Zero-shot ReAct&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 작업과 도구 설명을 보고 사용할 도구를 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ReAct는 Reasoning + Acting&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Resoning은 생각(Chain-of-Thought, COT), Acting은 외부 도구 실행을 의미&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;Structured Input ReAct&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;Conversational&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대화 + ReAct로 대화 히스토리 저장을 위한 메모리가 필요&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;Self-ask with search&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;ReAct document store&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 문서 저장소 + ReAct로 문서 검색 도구가 필요&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이전트의 작업 절차&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Input : 사용자가 에이전트에 작업 할당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Thought : 에이전트가 작업을 완수하기 위해 무엇을 할 지 생각&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Action / Action Input : 사용할 도구를 결정하고 도구의 입력(함수의 입력값)을 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Observation : 도구의 출력 결과를 관찰&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 관찰 결과 작업을 완료했다는 판단에 도달할 때까지 2~4 반복&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI Agent 프레임워크&lt;/b&gt;&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;/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;AI Agent 프레임워크 선택 시 고려 사항&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다양한 LLM 및 소프트웨어 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;- AI 에이전트 플랫폼이 사용자의 개입 없이 복잡한 작업을 자동으로 실행할 수 있는가&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;&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;&lt;b&gt;주요 프레임워크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangChain &amp;amp; LangGraph&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;- LLM을 활용하여 에이전트를 구축하는데 필요한 다양한 도구와 기능을 제공&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;CrewAI&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 파이썬 기반 오픈소스 프레임워크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 여러 AI 에이전트들이 협력하여 문제를 해결하는 분산형 AI 에이전트의 구축을 지원&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LlamdaIndex&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;- 검색 기반 AI 시스템이나 지식 관리 시스템을 구축하는데 유용&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;AutoGen&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;&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;Agent 개발에 자주 사용되는 LangChain 요소&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; OpenAI의 ChatGPT 등 여러 LLM 제공 업체와 연결하는 인터페이스를 제공&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LLM에 입력될 프롬프트를 구성하고 관리하는 PromptTemplate과 같은 도구를 포함&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;체인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일련의 구성 요소를 연결하여 복잡한 작업을 자동화하는 구조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LLMChain, ConversationChain 등이 대표적&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;에이전트&lt;/b&gt;&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;&amp;nbsp;&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;p data-ke-size=&quot;size16&quot;&gt;- 검색, DB, 파일 시스템, API, 사용자 정의 도구&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;/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;문서 로더 및 텍스트 분할기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RAG 파이프라인에서 다양한 형식의 문서를 불러오고 처리하기 쉬운 작은 청크로 분할하는데 사용&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;/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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LangChain Agents&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ReAct 기반 에이전트 개발을 지원&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Agent : 의사 결정을 담당하는 핵심 컴포넌트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Tools : 에이전트가 사용할 수 있는 기능들의 집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Toolkits : 관련된 도구들의 그룹&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AgentExecutor : 에이전트의 실행을 관리하는 컴포넌트&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;* ReAct&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Reasoning and Actng의 약자, 챗봇이 추론과 행동을 체계적으로 결합하여 문제를 해결하고 정보를 제공하는 프레임워크&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;- 헹동 : 외부 환경과 상호작용하여 필요한 정보를 수집하고 이를 바탕으로 작업을 수행&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;* RAG&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Retrieval-Augumented Generation (검색 증강 생성)&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;- 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;- LLM 자체를 재학습 시키는 대신 외부 데이터베이스만 업데이트하면 되므로 비용과 시간을 절약&lt;/p&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;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Context Engineering&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;context : llm이 응답을 생성할 때 참고할 수 있는 입력 정보의 범위&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;context 구성 요소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- prompt : 사용자가 입력한 전체 텍스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- system / instruction : 모델의 역할이나 스타일을 지정하는 초기 지침&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- user / assistant messages : 이전 대화 내용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- rerieved docments(선택적) : RAG 등에서 외부 검색 결과를 추가하여 문맥 확장 가능&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;Context window&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Context Engineering은 대형 언어 모델의 성능을 극대화하기 위해 정보 환경을 체계적으로 설계하는 것&lt;br /&gt;- 단순히 프롬프트를 최적화하는 Prompt Engineering을 넘어서는 개념&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;- 에이전트가 매 단계마다 필요한 정보만을 적절히 선택, 압축, 저장, 격리해서 llm의 컨텍스트 윈도우에 넣는 전략적 시스템 설계 작업&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;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 60.9303%;&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: 8.3333%;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 23.3866%;&quot;&gt;Prompt Engineering&lt;/td&gt;
&lt;td style=&quot;width: 29.7503%;&quot;&gt;Context Engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.3333%;&quot;&gt;범위&lt;/td&gt;
&lt;td style=&quot;width: 23.3866%;&quot;&gt;단일 입력, 출력&lt;/td&gt;
&lt;td style=&quot;width: 29.7503%;&quot;&gt;전체 시스템 흐름, 메모리, 도구 통합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.3333%;&quot;&gt;지속성&lt;/td&gt;
&lt;td style=&quot;width: 23.3866%;&quot;&gt;일회성&lt;/td&gt;
&lt;td style=&quot;width: 29.7503%;&quot;&gt;멀티턴, 세션 또는 장기 메모리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.3333%;&quot;&gt;목표&lt;/td&gt;
&lt;td style=&quot;width: 23.3866%;&quot;&gt;명확한 지시&lt;/td&gt;
&lt;td style=&quot;width: 29.7503%;&quot;&gt;정황 환경 구성, 상태 유지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.3333%;&quot;&gt;기술&lt;/td&gt;
&lt;td style=&quot;width: 23.3866%;&quot;&gt;문장 조정, 예시, few-shot&lt;/td&gt;
&lt;td style=&quot;width: 29.7503%;&quot;&gt;RAG, 스크래치패드, 동적 데이터, 툴 체인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 8.3333%;&quot;&gt;스케일&lt;/td&gt;
&lt;td style=&quot;width: 23.3866%;&quot;&gt;소규모 테스트&lt;/td&gt;
&lt;td style=&quot;width: 29.7503%;&quot;&gt;실전 시스템, 다양한 유저 및 플로우&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangChain에서 제공하는 네가지 핵심 전략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- write : 정보를 외부 스크래치패드나 메모리에 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- select : 필요한 정보를 필요할 때 컨텍스트로 불러오기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- compress : 긴 기록은 요약 등으로 축소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- isolate : 서로 다른 주제는 분리 저장 등&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;1. Write : 컨텍스트를 어디에 남길 것인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자가 말한 중요한 내용을 에이전트가 직접 기억을 못하니 외부 메모리에 명시적으로 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LangChain애서는 Memory, Dict, Scratchpad, Vector Stroe 등..&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;2. Select : 기억을 다 보여줄 필요는 없고 필요한 것만&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;- 방법: 조건 필터링, 태그 기반 메모리 조회, Vector Similarity 등&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. Compress : 핵심만&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;- 긴 기록을 그대로 넣으면 토큰이 초과하거나 llm이 핵심을 못잡거나..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- llm 써서 요약하거나 rule-based 방식으로 요약 또는 추출&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;4. Isolate : 서로 다른 주제는 분리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하나의 사용자와 여러 주제를 동시에 다룰 때 정보가 섞이지 않도록 각 주제별로 따로 나누어 저장하고 사용할 때도 명확히 구분해서 불러오기&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;</description>
      <category>학부/딥러닝</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/626</guid>
      <comments>https://lagooneng.tistory.com/626#entry626comment</comments>
      <pubDate>Mon, 8 Dec 2025 02:15:28 +0900</pubDate>
    </item>
    <item>
      <title>LangChain, LangGraph</title>
      <link>https://lagooneng.tistory.com/625</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Ollama&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자가 자신의 컴퓨터에 대규모 언어 모델을 쉽게 설치하고 실행할 수 있도록 돕는 도구&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷 연결 없이도 로컬 환경에서 AI 모델을 활용할 수 있게 해주며 복잡한 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;&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Prompt Engineering&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;Prompt&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- prompt engineering이 필요&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;Prompt engineering&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;구성 요소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Instructions&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;External Information or context(s)&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;User input or query&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;Output indicator&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;효율적인 프롬프트의 예&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역할(Role)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목표(Goal)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥락(Context)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지시사항(Instructions)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제약사항(Constraints)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과설정(Output)&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;- 톤 &amp;amp; 매너&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;Chain-of-Thought(CoT) Prompting&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;- 언어 모델이 답을 찾아가는 과정에서 생각을 말로 표현하거나(think aloud) 단계별 추론 과정(step-by-step reasoning)을 따르도록 유도하는 방식으로 구성&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;&lt;b&gt;Few-shot prompting&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;/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;/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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;zero-shot prompting : 예시 제공 없이 질의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;one ~ : 하나의 예시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Few ~ : 몇 개의 예시&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LangChain&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LangChain 프레임워크의 구성&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;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;&lt;b&gt;랭체인 템플릿&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;&amp;nbsp;&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;- 랭체인 체인을 REST 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;&lt;b&gt;랭스미스&lt;/b&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1765121556819&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama import ChatOllama

template = &quot;&quot;&quot;
	당신은 QA(Question-Answering)을 수행하는 Assistant입니다.
	{question}에 대해 설명하세요
	5문장 이내로 으로 답변하세요.
	&quot;&quot;&quot;

prompt = ChatPromptTemplate.from_template(template)

llm_model = ChatOllama(model=&quot;PetrosStav/gemma3-tools:4b&quot;)

rag_chain = prompt | llm_model

def answer_for(question):
	print(&quot;Answer :&quot;)
	for chunk in rag_chain.stream({&quot;question&quot;: question}):
		print(chunk.content, end=&quot;&quot;, flush=True)
	
	print(&quot;\n&quot;)&lt;/code&gt;&lt;/pre&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;pre id=&quot;code_1765121675299&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;template = &quot;&quot;&quot;
	당신은 QA(Question-Answering)을 수행하는 Assistant입니다.
	{month}에 적합한 {event}를 추천해 주세요.
	5문장 이내로 으로 답변하세요.
	&quot;&quot;&quot;&lt;/code&gt;&lt;/pre&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;&lt;b&gt;chat prompt&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ChatPromptTemplate은 대화형 상황에서 여러 메시지 입력을 기반으로 단일 메시지 응답을 생성하는데 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대화형 모델이나 챗봇 개발에 주로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 입력은 여러 메시지를 원소로 갖는 리스트로 구성, 각 메시지는 역할(role)과 내용(content)으로 구성&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SystemMessage : 시스템의 기능을 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HumanMessage : 사용자의 질문&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AIMessage : AI 모델의 응답을 제공 (대화의 history를 기억시키는 역할)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- FunctionMessage : 특정 함수 호출의 결과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ToolMessage : 도구 호출의 결과&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 싱글턴(single-turn) : 바로 직전의 질문에만 대답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 멀티턴(multi-turn) : 이전 대화를 계속 기억해 나가면서 대화를 이어나가는 것, 전체 대화의 맥락을 이해&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1765122330180&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from langchain_core.prompts import ChatPromptTemplate
from langchain_ollama import ChatOllama

message = [
	(&quot;system&quot;, &quot;너는 여행관련 전문가야.&quot;), # 역할 부여
	(&quot;system&quot;, &quot;너는 한국어로 대화해.&quot;), # 작업지시
	(&quot;placeholder&quot;, &quot;{chat_history}&quot;), # 대화이력 저장
	(&quot;user&quot;, &quot;{user_input}&quot;), # 사용자 입력
]

chat_prompt = ChatPromptTemplate.from_messages(message)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;placeholder : 원하는 위치에 동적으로 삽입될 메시지를 추가하기 위한 기능&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;pre id=&quot;code_1765122401543&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;llm_model = ChatOllama(model=&quot;PetrosStav/gemma3-tools:4b&quot;)

rag_chain = chat_prompt | llm_model

chat_history = [
	(&quot;ai&quot;, &quot;안녕하세요, 저는 여행 전문가 브라이언 입니다. 반갑습니다.&quot;),
	(&quot;user&quot;, &quot;안녕, 나는 길동이야&quot;),
	(&quot;user&quot;, &quot;나는 여행을 좋아해. 너는 어떤 여행지를 추천해줄 수 있어?&quot;),
	(&quot;ai&quot;, &quot;세계 여러 나라의 여행지를 추천해 줄 수 있습니다. &quot;),
]

def answer_for(user_input):
	chat_history.append(
		(&quot;human&quot;, user_input,)
	)
    
	whole_answer = &quot;&quot;
    
	for chunk in rag_chain.stream({&quot;chat_history&quot;: chat_history, &quot;user_input&quot;: user_input}):
		print(chunk.content, end=&quot;&quot;, flush=True)
		whole_answer += chunk.content
		chat_history.append(
			(&quot;ai&quot;, whole_answer,)
		)
        
		print(&quot;\n&quot;)&lt;/code&gt;&lt;/pre&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;LangGraph&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기존 랭체인의 장점은 유지하면서도 더 복잡하고 상태(State)를 가진 다단계 추론 프로세스(Agentic Workflow)를 명확하게 정의하고 제어하기 위해 등장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 랭체인이 LLM 애플리케이션 개발을 위한 도구 상자 역할을 했다면 LangGraph는 그 도구들을 조합하여 유한 상태 기계 형태의 복잡한 추론 흐름을 구현하는데 초점&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡한 제어 흐름의 구현 어려움&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 결국 워크플로우 간 상태관리를 하며 플로우를 더 쉽게 작성할 수 있도록 하는 프레임워크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 랭체인 에이전트는 Production 용도에는 적합하지 않다는 권고, 랭그래프 사용을 권장함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 71.5116%;&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: 18.7199%;&quot;&gt;비고&lt;/td&gt;
&lt;td style=&quot;width: 25.711%;&quot;&gt;LangChain&lt;/td&gt;
&lt;td style=&quot;width: 27.0806%;&quot;&gt;LangGraph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.7199%;&quot;&gt;prompt&lt;/td&gt;
&lt;td style=&quot;width: 25.711%;&quot;&gt;Reasoning 과정 직접 작성&lt;/td&gt;
&lt;td style=&quot;width: 27.0806%;&quot;&gt;단순한 Agent 역할 부여&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.7199%;&quot;&gt;ReAct의 구현&lt;/td&gt;
&lt;td style=&quot;width: 25.711%;&quot;&gt;프롬프트로 정의&lt;br /&gt;+ 랭체인 내부 구현&lt;/td&gt;
&lt;td style=&quot;width: 27.0806%;&quot;&gt;LangGraph로 구현&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.7199%;&quot;&gt;Function Call&lt;/td&gt;
&lt;td style=&quot;width: 25.711%;&quot;&gt;프롬프트를 이용해서 LLM이 툴을 사용하게 유도&lt;/td&gt;
&lt;td style=&quot;width: 27.0806%;&quot;&gt;LLM 학습 당시 구현한 Tool Call API 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.7199%;&quot;&gt;Tool 사용 가능 모델&lt;/td&gt;
&lt;td style=&quot;width: 25.711%;&quot;&gt;모든 모델&lt;/td&gt;
&lt;td style=&quot;width: 27.0806%;&quot;&gt;Tool Call이 가능한 모델&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tool Calling (도구 호출)&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도구 호출을 사용하는 이유&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;/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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 사용자 입력 : 사용자가 AI가 직접 답을 알지 못하거나 외부 데이터가 필요할 수 있는 질문 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 도구 식별 : 모델은 질문에 답하기 위해 도구를 사용해야 함을 감지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 도구 요청 : 모델은 도구에 대한 요청을 형식화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 도구 실행 : 도구는 요청을 처리하고 결과를 반환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 응답 구성 : AI는 도구의 응답을 사용자 친화적인 답변으로 통합&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;LangGraph 정의 단계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- State 정의&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;</description>
      <category>학부/딥러닝</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/625</guid>
      <comments>https://lagooneng.tistory.com/625#entry625comment</comments>
      <pubDate>Mon, 8 Dec 2025 01:02:46 +0900</pubDate>
    </item>
    <item>
      <title>Hugging face</title>
      <link>https://lagooneng.tistory.com/624</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Hugging face&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기계학습 모델을 구축, 배포 및 교육하기 위한 도구와 리소스를 개발하는 프랑스계 미국 회사이자 오픈 소스 커뮤니티&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;다양한 오픈소스 LLM 모델들과 라이브러리를 제공&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;/p&gt;
&lt;pre id=&quot;code_1765114111114&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;meta-llama/Llama-3.1-8B-Instruct&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;meta-llama : 모델 개발업체 / 개발자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Llama-3.1-8B-Instruct : 모델명(checkpoint)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.1 : 버전&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8B : 매개변수의 수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Instruct&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 일반 노트북이나 데탑은 4B 이하 모델이 현실적&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;Instruction Tuning&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context In 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;/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;- 외부 데이터(RAG)&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;Context(window) Length&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;- 이 값이 클 수록 유리하나 계산이 지수적으로 증가&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;LLM 모델의 저장 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Safetensor&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;- 구성 요소: JSON 헤더, 바이너리 데이터 블록&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;GGUF (GPT-Generated Unified Format)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- llama.cpp 프로젝트에서 개발된 포맷&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- llm을 효율적으로 저장하고 CPU 및 GPU에서 실행할 수 있도록 최적화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- safetensors와 마찬가지로 pickle 기반의 보안 취약점을 해결하고 모델 로딩 속도 및 효율성을 개선하는데 중점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Ollama의 모델들은 이 포맷&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;ONNX (Open Neural Network)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Meta, Microsoft 주도 개발&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 딥러닝 모델을 표현하기 위한 개방향 표준 포맷&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다양한 딥러닝 프레임워크에서 학습된 모델을 ONNX 형식으로 변환하여 다른 프레임워크나 런타임에서 추론할 수 있도록 함&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;Transformer&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;- 트랜스포머 기반의 다양한 모델을 파이토치, 텐서플로우로 각각 구현해놓은 모듈이며 각 모델에 맞는 tokenizer도 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사전 학습된 최첨단 모델들을 쉽게 다운로드하고 훈련시킬 수 있는 API와 도구 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Pipeline을 통한 고수준 추상화 제공&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- NLP : 텍스트 분류, 텍스트 생성, 개체명 인식, 질의응답, 빈칸 채우기, 요약, 번역&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CV : 이미지 분류, 이미지 분할, 객체 탐지&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Tokenizer&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;datasets&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;diffuser&lt;/b&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;accelerate&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;- 대규모 모델을 효과적으로 학습하기 위해서는 여러 GPU를 사용한 병렬처리가 필수적인데 매우 복잡한 과정이 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이러한 작업을 추상화를 통해 간단한 API로 제공&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pipeline&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- transformers 라이브러리의 가장 기본 객체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 모델 사용을 위한 인터페이스 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전처리 + 후처리 과정을 모델과 연결하여 쉽게 NLP 모델을 사용할 수 있게 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Transformer를 사용하는 가장 간단한 수단&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;Pipeline으로 가능한 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- sentiment-analysis : 감정 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- question-answering : 질의 응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- text-generation : 텍스트 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- translation : 번역&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- summarzation : 요약&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;- image-classification : 이미지 분류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- object-detection : 객체 탐지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- image-to-text : 이미지에 캡션 달기&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;- feature-extraction : 특징 추출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- fill-mask : 마스크 채우기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ner : 개체명 인식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- zero-shot-classification : 제로샷 분류&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;* Type of ansert&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 추출적(Extractive) 질의 응답 : 주어진 문맥에서 답변을 추출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 생성적(Abstractive) 질의 응답 : 문맥에서 질문에 올바르게 답하는 답변을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>학부/딥러닝</category>
      <author>라구넹</author>
      <guid isPermaLink="true">https://lagooneng.tistory.com/624</guid>
      <comments>https://lagooneng.tistory.com/624#entry624comment</comments>
      <pubDate>Sun, 7 Dec 2025 23:42:42 +0900</pubDate>
    </item>
  </channel>
</rss>