컴파일되어 사라지다

다음에 무엇이 자동화될지를 그리는 지도

영어 원문에서 옮김

Link to slide

2023년에 나는 아무도 청한 적 없는 소설을 쓰는 시스템을 만들었다. 다중 에이전트 오케스트레이션 프로젝트였고, 소설을 부하 시험 삼아 겨눈 것이었다. 전제는 재귀적이었다. 한 프로그래머가 AI를 써서, AI를 써서 소설을 쓰는 프로그래머에 관한 소설을 쓴다. 아홉 겹 깊이로. 주인공은 저마다 끝내, 자기가 한 층 위의 누군가가 쓴 이야기 속 인물이며, 동시에 한 층 아래를 쓰고 있음을 알아차린다. 그러면서도 저마다 한동안은 자기가 펜을 쥔 쪽이라 믿는다.

나는 그것을 발표했다. 흥미로운 대목은 엔지니어링이라고, 중첩된 서사 틀을 가로질러 에이전트를 협응시키는 도전이라고 여겼다.

내가 무엇을 만들었는지를 나는 잘못 알고 있었다.

깨닫는 데 두 해가 걸렸다. 그 소설의 모든 주인공은 자기가 제 이야기의 근원이라 믿었다. 그리고 저마다, 알고 보니 누군가의 이야기 한가운데였다.

나는 내가 가장 위층인 줄 알았다. 명세를 쓰는 자. 근원. 내가 어쩌면 어딘가 중간에 있을지 모른다는 것을 깨닫는 데 두 해가 걸렸다.

나는 AI 시스템을 만들며 먹고산다. 십 년째다. 기계 학습, 언어 모델, 연구부터 프로덕션까지 전 영역. 그리고 그 기계실 안에서 내가 보고 있는 것은 지식 노동의 구조적 개편인데, 바깥의 대다수는 아직 보지 못한다. 그들이 충분히 똑똑하지 않아서가 아니라, 그 메커니즘에 손을 얹고 있지 않아서다.

이것이 내가 선 자리에서 보이는 것이다.

열 시간 만에 본 것

어느 아침 나는 몇 주째 머릿속에 굴려 온 무언가를 만들려 앉았다. 데이터베이스 하나, 외부 API 연동 몇 개, 처리 파이프라인 하나를 갖춘 서비스. 알고리즘 때문에 어려웠던 적은 한 번도 없고 늘 가장자리 때문에 어려운 그런 종류의 것. 한 달은 걸리리라 짐작했다. 어쩌면 더.

에디터를 열고, 코딩 에이전트를 연결하고, 무엇을 원하는지 설명하기 시작했다.

두 시간째에 나는 코드를 쓰고 있지 않았다. 자연어로 의도를 설명하고 있었고, 에이전트가 이미 내놓은 것에 대한 수정으로 그렇게 하고 있었다. 에이전트가 컴포넌트 하나를 생성한다. 나는 내가 명시하지 않은 무언가를 그것이 추론해 넣은 자리를 잡아내, 다시 명세한다. 다시 쓰는 게 아니다. 다시 명세하는 것이다.

뚜렷이 구별되는 두 가지 실패가 있었다. 첫째는 에이전트가, 내가 일러 줄 수도 있었던 무언가를 잘못 짚었을 때다. 그것은 외부 호출을 동기식 요청-응답으로 엮었는데, 나는 재시도 큐를 둔 발사 후 망각 방식을 원했다. 하류 서비스가 부하를 받으면 흔들리리라는 것, 그리고 거기서 블로킹하면 연쇄로 무너지리라는 것을 경험으로 알았기 때문이다. 그것은 명세 실패였다. 내가 내 뜻을 말하지 않은 것이다. 알아채고 나면 고치기 쉬웠다.

둘째 종류는 더 묘했다. 나는 시스템의 컴포넌트가 서로 어떻게 맞물려야 하는지, 이미 다가옴이 느껴지는 기능을 위해 경계가 어디서 숨 쉴 틈을 두어야 하는지에 관한 심상이 있었다. 각 모듈의 요구사항은 진술할 수 있었다. 전할 수 없었던 것은 그 구성 전체를 안정되게 만드는 불변식의 집합이었다. 고칠 때마다 한 이음매는 나아졌으나 전체의 형태가 흐트러졌다. 병목은 인터페이스였다. 내가 명세하는 능력도, 에이전트가 실행하는 능력도 아니었다.

