CodeAgents + 구조: 실행 동작을 수행하는 더 나은 방법
요약
AI 에이전트가 복잡한 작업을 수행하는 방식은 전통적인 JSON 도구 호출에서 실행 가능한 Python 코드를 직접 작성하는 CodeAgent로 진화했습니다. 여기에 한 단계 더 나아가, 사고 과정(thoughts)과 코드 실행을 명시적인 JSON 구조로 강제하여 생성함으로써, 코드의 유연성과 구조화된 출력의 신뢰성을 결합한 새로운 패러다임을 제시합니다. 이 '구조화된 CodeAgent' 접근법은 여러 벤치마크에서 기존 방식 대비 일관되고 높은 성능 향상을 보여주며, 특히 파싱 오류와 같은 구현상의 취약점을 근본적으로 해결합니다.
핵심 포인트
- AI 에이전트의 동작 표현 방식은 JSON 도구 호출 $\rightarrow$ 실행 가능한 코드(CodeAgent) $\rightarrow$ 구조화된 사고+코드(Structured CodeAgent) 순으로 진화하고 있다.
- 기존 JSON 도구 호출 방식은 기능 제한과 중간 상태 관리의 어려움이라는 한계를 가진다.
- CodeAgent는 임의의 Python 코드를 작성하여 무한한 유연성을 제공하며, 도구를 코드 내에서 직접 호출할 수 있어 신뢰성이 높다.
- 최종적으로 사고(thoughts)와 코드(code)를 JSON으로 구조화하는 것이 가장 이상적이며, 이는 파싱 오류 위험을 제거하고 계획과 실행의 명확한 분리를 가능하게 한다.
- 구조화된 CodeAgent는 여러 벤치마크에서 기존 CodeAgent 대비 평균 2-7% 포인트 이상의 성능 향상을 보여주었다.
CodeAgents가 구조화된 JSON 형식으로 사고와 코드를 생성할 경우, 여러 벤치마크에서 전통적인 접근법보다 현저히 성능이 향상될 수 있습니다.
[그림 1]: SmolBench (GAIA, MATH, SimpleQA, Frames) 에서 세 가지 접근법의 정확도 비교: Structured CodeAgent (파란색), CodeAgent (주황색), ToolCallingAgent (회색). 오차 막대는 95% 신뢰 구간을 나타냅니다.
AI 에이전트는 세계 내에서 동작을 수행해야 합니다 - API 호출, 데이터 처리, 복잡한 문제 해결 등을 통해. 에이전트가 이러한 동작을 표현하는 방식은 여러 패러다임으로 진화해 왔습니다:
전통적인 JSON 에이전트: 에이전트는 도구를 호출하기 위해 구조화된 JSON 을 생성합니다.
{"tool": "get_weather", "arguments": {"city": "Paris"}}
이러한 에이전트는 사전 정의된 도구 목록에서 선택하고 JSON 형식의 호출을 생성하는 방식으로 작동합니다. 이 도구 호출 방법은 OpenAI 의 function calling API 로 인해 대중화되었으며, 이후 가장 널리 사용되는 도구 호출 방법이 되었습니다.
이 방법은 신뢰할 수 있지만 다음과 같은 한계가 있습니다:
한정된 동작 집합: 에이전트가 수행할 수 있는 동작은 사전 정의된 도구만 통해 표현되므로 기능에 제한이 있습니다.조립성 부족: 작업이 여러 소스의 정보를 조립해야 하는 경우, JSON 에이전트는 도구 호출 간 중간 상태 유지 지원이 없어 어려움을 겪습니다. 일부 모델은 병렬 도구 호출을 지원하지만, 한 도구의 출력이 다음 동작을 결정하거나 결과를 함께 비교하고 처리해야 하는 시나리오를 쉽게 처리할 수 없습니다.강화된 구조: 도구가 정확히 필요한 작업과 일치하지 않는 경우 처리에 매우 제한적입니다.
코드 에이전트: 에이전트는 본래의 코딩 능력을 활용하여 실행 가능한 Python 코드를 직접 작성합니다.
# 1 모델 호출로 3 도시의 평균 온도를 얻을 수 있습니다.
temperature_sum = 0
for city in ["Paris", "Tokyo", "New York"]:
...
이 전환은 "Executable Code Actions Elicit Better LLM Agents" 논문에서 CodeAct 로 처음 제시되었으며, AI 에이전트에게 도구 호출 외에도 임의의 실행 가능한 Python 코드를 작성할 수 있는 유연성을 부여했습니다.
여기서 핵심 통찰은 도구가 코드 내에서 직접 호출된다는 점이며, 변수와 상태 관리가 훨씬 더 신뢰할 수 있게 됩니다. 에이전트는 루프, 함수, 조건문 내에서 도구를 호출할 수 있으며 - 각 동작에서 실행 도구 그래프를 생성하는 것과 동일합니다!
CodeAgent 를 사용하는 장점:
스마트 도구 사용: 에이전트는 현재 상황에 따라 사용할 도구를 결정합니다.무한한 유연성: 목표를 달성하기 위해 어떤 Python 기능도 사용할 수 있습니다.사고 테스트 능력: 에이전트는 가설을 세우고 테스트할 수 있어 동작에 더 많은 유연성을 제공합니다.
하지만 마크다운에서 코드를 파싱하는 것은 오류가 발생할 수 있어 다음과 같은 제안이 나왔습니다: 왜 구조화된 생성을 사용하여 코드 동작을 생성하지 않는 것이 좋을까요?
구조화된 출력 (Structured outputs) 을 사용하면 LLM 이 사고와 코드를 명시적인 JSON blob 로 생성하도록 강제할 수 있습니다:
{
"thoughts": "3 도시의 평균 온도를 찾고 싶습니다.",
...
핵심 차이는 생성이 강제된다는 점이며 - 이제 단순히 사고를 출력하라는 프롬프트가 아니라, 구조화된 출력을 사용하는 것이 구조를 존중하도록 강제합니다.
이 접근법은 구조화된 생성의 신뢰성과 코드 실행의 유연성을 결합하여 양쪽의 장점을 모두 얻습니다.
명시적 추론: thoughts
field 는 행동 직전에 에이전트가 추론하도록 강제합니다.신뢰할 수 있는 파싱: JSON 구조는 마크다운 파싱 오류를 제거합니다.완전한 코드 표현력: code field 는 코드 에이전트의 모든 유연성을 유지합니다.더 나은 분리: 계획과 실행의 명확한 분리
우리는 GAIA, MATH, SimpleQA, Frames 을 포함한 여러 벤치마크에서 이 세 가지 패러다임을 비교했습니다. 결과는 다음과 같은 명확한 패턴을 보여줍니다: 코드 동작 + 구조화된 생성은 능숙한 모델에 항상 성능 향상을 가져옵니다.
대부분의 능숙한 모델에서, 구조화된 접근법은 평균적으로 2-7% 포인트 이상으로 일반 CodeAgent 접근법을 상회했습니다.
OpenAI 모델: 구조가 가장 큰 개선 효과를 보이며, 특히 추론 중심의 작업에서 두드러집니다Claude 모델: 구조에 이점을 얻으며, Claude 3.7 Sonnet 은 특히 강력한 결과를 보입니다Qwen 모델: 일반적으로 구조로 성능이 향상되지만, 작은 모델에서는 "구조세 (structure tax)" (다음 섹션 참조) 가 나타납니다.
우리의 smolagents 에서 CodeAgent 구현은 LLM 출력에서 Python 코드를 추출하며, 이는 다음 경우에 실패할 수 있습니다:
- 마크다운 코드 블록 형식이 불완전하거나 잘못 포맷됨
- 단일 응답에 여러 코드 블록이 포함됨
구조화된 생성은 신뢰할 수 있는 JSON 파싱으로 이러한 문제를 해결합니다.
구조화된 생성이 왜 중요한지 이해하기 위해, 우리는 벤치마크를 통해 15,724 개의 에이전트 트레이스를 분석했습니다. 결과는 놀랍습니다:
**2.4%**의 트레이스 첫 호출에서 파싱 오류가 발생 - Traces with first call parsing errors: **42.3%**성공률 - Traces without first call parsing errors: **51.3%**성공률
파싱 오류가 없는 에이전트 트레이스는 파싱 오류가 있는 트레이스보다 21.3% 더 자주 성공합니다.
이것은 편의에 관한 것만이 아닙니다 - 파싱 오류는 실패의 연쇄를 만들어 전체 에이전트 성능에 중대한 영향을 미칩니다. 에이전트가 잘못 포맷된 코드로 인해 첫 번째 동작을 실행할 수 없을 때, 종종 회복하기 어려워지며 최적의 문제 해결 경로를 가져오지 못합니다.
Figure 2: 첫 단계에서 파싱 오류는 에이전트의 성공률을 21.3% 감소시키고 평균 수행 단계를 3.18 에서 4.63 으로 증가시킵니다.
또한: 강제된 추론 과정
구조화된 생성과 명시적 thoughts 는 단순히 프롬프트를 넘어, 행동 전에 에이전트가 추론 과정을 명백하게 표현하도록 강제합니다. 이는 다음과 같은 결과를 가져옵니다:
더 나은 계획: 에이전트가 문제를 더 체계적으로 사고합니다향상된 신뢰성: 명시적인 추론은 논리적 오류를 초기에 발견합니다
우리의 결과 또한 명확한 능력 임계치를 보여줍니다: 모델이 구조화된 생성에서 이점을 얻으려면 충분한 지시 수행 능력과 JSON 데이터의 사전 학습 데이터가 필요합니다. 이는 구조화된 접근법이 다음 모델과 가장 잘 작동함을 시사합니다:
- 대형, 잘 훈련된 모델
- 강력한 지시 수행 능력을 가진 모델
- 구조화된 생성에 맞게 미세 조정된 모델.
작은 모델 (예 mistralai/Mistral-7B-Instruct-v0.3 ) 이 구조화된 코드를 생성하려고 할 때, 인지 부하가 너무 커지는 것이 발생합니다:
{
"thought": "I need to find the height...",
"code": "web_search(query="Eiffel Tower height")",
...
모델은 문법적으로 깨진 Python 코드를 생성합니다: web_search(query="Eiffel Tower height"),
- 잘못된 문자열에 추가된 인용부호와 쉼표가 있습니다. 이는 즉시 SyntaxError 와 실행 실패를 초래합니다.
이것은 "구조세금"을 설명합니다: 작은 모델은 JSON 포맷팅, Python 문법 및 실제 문제 해결 논리를 동시에 처리하는 데 어려움을 겪습니다. 구조화된 생성의 인지적 과부하가 단순 markdown 기반 코드 생성과 함께 합리적으로 수행할 수 있는 모델을 압도할 수 있습니다.
✅ 구조화된 CodeAgents 를 사용할 때:
- capable models(32B+ 파라미터 또는 frontier models)과 작업하기
- 작업이 복잡한 추론 및 코드 실행을 필요로 함
- agent outputs 의 신뢰할 수 있는 파싱이 필요함
⚠️ 대안을 고려할 때:
- 구조화된 생성에 어려움을 겪는 작은 모델과 작업하기
- 단순한, 사전 정의된 워크플로우가 충분함
그것은 super simple 입니다! use_structured_outputs_internally: 를 활성화하여만들기:
from smolagents import CodeAgent, InferenceClientModel, GoogleSearchTool
# 구조화된 생성을 위한 agent 구성
agent = CodeAgent(
...
LLM 은 다음과 같은 것을 생성할 것입니다:
{
"thoughts": "I need to find the length of the Golden Gate Bridge and the top speed of a cheetah, then calculate the time.",
"code": "bridge_info = web_search('Golden Gate Bridge length meters')\ncheetah_speed = web_search('Cheetah top speed') ..."
...
그런 다음 "code" 부분은 agent 가 일반적으로 실행됩니다: 이것은 표준 CodeAgent 이지만, 이제 100% 파싱 신뢰성을 가지고 있습니다!
명확한 프롬프팅: 예상 JSON 구조를 명확하게 지정하도록 프롬프트를 명확하게 하세요
모델 선택: 강력한 구조화된 생성 능력을 가진 모델을 선택하세요
올바른 제공자 선택: OpenAI 나 Anthropic 과 같은 일부 API 제공자는 구조화된 생성을 기본적으로 지원합니다. Hugging Face 를 통해 Inference 제공자를 사용하는 경우, 구조화된 생성 지원은 제공자에 따라 다릅니다. 구조화된 생성 지원을 지원하는 모델 목록: Structured generation support for Models in smolagents‣
이 연구는 agent architecture 의 더 세밀한 이해로 나아가고 있음을 시사합니다. 그것은 "agent 가 무엇을 할 수 있는가"에 관한 것이 아니라, "agent 는 무엇을 하는가에 대해 어떻게 생각해야 하는가"에 관한 것입니다.
추론 과정을 더 명시적으로 만드는 것이 모델의 진행을 유지하는 데 도움이 될 수도 있습니다. 아니면 그냥 파싱하기 쉬울 수도 있습니다. 어느 쪽이든, 그것은 승입니다.
하지만 이것은 시작일 뿐입니다. 여전히 탐구할 많은 질문들이 있습니다:
- 다른 구조적 개선은 무엇을 도와줄 수 있는가?
- 우리는 어떻게 다른 모델 architecture 를 통해 이것을 더 잘 작동시킬 수 있는가? 특히 smol models 에 대해?
- 이것이 AI reasoning 의 본성에 대해 우리에게 무엇을 알려주나요?
현재, smolagents 를 사용하는 경우 (또는 자체 CodeAgent 시스템을 구축하는 경우), 구조화된 출력에 시도해 보십시오. 파싱 오류를 감사하게 할 것이고, 당신은 아마도 성능의 좋은 증가를 볼 수 있을 것입니다!
AI 자동 생성 콘텐츠
본 콘텐츠는 Hugging Face Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기