AgentCore로 구현하는 하네스 엔지니어링
요약
본 글은 LLM을 단순한 모델이 아닌 '힘이 센 말'에 비유하며, 모델 주변 환경을 설계하는 하네스 엔지니어링 개념을 설명합니다. 이는 프롬프트/컨텍스트 엔지니어링 다음 단계로, 루프, 툴, 메모리, 권한 등 모델 외 모든 메커니즘을 포함하여 에이전트의 안정적 작동을 보장하는 방법을 다룹니다.
핵심 포인트
- 하네스 엔지니어링은 LLM 주변 환경 설계 방식이다.
- 모델(LLM)만으로는 업무 처리가 불가능하며, 하네스가 필수적이다.
- 하네스는 루프, 툴, 메모리, 권한 등 모델 외 모든 요소를 포함한다.
- 이는 프롬프트/컨텍스트 엔지니어링 다음 단계의 발전된 개념이다.
AgentCore를 사용해 에이전트를 만들 때, 프롬프트를 열심히 작성해도 툴(tool)을 전달하는 방법이나 기억(memory)시키는 방법, 권한(permission), 로그 기록 방식 등은 '작동했으니까 그대로'로 남기기 쉽습니다.
이렇게 모델 주변 환경을 설계하는 사고방식을 최근 자주 듣는 것이 바로 **하네스 엔지니어링(Harness Engineering)**입니다.
이 글은 2026년 10월 6일 (토) 13:00~18:00에 개최된 'JAWS-UG 니가타 #34 AWS Step Functions 핸즈온'에서 발표한 내용을 바탕으로 합니다. AgentCore Harness를 사용하는 이야기는 아닙니다. Runtime, Gateway, Memory, S3 같은 AgentCore의 부품들로 하네스를 구성하는 방법을 구성도와 코드로 설명하겠습니다.
하네스는 본래 마구(馬具)를 뜻합니다. 힘이 센 말에게 고삐나 안장을 달아 원하는 방향으로 달리게 하는 도구입니다.
여기서 '힘이 센 말'이 LLM입니다. 말 자체는 강해도, 고삐가 없으면 생각한 방향으로는 달려주지 않습니다. 모델은 똑똑하지만, 그것만으로는 업무를 처리할 수 없다는 의미입니다.
LangChain은 이를 Agent = Model + Harness라는 공식으로 설명합니다.
"If you're not the model, you're the harness." (모델이 아니면 모두 하네스다.)
AWS도 AgentCore Harness의 GA(General Availability) 때 "If the model is the brain, the harness is the body" (모델이 뇌라면, 하네스는 몸이다)라고 적었습니다.
즉, 루프(loop), 툴(tool), 기억(memory), 실행 환경(execution environment), 권한(permission), 관측(observation) 등 모델을 제외한 모든 것을 통틀어 하네스라고 부릅니다.
하네스 엔지니어링은 프롬프트 엔지니어링, 컨텍스트 엔지니어링의 흐름 다음에 있습니다. Anthropic은 "컨텍스트 엔지니어링은 프롬프트 엔지니어링이 자연스럽게 발전한 다음 단계에 있다"고 언급했습니다.
세 가지는 중첩 관계입니다.
| 질문 | 확산된 시기 | 내용 |
|---|---|---|
| 프롬프트 엔지니어링 | 뭐라고 할까 | 2022년경부터 ~ |
| ... | ||
| 컨텍스트 엔지니어링까지는 '모델에게 무엇을 보여줄 것인가'에 대한 이야기였습니다. 하네스 엔지니어링은 보여주는 메커니즘 외에도, 권한으로 막거나 검증하여 다시 시도하게 하는 등 '보이지 않게 지키는' 메커니즘까지 포함합니다. |
하네스의 요소를 8가지로 나누면 각각 AgentCore와 Strands Agents의 부품이 대응됩니다.
| 요소 | 무엇을 결정하는가 | AgentCore / Strands의 부품 |
|---|---|---|
| 루프 | 추론과 툴 호출을 어떻게 순환시키고, 어디서 멈출지 | Strands Agents |
| ... | ||
| 덧붙여, 하네스 이야기에는 두 가지 맥락이 있습니다. Claude Code나 Codex 같은 코딩 에이전트를 사용하는 쪽의 하네스(AGENTS.md, lint, 테스트 등으로 리포지토리를 정리하는 이야기)와 LLM 앱을 제공하는 쪽의 하네스(실행 기반 이야기)입니다. 이 글은 후자를 다룹니다. |
8가지 중 루프를 순환시키고 멈추는 것에 한정하여 '루프 엔지니어링(Loop Engineering)'이라는 용어도 등장했습니다. IBM의 설명 정의는 다음과 같습니다.
"Loop engineering is the practice of designing agentic workflows, or loops, that iteratively guide AI agents toward completing user-defined goals with minimal human intervention." (사람의 개입을 최소화하면서, 사용자가 정의한 목표를 달성하도록 AI 에이전트를 반복적으로 안내하는 워크플로우, 즉 루프를 설계하는 실천.)
지시를 내리고, 결과를 확인하고, 안 되면 다시 시도하며, 어딘가에서 멈추는 과정. Claude Code가 파일을 읽고, 쓰고, 테스트하고, 오류를 보고 수정하는 것을 반복하는 것이 바로 이것입니다. 후반부의 GoalLoop이 이 부분의 부품이 됩니다.
그렇다고 8가지 전부를 쌓으면 완성인 것은 아닙니다.
"every component in a harness encodes an assumption about what the model can't do on its own"
(ハーネス의 부품들은 모두 '모델이 이것을 스스로 할 수 없다'는 가정 위에 서 있다.)
부품을 하나 추가할 때마다, 모델의 약점을 하나 가정하고 있는 셈입니다. 모델이 똑똑해지면 그 가정이 깨지고, 부품은 그저 무게추가 됩니다. 실제로 Anthropic도 모델이 새롭게 바뀐 시점에 하네스(harness)의 일부를 제거했다고 합니다.
이를 수치로 확인한 곳이 바로 전통총연구소(電通総研)의 테크 블로그입니다.
작은 은행의 코어 서비스(core service)를 소재로, 하네스의 부품을 6가지로 나누고 각각 '있음'과 '없음'으로 비교했습니다. 모델은 Opus와 Haiku 모두 사용되었습니다.
| 부품 | 결과 |
|---|---|
| 작업 상태를 state.json에 외출(外出し)하는 것 | 효과가 있었다 |
| ... | |
| 효과가 있었던 2가지 공통점은, 모델이 알 수 없는 정보를 외부에서 전달해 주는 부품이었다는 것입니다. 생각하는 역할을 대신하게 하는 부품들은, 모델이 스스로 할 수 있는 것을 반복했을 뿐이었습니다. |
따라서 이 글에서는 '모두 넣기'가 아니라, 어려운 부분에 필요한 부품을 추가해 나가는 방식을 취합니다.
AgentCore에는 에이전트를 구동하는 진입점(入口)이 2가지 있습니다.
| AgentCore Harness | Runtime + Strands |
|---|---|
| 시작 방법 | 설정만으로 작동 |
| ... | |
AgentCore Harness는 2026년 6월에 GA(General Availability)했습니다. 내용은 Strands Agents이며, Runtime 위에서 동작하는 관리형 루프입니다. agentcore export harness로 Strands의 코드로도 추출할 수 있습니다. |
위 공식 문서를 비교표를 보면, Runtime 측에서는 다음 항목들이 'Custom', 즉 직접 구현해야 하는 것으로 되어 있습니다.
- Memory(단기/장기), Gateway, Browser, Code Interpreter와의 연결
- 컨텍스트의 축소 방식, 실행 횟수의 상한
- 전송측의 Identity, Observability, lifecycle hooks
반대로 말하면, 이 표는 Harness가 내부적으로 수행하는 작업 목록입니다. 이 글에서는 이를 Runtime과 Strands로 하나씩 재구성해 나갈 것입니다.
최종적으로 구성되는 구조는 다음과 같습니다.
| 부품 | 이 구성에서의 역할 |
|---|---|
| Runtime | Strands로 작성된 에이전트를 세션별 microVM에서 구동하는 것 |
| ... | |
| 이 전체를 한 번에 만들지 않고, 4단계에 걸쳐 육성합니다. |
- Runtime · Identity · Observability의 최소 구성으로 작동시키기
- 트레이스(trace)를 보고 어디서 막히는지 파악하기
- 증상에 맞는 부품 추가하기
- 품질을 계속 평가하기
'부품이 많다고 효과가 있는 것은 아니다'라는 것을 그대로 절차로 만든 것입니다.
처음에 넣는 것은 3가지뿐입니다.
| 부품 | 역할 | 처음부터 넣는 이유 |
|---|---|
| Runtime | 에이전트를 구동하는 것 | 격리 단위는 나중에 바꾸기 어렵기 때문에 |
| ... |
이 3가지는 모델의 똑똑함과는 관계가 없습니다. 모델이 똑똑해져도 필요 없어지지 않으므로, 처음부터 넣어둡니다.
Runtime은 세션마다 전용 microVM이 생성됩니다. 사용자 A와 사용자 B의 세션은 각각 다른 microVM에서 작동하며, 종료 시에는 microVM과 메모리 전체가 파기됩니다.
세션 수명은 다음과 같습니다.
| 항목 | 값 |
|---|---|
| 유휴 시간 초과(기본값) | 15분 |
| ... | LifecycleConfiguration에서 60~28,800초(8시간) 범위로 설정 |
| 긴 처리 | |
/ping이 HealthyBusy를 반환하는 동안은 유휴 상태로 멈추지 않음 | |
| 명시적으로 중단 | StopRuntimeSession |
설계에서 중요한 것은, 세션이 끝나면 내용물이 사라진다는 전제하에 만드는 것입니다. 작업 중인 파일도, 대화 기록도 그대로 남아있지 않습니다. 남기고 싶은 데이터는 처음부터 외부에 두는 설계로 만듭니다. 어디에 둘지는 ③에서 설명하겠습니다.
2026년 9월에 GA한 Runtime(V2)은 스냅샷으로부터 복원하여 구동합니다. 공식 발표에 따르면, 콜드 스타트(cold start)의 P75가 1.92.0초로 V1의 5.430초에서 크게 단축되었습니다(내용물이 비어있는 에이전트로 측정한 값입니다.)
다만, 시작 시점에 생성된 값은 스냅샷에 기록되어 모든 인스턴스에서 동일하게 됩니다. 난수, ID, 토큰, 현재 시간, 인증 정보 등은 시작 시점이 아니라 요청을 처리하는 핸들러 내에서 생성해야 합니다. 호스트명과 PID 역시 모든 인스턴스에서 localhost와 1이 되므로 식별자로 사용할 수 없습니다.
8시간으로는 부족한 처리는 자신의 계정 EC2에서 구동하는 Runtime Instances를 이용할 수 있으며, 최대 14일까지 운영 가능합니다. 이 기능은 VPC가 필수입니다.
Identity에는 호출되는 쪽(inbound)과 호출하는 쪽(outbound) 두 가지 방향이 있습니다.
inbound 측에서는 에이전트를 호출할 수 있는 사람을 JWT (Cognito 등의 IdP가 발행한 것)나 IAM으로 제한합니다. outbound 측에서는 에이전트가 외부 API를 호출하기 위한 OAuth 토큰이나 API 키를 Identity에 보관합니다. 이렇게 하면 비밀 키를 코드나 환경 변수에 작성하지 않아도 됩니다. 하네스 요소에서 말하는 '경계'는 여기서부터 시작됩니다.
Observability를 활성화하면 OpenTelemetry의 트레이스가 CloudWatch에 수집되며, LLM 호출과 툴 호출이 순서대로 나열되어 보입니다.
이 트레이스는 ②에서 실패 지점을 찾는 자료가 되고, ④에서 품질을 평가하는 자료가 되기도 합니다. 같은 데이터를 두 번 사용할 수 있으므로 처음부터 넣어두는 것이 가장 이득입니다.
트레이스를 보면 어디서 막히는지 알 수 있습니다. 위 그림은 예시이지만, 예를 들어 다음과 같은 상황이 띠의 길이와 순서에서 드러납니다.
- 로그를 가져오는 툴이 38,000 토큰을 반환한다.
- 그 다음 LLM 호출이 지나치게 오래 생각하며 판단력이 흐려진다.
- 마지막에 승인 없이 삭제 툴을 호출하고 있다.
증상을 알면 효과적인 부품은 저절로 정해집니다.
| 트레이스에서 나타나는 증상 | 원인 | 효과적인 부품 |
|---|---|---|
| 긴 툴 결과 이후 판단력 저하 | 컨텍스트 과부하 | ContextOffloader로 S3에 퇴거 |
| ... | ||
| 여기서부터는 이 표의 오른쪽 열을 순서대로 조합해 나갑니다. |
추가할 것은 크게 세 가지입니다.
- 긴 결과나 중간 경과는 모델 외부(S3, Memory)로 빼낸다.
- 툴이나 자료를 전부 전달하지 않고 검색해서 선택하게 한다.
- 위험한 작업은 에이전트 외부에서 막는다.
우선 전제부터 말씀드립니다. Chroma 검증에서는 Claude든 GPT든 Gemini든 입력이 길어질수록 정확도가 떨어집니다. context rot (컨텍스트 열화)라고 불리는 현상이며, Anthropic의 기사에서도 인용되었습니다.
Anthropic은 컨텍스트를 '수확 체감하는 유한 자원'으로 다루어야 한다고 적었습니다. 긴 툴 결과를 그대로 대화에 쌓으면 그 이후 모든 추론이 그것을 계속 읽게 됩니다. 따라서 긴 것은 외부에 두고 필요한 부분만 읽게 하는 것이 기본 방침입니다.
보관 장소는 남기고 싶은 범위에 따라 세 단계로 나뉩니다.
긴 툴 결과는 Strands의 ContextOffloader라는 플러그인으로 빼낼 수 있습니다.
작동 방식은 다음과 같습니다.
- 툴이 결과를 반환하는 타이밍에 후크가 작동하여 토큰 수를 계산합니다.
- 기본 설정으로는 2,500 토큰을 초과하면 전체 내용을 외부 저장소(여기서는 S3)에 저장합니다.
- 대화에는 맨 앞의 미리보기와 저장된 위치의 참조만 남깁니다.
- 다음 내용이 필요할 때 에이전트가
retrieve_offloaded_content
툴로 필요한 부분만 가져옵니다.
구현은 Agent의 plugins에 하나 추가하기만 하면 됩니다.
from strands import Agent
from strands.storage import S3Storage
from strands.vended_plugins.context_offloader import ContextOffloader
...
저장소는 S3 외에도 strands.storage의 InMemoryStorage (메모리)나 LocalFileStorage (로컬 파일)를 선택할 수 있습니다. Runtime에서는 세션이 끝나면 로컬 파일도 사라지므로, S3를 선택하는 것이 자연스럽습니다.
참고로, S3 상의 키에는 offloader/
이 경우 자동으로 붙기 때문에, 이 예시에서는 offload/offloader/<toolUseId>_<연번> 형태로 저장됩니다. 또한 기본적으로 20 사이클이 지난 오래된 오프로드 내용은 삭제되므로 (evict_after_cycles=20), 계속 보존하고 싶은 결과물의 보관 장소로는 적합하지 않습니다.
오프로드되면 대화에는 다음과 같은 형태로 남게 됩니다.
[Offloaded: 1 blocks, ~38000 tokens]
(가져오는 방법 안내)
(맨 앞 미리보기)
...
retrieve_offloaded_content에는 대화에 남아있는 참조(reference)를 반드시 전달해야 합니다. 그 위에 pattern으로 정규표현식을, line_range로 줄의 범위를 지정할 수 있고, context_lines로 앞뒤 줄도 함께 가져올 수 있습니다. 참조만 전달하면 전체 내용을 반환합니다. 에이전트가 스스로 읽는 방식을 '오류를 포함한 줄만 읽기'처럼 선택할 수 있게 되는 것입니다.
import와 인수는 strands-agents 1.57.2의 소스에서 확인했습니다. 다만, S3Storage와 결합한 공식 샘플은 찾을 수 없었으며, 위의 코드는 사양으로부터 구성한 예시입니다.
다음은 작업 중인 파일에 대한 내용입니다. 에이전트에게 코드를 작성하게 하거나 파일을 가공하게 하면 작업 디렉터리가 필요합니다. 하지만 Runtime은 세션이 끝나면 microVM 별로 사라집니다.
session storage를 사용하면, 세션을 멈춰도 같은 세션 ID로 재개하면 파일이 돌아옵니다. 쓰기는 세션 중에 백그라운드에서 복제되어 있고, 중지할 때 남은 것을 기록하는 방식입니다.
설정은 Runtime의 filesystemConfigurations에 마운트할 경로를 지정하기만 하면 됩니다.
aws bedrock-agentcore-control update-agent-runtime \
--agent-runtime-id <runtime-id> \
--agent-runtime-artifact <기존과 동일한 설정> \
...
VPC도 추가 IAM도 필요 없습니다. Strands의 FileSessionManager의 storage_dir를 이 경로로 지정하면, 대화 기록도 함께 남길 수 있습니다.
| 항목 | 내용 |
|---|---|
| 상태 | 미리보기 (미리보기 중에는 무료) |
| ... | |
| 공식 문서에서는 파일의 상태는 session storage, 대화 기록이나 학습한 지식은 Memory로 구분하고 있습니다. |
다만, session storage는 세션 내부에 닫힌 보관 장소입니다. 에이전트끼리 자료를 주고받고 싶을 때는 S3 Files를 마운트합니다.
에이전트 A가 reports/에 작성하고, 에이전트 B가 그것을 읽는 형태입니다. S3 Files는 S3의 버킷과 양방향 동기화되므로, 다른 시스템에서는 일반적인 S3처럼 읽을 수 있습니다.
AWS Storage Blog에는 중간 결과를 프롬프트가 아닌 S3 Files 상의 파일로 주고받는 멀티 에이전트 구성 예시가 나와 있습니다. 블로그의 표현을 빌리자면
파일이 아니라, '이 사용자는 답변을 목록으로 원한다'와 같은 지식을 대화 전반에 걸쳐 기억시키고 싶을 때는 AgentCore Memory를 사용합니다.
Memory는 2단계로 구성되어 있습니다.
- 대화를 저장하면 먼저 단기 기억(raw event) 형태로 그대로 남습니다. 단위는 actorId와 sessionId이며, 보존 기간은 Memory를 만들 때 3일에서 365일 사이의 범위로 결정합니다 (
eventExpiryDuration). - 선택한 전략에 따라 백그라운드에서 비동기로 핵심 내용을 추출하여 장기 기억으로 저장합니다.
- 다음 대화 시에는 장기 기억을 검색하여 관련된 내용만 Context에 추가합니다.
장기 기억 전략은 4가지가 있습니다.
| 전략 | 저장하는 것 |
|---|---|
| SUMMARIZATION | 대화 요약 |
| ... | |
Strands에서는 AgentCore의 SDK에 있는 AgentCoreMemorySessionManager를 통해 연결합니다. |
from strands import Agent
from bedrock_agentcore.memory.integrations.strands.config import (
AgentCoreMemoryConfig,
...
namespace는 '누구의, 어떤 기억인가'를 구분하는 주소와 같으며, {actorId} 부분이 사용자별로 대체됩니다. 이 예시에서는 선호도를 /preferences/{actorId}/에서 상위 5개만, 관련도 0.7 이상인 것만 가져오고 있습니다.
참고로 AgentCore Harness의 Memory 연동은 호출할 때마다 장기 기억을 topK=10, relevanceScore=0.2로 가져와 추론 전에 Context에 추가하는 것으로 알려져 있습니다. RetrievalConfig의 기본값도 같은 10개/0.2이므로 아무것도 지정하지 않으면 Harness와 동일한 방식으로 작동합니다. 직접 구현할 경우, 얼마나 많이 가져올지 스스로 결정할 수 있다는 것이 장점입니다. 너무 많이 가져오면 Context가 다시 무거워지기 때문에, 이 부분은 조정할 여지가 있습니다.
지금까지의 저장 위치를 나열하면 다음과 같습니다.
| ContextOffloader (S3) | session storage | S3 Files | Memory | |
|---|---|---|---|---|
| 저장하는 것 | 긴 툴 결과 | 작업 중인 파일 | 공유 자료 | 선호도나 지식 |
| ... | ||||
| 누구와 공유하고 싶은지, 언제까지 남기고 싶은지에 따라 선택하면 혼란을 줄일 수 있습니다. |
Context를 가볍게 하는 생각은 툴에도 적용할 수 있습니다. 툴 설명 자체만으로 토큰을 소모하기 때문에, 수십 개를 나열하면 그것만으로도 Context가 무거워집니다.
그래서 처음부터 전부 전달하는 것이 아니라, 필요한 것을 에이전트가 검색하게 합니다. Gateway의 툴 검색, ContextOffloader의 부분 가져오기, Memory의 검색. 이 세 가지 모두 Anthropic이
forbid(
principal,
action == AgentCore::Action::"OpsTarget___delete_instance",
...
action의 이름은 "타겟명 + 언더스코어3개 + 툴명" 형태가 됩니다.
판단 규칙은 간단합니다.
| 상황 | 결과 |
|---|---|
| forbid가 1개라도 해당되면 | 거부 |
| ... | |
거부될 경우, 에이전트에게 오류 결과(isError: true) | |
| 가 반환되므로, 에이전트는 호출할 수 없었음을 알게 됩니다. |
바로 운영 환경에서 중단하는 것이 두려운 경우에는 LOG_ONLY
모드에서 "무엇이 중단되는지"를 로그로 확인한 후, ENFORCE
로 전환할 수 있습니다.
2026년 8월에 도입된 Temporal policies(시간적 정책)를 사용하면 세션 내에서 과거에 무엇을 했었는지를 조건으로 삼을 수 있습니다. 이는 Cedar와 호환되는 Dogwood라는 언어로 작성하며, 만들 때는 definition.policy.statement
에 넣습니다. 공식 문서 예시로는 직전 1시간 동안 같은 계좌의 잔액 조회 기록이 없으면 송금을 허용하지 않는 규칙입니다.
permit (
principal,
action == AgentCore::Action::"FundsTarget___transfer_funds",
...
연산자는 formerly within 외에도 since within, count, sum 등 여러 가지가 있어, "5분 이내 송금이 3회를 초과하면 중단한다"와 같은 횟수 조건도 작성할 수 있습니다. 이 횟수에는 현재 판정하고 있는 호출도 포함됩니다.
다만, 이력은 세션 단위입니다. 세션은 세션 ID와 사용자의 조합으로 결정되며, 소급 가능한 기간은 24시간까지입니다. 세션 ID가 바뀌면 다시 계산되기 때문에, 이것만으로는 확실하게 막을 수 있는 것은 아닙니다. 공식 문서에서도 횟수 조건은 보안 제어는 아니라고 주석하고 있습니다. JWT의 claim, IAM, 툴, 모델 등의 단위로 RPM이나 TPM을 제한하는 레이트 리미팅과 결합하는 것이 현실적이라고 생각합니다.
마지막 단계는 품질을 계속 측정하는 것입니다. 여기에는 "실행한 후에 측정하는 것"과 "실행 중에 확인하는 것"이 있습니다.
AgentCore Evaluations에는 세 가지 사용법이 있습니다.
| 사용법 | 모드 | 내용 |
|---|---|---|
| CI의 품질 게이트 | on-demand | 정답(ground truth)을 붙여 채점함 |
| ... | ||
| CI에 대해서는 AWS 블로그에 GitHub Actions를 사용한 구성 예시가 있습니다. |
운영 환경에서는 online 모드로 추출하여 채점하고, 결과는 CloudWatch의 메트릭(네임스페이스는 Bedrock-AgentCore/Evaluations)
에 나오므로, 점수가 떨어지면 알람을 울릴 수 있습니다. 둘 다 ①에서 넣은 Observability의 트레이스가 재료가 됩니다.
Evaluations는 실행한 후의 평가입니다. 실행 중에 확인하여 그 자리에서 수정하고 싶을 때는 Strands의 GoalLoop를 사용합니다.
에이전트가 응답할 때마다 검증역이 합격/불합격을 내립니다. 합격이면 그대로 반환하고, 불합격이면 무엇이 잘못되었는지 피드백을 다음 지시로 삼아 다시 시킵니다. 이는 루프 엔지니어링의 "결과를 확인하고, 안 되면 재실행하는" 부분입니다.
from strands import Agent
from strands.vended_plugins.goal import GoalLoop
def word_count_validator(response, agent):
...
검증역 함수는 에이전트의 마지막 응답과 에이전트 자신을 받습니다. 합격이면 True,
불합격이면 passed와 feedback을 가진 딕셔너리를 반환합니다. 위의 함수는 Strands의 docstring에 있는 예시 그대로입니다. goal에는 이런 함수의 외에도, 자연어 조건을 전달하면 다른 모델이 판정해 줍니다.
여기서 중요한 주의사항이 하나 있습니다. GoalLoop는 기본적으로 횟수와 시간 모두 무제한입니다(둘 다 float("inf"))
)。두 가지를 모두 생략하면 경고는 나오지만, 그대로 통과할 때까지 계속 순환합니다. max_attempts
그리고 timeout은 반드시 정해 두어야 합니다.
또 하나, Strands의 steering이라는 메커니즘도 있습니다. 이것은 툴을 호출하기 전에 개입할 수 있습니다.
from strands import Agent
from strands.vended_plugins.steering import Guide, Proceed, SteeringHandler
class OpsSteering(SteeringHandler):
...
steering 역시 ContextOffloader나 GoalLoop와 같은 플러그인이므로, plugins에 전달하여 통합합니다.
| 반환 값 | 발생하는 일 |
|---|---|
| Proceed | 그대로 호출 |
| ... | |
| Guide를 반환하면 툴 호출이 취소되고, 에이전트에게는 |
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기