하나는 명세 실패였다. 다른 하나는 투영 실패였다. 그때 나에게는 아직 그 말이 없었다.

다섯 시간째에 나는 십 년의 엔지니어링에서 알아본 적 없는 리듬에 자리 잡았다. 명세하고, 검토하고, 잡아내고, 다시 명세한다. 나는 아키텍처 결정을 구현하는 게 아니라 평가하고 있었다. 번역 작업은 에이전트가 하고 있었다. 몇 주 동안 내 손과 내 화면을 차지했을 그 부분을. 내 일은 완전히 다른 무엇이 되어 있었다. 그 번역이 충실한지 살피는 일.

여덟 시간째에 나는 작동하는 시스템을 손에 쥐었다. 기능하고, 시험을 거쳤고, 배포되었다. 그 열 시간에서 나온 것은 숙련된 팀이라도 몇 주가 걸렸을 일이었다. 코드가 더 나아서가 아니다. 내가 뜻한 것에서 존재하는 것으로의 번역이, 내가 손으로 수행하지 않고도 일어났기 때문이다.

에이전트가 하고 있던 일에는 정확히 들어맞는 구조적 용어가 있다. 그것은 컴파일이었다. 더 높은 추상 수준의 표현을 더 낮은 수준의 실행 가능한 형태로 번역하는 일. 비유로서가 아니라 구조적으로. 컴파일러는 단지 압축만 하지 않는다. 선택을 확정하며, 한번 확정되면 다른 길은 사라진다. 내 의도는 풍부했다. 나온 것은 돌아가는 코드였다. 잃어버린 것들은(내 이유, 내 취향, 무엇이 여섯 달 뒤에 깨질지에 관한 암묵적 지식) 에이전트가 나빠서 잃은 게 아니라, 목표 표현이 그것들을 담을 수 없어서 잃은 것이다.

번역이 아니다. 번역은 동등한 고도를 함의한다. 압축도 아니다. 압축은 가역성을 함의한다. 증류도 아니다. 증류는 잃은 재료가 잡음이었음을 함의한다. 컴파일이다. 방향이 있고, 실행 가능하며, 되돌릴 수 없이 손실적이다. 이것은 특정한 부류의 일에 관한 주장이다. 의도를, 세상에서 돌아가야 하는 산출물로 번역하는 일. 진정으로 새로운 무언가를 만들어 내는 생성은 다른 연산이다.

내 아래층, 내 의도를 내 손으로 직접 코드로 번역하며 여러 해를 보낸 그 층이 한 아침에 사라졌다. 그리고 내 층을 잃는다는 그 두려움이야말로, 나를 그 위층으로 밀어 올리고 있던 바로 그것이었다.

나는 몇 달째 이 상태로 살고 있다. 날마다 내가 하는 일을 배워 가는 시스템과 함께 일하고, 그 자각은 나를 한 번도 다뤄 본 적 없는 수준에서 생각하도록 떠민다. 내가 성장하기를 골라서가 아니다. 발밑이 움직여서다. 그리고 그 위에서 내가 발견한 것은, 전에는 보지 못한 패턴을 보고, 짓지 않았을 연결을 짓고, 일 년 전이라면 불가능했을 속도와 추상 수준으로 일을 내놓을 수 있다는 것이다.

내가 떠올릴 수 있는 모든 지식 노동의 역할은 하나의 컴파일 단계다. 전략을 계획으로. 계획을 과제로. 과제를 코드로. 판단을 결정으로. 취향을 명세로. AI는 이 컴파일이 자동화되고 있는 곳이다. 구조는 늘 거기 있었다. 자동화가 새로운 것이다.

그리고 AI는 이 번역을 하나하나 수행하는 법을 배워 가고 있다. 명세 간극(Spec Gap)이 가장 작은 곳에서 시작하면서.

왜 바닥에서 시작하는가

AI가 전략보다 코드를 먼저 정복한 데는 이유가 있다. 그리고 그 이유가, 다음에 무엇이 맞을지를 정확히 일러 준다.

