Logo Ernie.SG
Fork Work: 자율 에이전트가 있는데 왜 일하지?

Fork Work: 자율 에이전트가 있는데 왜 일하지?

2023년 8월 11일
5분 읽기
사용 가능한 태그가 없습니다
Table of Contents

좌절해서 키보드를 두드리거나 물려받은 코드베이스 앞에서 눈물을 조금 흘리는 대신, 그 정보를 A.I.에 넘기고 대화하는 편이 훨씬 말이 된다. LLM의 지식과 추론 능력을 그런 정보 위에서 활용하기 시작하는 순간, 자연스러운 다음 단계는 종합이다. 기존 코드베이스 위에서 실행될 수 있는 새 코드를 생성해, 전 세계 누구나 프롬프트에서 기능까지 갈 수 있게 하는 것이다. 이런 과제를 다루기 위해 아래 데모를 만들었고, 주말 하루 이틀 정도 작업한 결과물이다. 만드는 과정에서 새로 배운 것도 많고 여러 개념을 더 깊이 이해하게 되어 꽤 재미있었다.

Arthur - 무엇이든 검색하고 가져오기

왜 일하지 Leh?

내가 하려던 일은 내 데이터 공장에 관한 정보를 Deep Lake 벡터 저장소에 넣고, 맞춤형 지식 저장소 위에서 ChatGPT의 추론 능력을 활용해 기존 설정에서 무슨 일이 벌어지는지 이해하는 것이었다. 인간이 남긴 레거시 코드베이스를 이해하려 애쓰는 것보다 훨씬 즐거웠다. 소통과 회의가 엄청난 시간 낭비였던 순간이 충분히 많았고, 답변을 기다리는 지연, 질문에 대한 인간의 느린 반응은 정말 할 말이 없다… 그래서 이렇게 시작했다. 첫 벽돌을 놓고 나면, 자율 에이전트의 공장을 만들 수 있다. 그 에이전트는 온갖 정보를 조사하고, 검색하고, 추론하며, 소셜 미디어 콘텐츠든 코드든 새로운 가치 있는 출력을 종합하고 생성할 수 있다. 내게 이것이 바로 A.I.의 노동시장 함의가 사회 전체의 진지한 대화를 필요로 하는 이유다.

부분적인 A.I. 지능조차 초인적 지능이 되고, 우리가 생산성을 1000배 높일 수 있다면, 즉 어쩌면 나눌 일이 충분하지 않을 수도 있다면 우리는 무엇을 해야 할까? 한 걸음 물러서서 보면, 애초에 왜 인간이 그렇게 많이 일하기를 원하는 걸까? 아마 정말 필요한 일은 일, 소득, 의미 사이의 화살표를 다시 구성하고 다시 그리는 것일지도 모른다. 나는 기꺼이 주 4시간 근무에 투표하고 나머지 시간은 놀고 배우는 데 쓰겠다, 그냥 하는 말이다.

마주친 과제들

에이전트를 만들면서 가장 많이 막혔던 어려운 지점은 다음과 같았다:

  1. 올바른 패키지 버전 사용하기

시작하기 위해 기존 프로젝트(chat-with-code)에서 배우기로 했지만, 아래와 같은 오류를 계속 만났다:

RuntimeError: no validator found for <class 're.Pattern'>, see `arbitrary_types_allowed` in Config
Traceback:
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/streamlit/scriptrunner/script_runner.py", line 557, in _run_script
    exec(code, module.__dict__)
File "chatbot.py", line 2, in <module>
    import utils
