회사 메일로, 우리 org에 대한 Github Copilot Chat(beta) 기능이 활성화됐다. 아마 올해 초 ChatGPT가 나올 때 쯤 beta feature 대기 명단에 신청한걸로 기억하는데, 드디어 됐다(Required Worfklow도 private beta가 되기 전에 신청했어야 하는데…).
•
현재도 개인 waitlist 신청 가능하고 이거 역시 했으나 활성화되지 않았다.
기존에 VSCode에서 Copilot 확장을 org에 속한 github 계정으로 이미 쓰고 있다면 별 다른 설정 없이 새로운 chat 기능을 사용할 수 있다.
사용법(VSCode)
VSCode 명령 팔레트에서 “github copilot”으로 검색하면 처음보는, 여러 명령이 나온다. 사실 그 전에도 탭으로 자동완성만 쓰긴 했지만(intelli sense에게 경례!🫡) 아마 단축키가 설정되지 않은 모든 명령은 그렇지 않은가 싶다.
Fix This
일부러 YAML(k8s manifest 중 Karpenter provisioner로 했다)의 indent를 틀리게 하고 이 명령을 사용해봤다(manifest는 회사 자산이라 코드 전체를 공개하지 못한다).
코드를 블록하거나 고치고 싶은 곳에 커서를 올리고 실행하면 둘 다 작동한다. 수정할 라인이나 블록 아래로 patch(diff)가 뜨고 fix 뒤에 수정한 이유나 내용이 나오는 것 같다.
우선 수정한 diff 자체는 틀렸다. operator 키를 바깥으로 빼어야 하는데 키가 속한 항목(item) 전부를 operator 와 같은 수준으로 한단계 들여 썼다. formater/linter가 표시하는 빨간 줄 안보이니?(아직은 이것까지 인식 못하는 듯 하다) .
하지만 예시가 적절치 않았다는 생각도 든다.
•
수정하라는 내용 자체의 수준이 낮다.
◦
방금 말한 것처럼 이건 기존 formatter/linter가 할 수 있는 일이지 않는가.
▪
그럼 copilot은 어떤걸 수정할 수 있을까? stackoverflow에 자주 틀리는 패턴? 비즈니스 로직에 대한 타당성 검토?
•
코드라기 보단 구성(configuration)에 해당하는 YAML manifest이다.
◦
하지만 개발자(사용자)가 이걸 의식하고 구분할 필요는 없다고 생각한다.
◦
참고로 copilot의 기본 설정은 .yaml|.yml 파일에 대해선 동작하지 않게 되어 있다. 내가 풀어 놓고 쓰는 것이다.
그리고 답변이라고 볼 수 있는 수정한 이유 작성은 적절하다. 문제 파악은 꽤 잘한다고 볼 수 있겠다. 나아가 나는 이걸 커밋 메세지로 활용하면 자동화된 워크플로로 커밋 작성 시간을 많이 줄일 수 있다고 생각 든다 .
Explain This
위 manifest 전체에 대해서 explain this 명령을 실행했다(explain). 그러면 왼쪽에 copilot과의 채팅창이 뜬다.
이번에도 YAML manifest를 올릴 순 없지만, copilot의 설명을 일부 데이터 redacted 하여 올린다(이것이 리버스 엔지니어링?). 일반적인 Karpenter Provisioner에 대한 설명이다.
This is a YAML file that defines a Kubernetes custom resource of kind Provisioner with the name xxx. The spec section of the resource defines the desired state of the provisioner.
The providerRef field specifies the name of the provider that this provisioner should use. In this case, it references a provider named xxx.
The taints field specifies a taint that should be applied to nodes that this provisioner creates. The taint has an effect of NoSchedule, which means that no pods will be scheduled on nodes with this taint. The key of the taint is xxx and the value is xxx.
The labels field specifies labels that should be applied to nodes that this provisioner creates. The label key is xxx and the value is xxx.
The requirements field specifies a list of requirements that nodes created by this provisioner must satisfy. The first requirement specifies that the karpenter.k8s.aws/instance-family label must be set to one of the values in the list xxx. The second requirement specifies that the karpenter.sh/capacity-type label must be set to the value xxx. The third and fourth requirements specify that the kubernetes.io/os and kubernetes.io/arch labels must be set to xxx and xxx, respectively.
The limits field specifies the resource limits that should be applied to nodes created by this provisioner. In this case, the limits are set to cpu: "xxx" and memory: xxxGi.
Finally, the consolidation field specifies whether node consolidation should be enabled for nodes created by this provisioner. In this case, it is set to true.
Possible ways to improve the code with respect to readability and performance include adding comments to explain the purpose of each field, grouping related fields together, and using consistent indentation. Additionally, it may be helpful to split the file into multiple smaller files to make it easier to manage.
뻔하다고도 할 수 있고 정석 같은 (자격증 따려고 외운 듯한?) 답변을 준다(아마 Karpenter에 대한 학습 데이터나 사례가 좀 적었을거란 예상도 된다). 이런 점에선 새로 배우려는 언어의 코드를 이해할 때 도움이 될 거 같다
채팅을 이어가기 위해? copilot이 질문을 추천해준다. 아래 파란색으로 보이는, 내가 할 질문을 누루면 copilot이 답한다(자문자답). 따라서 위의 질문도 내가 한게 아니라 추천 질문을 누른 것 뿐이다.
아주 잘 대답했을 뻔하다가 마지막에 가서 틀렸다. 적어도 현재 latest(v0.30) Karpenter의 karpenter.sh/capacity-type 엔 mixed 란 값이 없다. 개발자가 인터넷 또는 문서에서 한번 더 검증을 해야한다면, 답변으로써 신뢰도가 크게 떨어진다.
하지만 또 좋은 기능이라 생각하는 점은 채팅을 통해 학습할거리를 던져 준다는 것이다. 따라서 처음 보는 라이브러리 코드나 내가 커밋은 자주 하지 않지만 파악해야 하는 동료 코드의 PR 리뷰 시 좋을거 같다 .
Generate Tests
이름만 보면 꿈의 기능이지 않는가 싶으면서 과연? 이란 생각도 든다. 난 다음 코드에 대해 실행해봤다.
@app.command()
# declare typer option for node's label
# e.g. -l node-role.kubernetes.io/master=1
def list_pods_in_labeled_nodes(
label: str = typer.Option(
None,
"-l",
"--label",
)
):
config.load_kube_config()
v1 = client.CoreV1Api()
if label is None:
nodes = [node for node in v1.list_node().items]
else:
nodes = [node for node in v1.list_node(label_selector=label).items]
for node in nodes:
pods = [
pod
for pod in v1.list_pod_for_all_namespaces(field_selector=f"spec.nodeName={node.metadata.name}").items
if pod.metadata.owner_references[0].kind in ["ReplicaSet", "StatefulSet"]
]
typer.secho(f"{node.metadata.name}:", fg=typer.colors.CYAN)
for pod in pods:
# if pod is terminating print in purple else print in green
if pod.metadata.deletion_timestamp is not None:
pod_color = typer.colors.MAGENTA
else:
pod_color = typer.colors.GREEN
typer.secho(
f" {pod.metadata.namespace}/{pod.metadata.name}",
fg=pod_color,
)
Python
복사
이것도 회사에서 쓴 코드지만 자산 정보가 있지 않고 일반적인 내용이라 공개해도 될거 같다. Typer라는 python cli 프레임워크의 메소드로써, 이 메소드(=명령)를 실행하면 쿠버네티스 노드를 레이블 순서대로 groupby 후 스케쥴 된 파드 수를 세어준다.
예를 들어 레이블 우선순위를 다음과 같이 하면:
아래처럼 나온다:
•
provisioner 이름과 노드 이름 일부는 redacted
•
Karpenter 전환 시 AZ와 노드 타입별 최대 파드 개수를 파악하고 싶어 만들었다.
그런데 위 코드를 테스트 하려니 k8s api mocking 서버가 있어야 할 거 같았고, 대충 알아보다가 (여느 테스트가 그렇듯…) 안하게 됐다. 또 파이썬을 업무할 때 주력 언어로 쓰지 않는다는 점도 한몫했다.
서론이 길었는데 아무튼… 위 코드를 copilot에게 테스트를 만들어 달라고 했다
tests 명령 뒤에(지금보니 프롬프트 타입 정도로 볼 수 있겠다), 내가 원하는 컨텍스트, kube api mock 서버가 필요할거 같다고 전달해주었다. 또 이 함수가 Typer의 @app.command 데코레이터를 달고 있다는 점도.
일단 복붙해서 쓸 수 있는 코드를 바로 주며, 내가 원한 api mock 서버를 찾아준 점이 좋았다 . 물론 저 코드가 동작하는진 실제로 실행해봐야 한다.
하지만 ApiMock.register_url 를 보면 바로 사용할 수 있는 더미데이터를 gen 해주진 않았다. 이 부분은 계속 프롬프팅 할 수 있게 채팅이 이어진다. 또한 explain과 마찬가지로 따름 질문을 추천해준다.
정리
Github Copilot Chat을 VSCode에서 사용해본 경험을 간단히 정리해본다.
•
사용법은 아주 간단한다. 신청했고 Github 계정과 연동만 잘 되어 있으면 된다.
•
fix
◦
Copilot이 말하는 수정에 대한 이유를 커밋 메세지로 활용하면 자동화된 워크플로를 통해 커밋 작성 시간을 많이 줄일 수 있을거 같다.
◦
간단한 linter 문제를 틀려서 아쉽다. VSCode formatter/linter/compiler 등 이미 체크 가능한 부분/확장들과 연동이 되면 좋을거 같다.
◦
틀린 정보를 알려줘서 아쉽다(검색을 또 해야한다).
•
explain
◦
새로 배우려는 언어의 코드나 오픈 라이브러리 코드를 큰 맥락에서 이해할 때 도움이 될 거 같다
▪
동료 코드의 PR 리뷰 시에도 마찬가지다. 리뷰어가 한명 더 생긴거 아닌가?
◦
좀 뻔한 부분(e.g. 언어 문법 같은 부분)만 답변을 준다.
▪
프롬프팅에 따라 달라질지 모르겠다(e.g 채팅으로 컨텍스트를 더 전달하면)
▪
많이 쓰이고 학습 사례가 많은 도메인, 언어, 프레임워크 등에 답변 품질이 따라 다를 거 같다.
◦
객관적인 정보에 대한 할루시네이션(hallucination)이 있다.
▪
틀린 답변을 하면 인터넷 검색 또는 문서를 찾아 검증 과정이 또 필요하거나,
▪
혼내게 된다 -_-
•
tests
◦
복붙해서 쓸 수 있는 코드를 바로 준다
◦
프롬프트로 넣어준, 내가 모르는 부분에 대한 코드 작성이 꽤 만족스럽다
•
사실 위 모든 기능의 품질은 어느 정도 개발자(=프롬프터)의 질문 역량에 따라서 달라질 수 있을 것이다.
◦
“많이 쓰이고 학습 사례가 많은 도메인, 언어, 프레임워크 등에 답변 품질이 따라 다를 거 같다.”
•
결과적으로, 처음 Copilot이 (Super)TAB 단축키를 훔쳐갔듯, 난 alt + c + e 를 Copilot Chat에게 주었다