내가 AI 에이전트에게 기능 하나를 만들라 지시할 때, 내 의도는 일부만 명세된다. 나는 무엇을 원하는지 알지만, 그것을 전부 말하지는 않았다. 에이전트는 멈춰 묻지 않는다. 짐작한다. 그리고 여기, AI로 무언가를 만드는 대다수가 아직 온전히 흡수하지 못한 점이 있다. 모든 AI 출력은 당신이 원한 것과 기계가 당신이 원했으리라 추론한 것의 혼합물이며, 둘은 뒤섞인 채 표시도 없다. 어느 부분이 당신 의도에서 왔고 어느 부분이 모델의 추론에서 왔는지 표시할 수 없다면, 그 출력을 미덥게 디버깅할 수 없다. 그저 거기에 반응할 수 있을 뿐이다.

나는 이것을 명세 간극이라 부른다. 당신이 뜻하는 것과 당신이 가까스로 명세해 낸 것 사이의 거리. 그것은 AI가 어디서 무너뜨리고 어디서 무너뜨리지 못하는지를 예측하는 단 하나의 변수다. 아직은.

명세 간극에는 두 층이 있다. 그 열 시간에 내가 명세하지 못한 것의 일부는, 다그쳐졌다면 분명히 말로 풀 수 있었을 암묵적 지식이었다. 나는 내가 어떤 오류 처리 방식을 선호하는지 알았다. 그저 말하기를 굳이 하지 않았을 뿐이다. 이것은 말로 풀 수 있는 명세 간극이며, 당신이 의도를 명시하도록 다그쳐질 때마다 줄어든다. 다른 쪽은 더 까다롭다. 내가 뜻한 것의 일부는, 시간이 무한히 있었더라도 명세할 수 없었을 것이다. 어떤 아키텍처가 오래도 잘 버티리라는 느껴지는 감각. 천 번의 지난 실패에서 쌓인, 어떤 접근이 내가 이름 붙일 수 없는 조건에서 깨지리라는 직감. 이것은 말로 풀 수 없는 명세 간극이며, 외부화에 저항하는 의도의 몫이다. 당신이 게을러서가 아니라, 애초에 온전히 적어 낼 수 있는 종류의 것이 아니었기 때문이다.

코드 수준에서 명세 간극은 작다. AI는 여기서 많은 팀의 병목을 지울 만큼 잘 컴파일한다. 이 층은 지금 무너지고 있다. 분석 수준에서 간극은 중간쯤이다. 당신은 원하는 것을 대체로 말로 풀 수 있다. AI는 가벼운 감독으로 그것을 처리한다. 협응 수준에서는 간극이 넓어진다. 의도가 여러 사람에게 흩어져 있고, 그 절반은 말해진 적 없다. 전략 수준에서는 어마어마하다. 조직의 의도는 창발적이고, 모순되며, 아무도 적어 본 적 없는 힘에 빚어진다. 이 층이 가장 오래 버틴다.

이것은 어려움이나 기량의 서열이 아니다. 견고한 코드를 쓰는 일은 어렵다. 다만 그것은 이미 형식적으로 명세된 방식으로 어려우며, 그래서 AI가 그것부터 컴파일한다.

이 기울기는 경향이지 법칙이 아니다. 순서를 실제로 예측하는 것은 추상 수준 그 자체가 아니다. 세 가지다. 의도가 산출물로 얼마나 많이 외부화되어 있는가. 출력을 얼마나 값싸게 검증할 수 있는가. 그리고 오류가 얼마나 비싼가. 이 동인이 추상 수준과 상관되기에 기울기가 대략 아래에서 위로 흐른다. 그러나 진짜 일을 하는 것은 이 동인이다.

오늘 모델이 못 하는 것을 중심으로 계획을 짜지 마라. 당신이 보는 모든 한계는 움직이는 최전선의 한 스냅숏이다. 그리고 그 최전선은 바깥의 누구보다 빠르게 움직이는데, 아래층을 풀면 어지러운 무언가가 드러나기 때문이다. 위층에서 환원 불가능하게 인간적으로 느껴지던 많은 것이, 실은 줄곧 명세 가능했던 것이다. 우리가 그저 명세하도록 다그쳐진 적이 없었을 뿐이다. 코드 생성이 스택의 바닥을 자동화하자, 별안간 나는 전에는 암묵으로 남겨 두었던 아키텍처 의도를 말로 풀어야 했다. 그리고 알고 보니 나는 그것을 풀 수 있었고, 그것은 에이전트가 그것을 컴파일할 수 있다는 뜻이었으며, 그것은 그 층이 다음 차례라는 뜻이었다.