File "/home/erniesg/code/erniesg/chat-with-code/utils.py", line 1, in <module>
    from langchain.document_loaders import TextLoader
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/__init__.py", line 6, in <module>
    from langchain.agents import MRKLChain, ReActChain, SelfAskWithSearchChain
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/__init__.py", line 40, in <module>
    from langchain.agents.agent_toolkits import (
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/agent_toolkits/__init__.py", line 12, in <module>
    from langchain.agents.agent_toolkits.csv.base import create_csv_agent
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/agent_toolkits/csv/base.py", line 4, in <module>
    from langchain.agents.agent_toolkits.pandas.base import create_pandas_dataframe_agent
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/agent_toolkits/pandas/base.py", line 18, in <module>
    from langchain.agents.types import AgentType
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/types.py", line 5, in <module>
    from langchain.agents.chat.base import ChatAgent
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/chat/base.py", line 6, in <module>
    from langchain.agents.chat.output_parser import ChatOutputParser
File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/chat/output_parser.py", line 12, in <module>
    class ChatOutputParser(AgentOutputParser):
File "pydantic/main.py", line 229, in pydantic.main.ModelMetaclass.__new__
File "pydantic/fields.py", line 491, in pydantic.fields.ModelField.infer
File "pydantic/fields.py", line 421, in pydantic.fields.ModelField.__init__
File "pydantic/fields.py", line 542, in pydantic.fields.ModelField.prepare
File "pydantic/fields.py", line 804, in pydantic.fields.ModelField.populate_validators
File "pydantic/validators.py", line 723, in find_validators

또는 이런 식이었다:

➜  chat-with-code git:(main) ✗ poetry run streamlit run chatbot.py                                         [🐍 lewagon]
2023-08-04 19:39:49.759 INFO    numexpr.utils: Note: NumExpr detected 12 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
2023-08-04 19:39:49.760 INFO    numexpr.utils: NumExpr defaulting to 8 threads.
 
  You can now view your Streamlit app in your browser.
 
  Network URL: http://172.19.237.74:8501
  External URL: http://180.129.59.54:8501
 
2023-08-04 19:39:51.484 Uncaught app exception
Traceback (most recent call last):
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/streamlit/scriptrunner/script_runner.py", line 557, in _run_script
    exec(code, module.__dict__)
  File "/home/erniesg/code/erniesg/chat-with-code/chatbot.py", line 2, in <module>
    import utils
  File "/home/erniesg/code/erniesg/chat-with-code/utils.py", line 1, in <module>
    from langchain.document_loaders import TextLoader
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/__init__.py", line 6, in <module>
    from langchain.agents import MRKLChain, ReActChain, SelfAskWithSearchChain
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/__init__.py", line 31, in <module>
    from langchain.agents.agent import (
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/agent.py", line 15, in <module>
    from langchain.agents.agent_iterator import AgentExecutorIterator
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/agents/agent_iterator.py", line 21, in <module>
    from langchain.callbacks.manager import (
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/callbacks/__init__.py", line 10, in <module>
    from langchain.callbacks.aim_callback import AimCallbackHandler
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/callbacks/aim_callback.py", line 5, in <module>
    from langchain.schema import AgentAction, AgentFinish, LLMResult
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/schema/__init__.py", line 4, in <module>
    from langchain.schema.memory import BaseChatMessageHistory, BaseMemory
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/schema/memory.py", line 7, in <module>
    from langchain.schema.messages import AIMessage, BaseMessage, HumanMessage
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/langchain/schema/messages.py", line 147, in <module>
    class HumanMessageChunk(HumanMessage, BaseMessageChunk):
  File "/home/erniesg/.pyenv/versions/3.10.6/envs/lewagon/lib/python3.10/site-packages/pydantic/main.py", line 352, in __new__

해결: 알고 보니 특정한 streamlit (1.25.0)pydanic version (1.10.12)를 써야 했다. 여러 패키지 사이의 호환성 문제가 꽤 자주 반복되니, 이를 관리하는 도구와 모범 사례를 더 배워야 할 것 같다. 어쩌면 사용한 구체 버전은 항상 poetry 안에 정의되어야 하는 것 아닐까!?

  1. .json 파일로 정의된 Azure Data Factory 리소스를 수집하고 분할하는 방법 알아내기

문서, .pdf, GitHub 코드 저장소 등을 처리하는 튜토리얼은 많지만 .json 이야기는 거의 없었다. ChatGPT에게 생성해달라고 해도 소용이 없어서, 결국 .jsonlangchain JSON loader를 자세히 들여다보고 내가 생각하는 방식대로 단계별로 ChatGPT를 안내했더니 마침내 작동했다. 적어도 Google과 YouTube 검색 첫 페이지 기준으로는 Azure Resource Manager(ARM) 템플릿에 대해 이 작업을 한 사람이 없었으니, 조금은 새로움을 만들어야 했다.

해결: 이 초기 프로토타입에서는 Azure Data Factory의 parameters, variables, resourcesresources 안의 개별 객체를 보존하고 싶었다. 그것들이 내 파이프라인과 액티비티 등이 될 것이기 때문이다. 여기에 few-shot 지시와 맥락을 결합하자 ChatGPT가 필요한 결과를 만들어냈다.

앞으로의 방향

그렇게 해서 75개 항목을 Deep Lake 데이터셋으로 나누어 넣게 됐다. 이제는 더 많은 데이터 소스를 연결해야겠다고 생각하고 있다. 모든 SQL 스키마, 저장 프로시저, 데이터 그 자체까지 질의할 수 있게 하고, 메모리와 관련된 메타데이터를 업데이트하고, 멀티모달 데이터 레이크 겸 벡터 저장소 위에서 CRUD 작업을 수행하고, 검색 전략과 토큰 컨텍스트를 최적화하는 일까지 말이다. 사실 도구를 써서 LLM 안에서 바로 실행하고 행동하게 하면 안 될 이유가 있을까? 더 나아가 LLM이 스스로 테스트를 쓰고, 디버그하고, 검증하게 만들면 어떨까? 이런 것들은 어느 규모의 팀이나 조직이든 보수적으로 말해 생산성을 1000배 끌어올릴 자율 에이전트를 프로덕션에 올리는 데 반드시 필요하다.

즐겁네! 🤩🤩🤩


원래 PubPub의 erniesg.pubpub.org/pub/i8a0vp8z에 게시됨.