천장은 자꾸만, 아래에서 올려다본 것보다 낮은 것으로 드러난다.

그러나 스택은 나에게서 멈추지 않는다. 내 조직은 나 같은 사람들을 거쳐 자기 전략을 실행 가능한 일로 컴파일한다. 시장은 조직을 거쳐 경쟁 압력을 전략적 대응으로 컴파일한다. 나는 늘, 내 위로 뻗은 컴파일 사슬의 중간층이었다. 그저 위층을 컴파일로 보지 못했을 뿐이다. 그 위층이, 또 하나의 번역되는 표현이라기보다 세상처럼, 표현이 아닌 실재처럼 느껴졌기 때문이다.

나는 근원이 아니다. 나는 중간이다. 그리고 중간층은 컴파일러가 최적화로 없애 버리는 것이다.

최전선과 함께 옮겨 다니는 실패면

지금 가장 큰 혼란을 일으키는 것은 두 가지 특정한 실패면이다. 더 나은 모델이 이 수준에서는 그것을 고칠 것이다. 그러면 같은 실패가 한 층 위에서, 그리고 AI가 도착하는 모든 새로운 영역에서 다시 나타날 것이다. 이것이 현재 모델의 한계가 아니기 때문이다. 컴파일 그 자체의 구조적 특성이다.

첫째는 명세 간극이다. 둘째는, 그 열 시간에 내가 이름 붙이기 전에 느꼈던 것이다. 실패가, 내가 의도를 명세하지 못해서가 아니라 우리 사이의 통로가 그것을 실어 나르지 못해서였던 순간.

당신이 원하는 것을 정확히 명세해도, 출력은 여전히 그 전부를 담지 못한다. 음악에서의 취향을 보라. 당신의 취향은 조건적이고, 기억과 맥락과 기분과, 아무도 함께 갖지 못한 연상에 빚어진다. AI에는 벡터가 필요하다. 템포, 조성, 악기 구성, 에너지 수준. 그 파라미터에 들어맞지 않는 당신 경험의 차원은 잃어버린다. 오늘의 인터페이스를 거치면, 당신의 10점짜리 곡은 누구에게나 7점짜리가 되곤 한다. AI가 실패해서가 아니라, 당신의 내적 상태와 시스템의 입력 사이 통로가, 그 곡을 당신의 것으로 만든 바로 그것을 실어 나르지 못해서다.

나는 이것을 투영 간극(Projection Gap)이라 부른다. 병목은 모델이 내부적으로 저차원이라는 데 있지 않다. 현대 모델은 굉장히 고차원이다. 병목은 인터페이스다. 모델이 당신이 뜻하는 모든 것을 표현할 수 있다 해도, 당신은 여전히 좁은 관을 거쳐 전달한다. 텍스트 프롬프트, 파라미터 슬라이더, 참조 예시, 반복 피드백. 그 통로는 당신의 인지 상태보다 자유도가 적다. 코딩 세션의 명세-검토-수정 리듬은, 인간이 두 간극을 한꺼번에 좁히려는 시도다. 반복하며 명세를 좁히고 통로를 넓히는 것. 도움은 된다. 어느 병목도 없애지는 못한다.

업계는 두 실패를 하나의 문제로(”AI가 내가 원한 대로 안 했어”) 다루고, 그 뒤섞임이 중요한 곳마다 평가를 조용히 망가뜨리고 있다. AI가 무언가를 잃었는지는, 원본이 무엇이었는지 알아야만 확인할 수 있다. 그러나 높은 추상에서 원본은 애초에 온전히 명세된 적이 없다. 그것이 명세 간극이다. 그리고 완벽히 명세된 원본조차 인터페이스를 온전히 통과해 살아남지 못한다. 그것이 투영 간극이다. 둘을 합치면, 당신은 존재하지 않는 한 점으로부터의 거리를 재고 있는 셈이다.

이제 이것을 성장통이 아니라 영속적 구조 조건으로 만드는 대목이다.

더 나은 모델이 코딩 수준에서 두 간극을 좁힌다. 그러면 최전선이 시스템 아키텍처로 올라가고, 명세 간극이 더 넓게 다시 나타난다. 그것을 풀면 제품 전략으로 옮겨 간다. 매번 같은 두 실패면이 더 높은 추상 수준에서 더 넓은 간극으로 떠오른다. 그리고 AI가 새로운 영역에 들어설 때마다 같은 패턴이 새로 나타난다. 명세 간극은 실무자가 알지만 기계에게 말로 풀어내지 못하는 그 무엇이다. 투영 간극은 중요하지만 시스템이 받아들이는 인터페이스를 통과하지 못하는 그 무엇이다.

특정한 문제는 돌고 돈다. 구조는 영속적이다.

그러니 AI에서 가장 중요한 미해결 문제는 더 나은 모델만이 아닐지도 모른다. 그것은 또한 더 나은 명세, 곧 인간이 실제로 원하는 것을 표현하는 더 풍부하고 더 고차원적인 방식일지도 모른다. 모델은 빠르게 나아지고 있다. 그러나 병목은 상류에도, 그 근원에도 있다. 그리고 그것은 상류에 머물 텐데, 컴파일러가 나아질 때마다 근원이 전보다 덜 명세된 수준으로 최전선이 옮겨 가기 때문이다.

중간이 빠지면 무엇이 깨지는가

나는 AI가 이제 맡는 그 일을 하면서 내 판단을 익혔다. 십 년 동안 돌아가지 않는 코드를 썼다. 그것을 디버깅했다. 부하를 받으면 무엇이 깨지는지 배웠다. 여러 해 동안 남들의 의도를 돌아가는 시스템으로 번역했다. 처음엔 서툴게, 그러다 사람들이 더 크고 더 모호한 문제를 내게 맡길 만큼 충분히. 실행에서 지휘로, 지휘에서 판단으로 가는 그 길이, 내가 지금 하는 일을 할 수 있게 된 경로다.

그 길이 컴파일되어 사라지고 있다.

엔지니어링 조직에서 이미 벌어지는 일을 보라. 예전에 주니어 개발자는 경계가 분명한 기능 하나를 처음부터 끝까지 책임졌다. 쓰고, 디버깅하고, 출시하고, 깨진 데서 배운다. 이제는 에이전트가 그 기능을 생성한다. 주니어는, 평가할 맥락이 없는 출력의 검토자가 된다. 그들은 에이전트의 추론을 원래 의도와 구별하지 못하는데, 의도를 스스로 생성하는 근육을 한 번도 길러 본 적이 없기 때문이다. 그것이 명세 간극에서 온 표시 없는 혼합물 문제이고, 이제는 훈련 실패로 작동한다. 조직은 더 빨라진 출력을 본다. 보지 못하는 것은, 시니어들이 기대 온 그 판단을 아무도 키우고 있지 않다는 사실이다.

이것은 엔지니어링에만 있는 일이 아니다. 모든 산업에 같은 경로의 한 판본이 있다. 주니어 분석가가 시니어 분석가가 되고 디렉터가 된다. 어소시에이트 변호사가 파트너가 된다. 레지던트가 어텐딩 의사가 된다. 이 파이프라인이 돌아가는 까닭은, 중간층, 곧 전략을 과제로 또 판단을 실행으로 번역하며 보낸 그 여러 해가, 위층을 위한 판단을 키우는 자리이기 때문이다. 지휘를 공부해서 지휘를 배우는 게 아니다. 번역 작업을 하고, 실패와 마주치고, 무엇이 컴파일을 살아남고 무엇이 못 살아남는지에 대한 취향을 쌓으며 배우는 것이다.

AI가 그 중간층을 컴파일해 없애면, 그것은 거기서 일하던 사람들을 밀어낼 뿐 아니라, 꼭대기에 걸맞은 사람들을 길러 내는 파이프라인을 깨뜨린다.

뻔한 반론은 이렇다. 어쩌면 AI 컴파일러와 나란히 일하는 것 자체가, 다만 압축되었을 뿐인, 하나의 훈련 파이프라인일지 모른다. 두 해 동안 에이전트에게 의도를 명세하고, 그 실패를 잡아내고, 명세 간극과 투영 간극을 실시간으로 구별하는 법을 배운 주니어는, 다섯 해 동안 손으로 코드를 쓴 주니어보다 판단을 더 빨리 키울지 모른다. 어쩌면 도제 모델이 적응한다. 이것이 딱히 틀렸다고는 생각하지 않는다. 그러나 옛 파이프라인은 당신을 번역 안에 살게 했고, 왜 어떤 추상이 부하를 받으면 깨지는지를 손으로 느끼게 했다. 에이전트의 출력을 검토하는 것은, 그것을 스스로 만들어 내는 것과는 다른 인지 연산이다. 검토는 평가적 판단을 훈련한다. 짓는 일은 생성적 판단을 훈련한다. 새 파이프라인이 첫째 종류만 키운다면, 무언가가 잘못됐다는 건 알아채되 옳음이 어떤 모습인지는 말로 풀지 못하는 사람들이 남는다. 우리는 아직 모른다. 실험은 진행 중이다.

어느 쪽이든, 위험은 인지적 유령 GDP(Ghost GDP)다. Citrini Research의 용어를 빌려 비틀었다. 끝내 키워지지 않은 역량. 겉면은 지능처럼 보인다. 그 밑에서는, 진짜 인간의 판단을 길러 내던 파이프라인이 말라 가고 있다.

AI 시스템 자체에도 구조적 간극이 있다. 다들 영역별 컴파일러를 짓고 있다. 그 출력을 화해시키는 시스템을 짓는 이는 거의 없다. 컴파일러 엔지니어링에서는 그것을 링커라 부른다. 이것은 인간과 AI 사이가 아니라 AI 시스템 사이에서 작동하는 투영 간극이다. 컴파일러마다 서로 다른 차원을 떨군다. 그리고 그 빠진 차원이 바로, 영역을 가로지르는 일관성에 필요한 차원이다. 백엔드는 프런트엔드가 명세한 적 없는 데이터 모델을 가정한다. 로드맵은 아키텍처가 받쳐 줄 수 없는 일정을 약속한다. 출력 하나하나는 국소적으로 타당하다. 함께 놓으면 서로 어긋난다. 링킹은, 따로 컴파일된 산출물을 가로지르는 제약 전파다. 그것은 AI 인프라에서 빠진 가장 중요한 조각일지 모른다.

당신이 이 기울기에서 어디에 앉아 있는지 볼 수 있다면, 당신의 기량 중 무엇이 자동화를 기다리는 컴파일 단계이고 무엇이 그 위의 환원 불가능한 명세 작업인지 가려낼 수 있다면, 당신에게는 대다수가 갖지 못한 지도가 있다. 이 틀은 당신의 층이 안전한지는 일러 주지 않는다. 그러나 어느 방향으로 움직여야 하는지는 일러 준다.

내 생각

내가 세 해 전에 만든 그 재귀적 소설은, 알고 보니 컴파일 스택의 작동하는 모델이었다. 같은 실패면이 층마다 되풀이된다. 아홉 번. 어휘를 손에 쥐기 전까지 나는 내가 무엇을 보고 있는지 몰랐다.

물음은 천장이 있느냐다. 말로 풀 수 있는 명세 간극은 당신이 의도를 외부화하도록 다그쳐질 때마다 줄어들고, AI는 그렇게 다그치는 데 매우 능하다. 그러나 말로 풀 수 없는 종류, 곧 느껴지는 감각, 살아 낸 실패에서 쌓인 직감, 애초에 명제였던 적이 없는 지식. 그런 종류의 의도가 실재하고 지속한다면, 명세 간극이 영속하는 층이 있다. 기술이 아직 거기 닿지 못해서가 아니라, 근원과 목표가 구조적으로 통약 불가능해서다. 아니면 그 진단이 그저 계속 되풀이될 뿐이다. 천장이 저마다 바닥이 되면서.

나는 말로 풀 수 없는 종류가 실재한다고 생각한다. 특정한 몸으로 특정한 삶을 살아 냈다는 것의 구조적 특성으로서, 외부화에 저항하는 의도가 있다고 생각한다. 그러나 그것은 대다수가 바라는 것보다 좁다고 생각한다. 우리가 환원 불가능하게 인간적인 판단이라 부르는 것의 대부분은, 우리가 아직 명세하도록 다그쳐지지 않았을 뿐인, 말로 풀 수 있는 종류라고 나는 짐작한다.

천장은 실재할지 모른다. 그러나 그것은 여기서 보이는 것보다 낮다.

Link to slide