Scalekit with LiteLLM
Scalekit with LiteLLM
인증된 도구 호출을 LiteLLM 기반 에이전트에 추가해 보세요. Scalekit은 100개 이상의 타사 앱(Gmail, GitHub, Slack, Salesforce 등)에 대해 OAuth 흐름, 토큰 저장, API 실행을 관리합니다. 여러분의 에이전트는 런타임에 도구를 선택하고 LiteLLM이 모델 호출을 어떤 제공자로든 라우팅해요.
개요
- Scalekit에서 사용자 범위(user-scoped) 도구 정의를 가져와
litellm.completion()에 함수 스키마로 전달 - 같은 도구 정의가 OpenAI, Anthropic, Bedrock, Vertex AI 등 LiteLLM이 지원하는 모든 제공자에서 동작하므로 모델을 자유롭게 전환
- 타사 앱마다 API 키, 엔드포인트, 인증 헤더를 관리할 필요 없이 Scalekit을 통해 도구 호출 실행
전제 조건
- Python 3.10+
- 연결(connection)이 구성된 Scalekit 계정(이 튜토리얼은 Gmail 사용)
- 최소 하나의 LLM 제공자 API 키, 또는 실행 중인 LiteLLM proxy
- Dashboard → Developers → API Credentials의 Scalekit API 자격 증명(
SCALEKIT_CLIENT_ID,SCALEKIT_CLIENT_SECRET,SCALEKIT_ENV_URL)
1. 의존성 설치
pip install litellm scalekit-sdk-python
2. 클라이언트 초기화
setup.py
import osimport jsonimport litellmimport scalekit.clientfrom google.protobuf.json_format import MessageToDict # installed with scalekit-sdk-pythonscalekit_client = scalekit.client.ScalekitClient(
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
env_url=os.getenv("SCALEKIT_ENV_URL"),
)actions = scalekit_client.actions
3. 사용자 인증
연결된 계정을 만들고 OAuth 흐름을 완료하세요. 계정 상태가 ACTIVE가 되면 Scalekit은 사용자를 대신해 도구를 실행할 수 있어요.
authorize.py
connection_name = os.getenv("GMAIL_CONNECTION_NAME", "gmail")response = actions.get_or_create_connected_account(
connection_name=connection_name,
identifier="user_123", # your app's user ID)connected_account = response.connected_accountif connected_account.status != "ACTIVE":
link = actions.get_authorization_link(
connection_name=connection_name,
identifier="user_123",
)
print("Authorize Gmail:", link.link)
input("Press Enter after completing authorization...")
4. 범위 지정 도구 가져오기
list_scoped_tools는 이 특정 사용자가 호출하도록 인증된 도구만 반환합니다. 이를 LiteLLM이 모든 제공자에 걸쳐 정규화하는 OpenAI 함수 호출 형식으로 변환하세요.
fetch_tools.py
scoped_response, _ = actions.tools.list_scoped_tools(
identifier="user_123",
filter={"connection_names": [connection_name]},
page_size=100,)# Convert to OpenAI function-calling format (used by litellm for all providers)llm_tools = [
{
"type": "function",
"function": {
"name": MessageToDict(t.tool).get("definition", {}).get("name"),
"description": MessageToDict(t.tool).get("definition", {}).get("description", ""),
"parameters": MessageToDict(t.tool).get("definition", {}).get("input_schema", {}),
},
}
for t in scoped_response.tools]
5. 에이전트 루프 실행
도구 정의와 함께 litellm.completion()을 호출하세요. 모델이 도구 호출을 반환하면 Scalekit을 통해 실행하고 결과를 다시 넣어 주세요. model 파라미터를 변경해 제공자를 전환하면 되며, 다른 코드 변경은 필요 없어요.
agent_loop.py
messages = [{"role": "user", "content": "Fetch my last 5 unread emails and summarize them"}]while True:
response = litellm.completion(
model="anthropic/claude-sonnet-5", # swap to any litellm-supported model
tools=llm_tools,
messages=messages,
)
message = response.choices[0].message
if not message.tool_calls:
print(message.content)
break
# Append assistant message with tool calls
messages.append(message)
# Execute each tool call through Scalekit
for tc in message.tool_calls:
result = actions.execute_tool(
tool_name=tc.function.name,
identifier="user_123",
tool_input=json.loads(tc.function.arguments),
)
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": str(result.data),
})
6. 완전한 동작 예시
복사해서 실행할 수 있는 완전한 엔드투엔드 스크립트:
scalekit_agent.py
import osimport jsonimport litellmimport scalekit.clientfrom google.protobuf.json_format import MessageToDict# --- Configuration ---MODEL = os.getenv("MODEL", "anthropic/claude-sonnet-5")CONNECTION_NAME = os.getenv("GMAIL_CONNECTION_NAME", "gmail")USER_ID = "user_123"# --- Initialize ---scalekit_client = scalekit.client.ScalekitClient(
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
env_url=os.getenv("SCALEKIT_ENV_URL"),
)actions = scalekit_client.actions# --- Authorize user ---response = actions.get_or_create_connected_account(
connection_name=CONNECTION_NAME,
identifier=USER_ID,)if response.connected_account.status != "ACTIVE":
link = actions.get_authorization_link(
connection_name=CONNECTION_NAME,
identifier=USER_ID,
)
print("Authorize Gmail:", link.link)
input("Press Enter after completing authorization...")# --- Fetch tools ---scoped_response, _ = actions.tools.list_scoped_tools(
identifier=USER_ID,
filter={"connection_names": [CONNECTION_NAME]},
page_size=100,)llm_tools = [
{
"type": "function",
"function": {
"name": MessageToDict(t.tool).get("definition", {}).get("name"),
"description": MessageToDict(t.tool).get("definition", {}).get("description", ""),
"parameters": MessageToDict(t.tool).get("definition", {}).get("input_schema", {}),
},
}
for t in scoped_response.tools]print(f"Loaded {len(llm_tools)} tools for {CONNECTION_NAME}")# --- Agent loop ---messages = [{"role": "user", "content": "Fetch my last 5 unread emails and summarize them"}]while True:
response = litellm.completion(model=MODEL, tools=llm_tools, messages=messages)
message = response.choices[0].message
if not message.tool_calls:
print(message.content)
break
messages.append(message)
for tc in message.tool_calls:
print(f" Calling tool: {tc.function.name}")
result = actions.execute_tool(
tool_name=tc.function.name,
identifier=USER_ID,
tool_input=json.loads(tc.function.arguments),
)
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": str(result.data),
})
MODEL 환경 변수를 변경해 모델을 전환하세요:
# OpenAIMODEL=gpt-5.6-terra python scalekit_agent.py# AnthropicMODEL=anthropic/claude-sonnet-5 python scalekit_agent.py# AWS BedrockMODEL=bedrock/us.anthropic.claude-sonnet-5 python scalekit_agent.py# Via LiteLLM ProxyOPENAI_API_BASE=http://localhost:4000 OPENAI_API_KEY=sk- MODEL=claude-sonnet-5 python scalekit_agent.py
비용 추적과 Rate Limit을 위한 LiteLLM Proxy 라우팅
LiteLLM proxy를 실행 중이라면 중앙 집중식 모델 관리, 비용 추적, rate limiting을 위해 에이전트를 그 proxy로 지정하세요. 에이전트 코드는 동일하며 proxy URL만 설정하면 돼요:
proxy_agent.py
import litellm# Point litellm at your proxyresponse = litellm.completion(
model="claude-sonnet-5", # model name from your proxy config
api_base="http://localhost:4000", # proxy URL
api_key="sk-", # proxy virtual key
tools=llm_tools,
messages=messages,)
또는 코드 변경 없이 환경 변수를 사용하세요:
export OPENAI_API_BASE="http://localhost:4000"export OPENAI_API_KEY="sk-"python scalekit_agent.py
엔드투엔드 예시: Inbox Triage Agent
Scalekit 도구 실행과 단계별 모델 라우팅을 LiteLLM으로 결합한 프로덕션 스타일 예시는 litellm-agentkit-inbox-triage를 참고하세요. 다음을 보여줍니다:
- Gmail 폴링과 파이프라인 단계별로 다른 모델로 스레드 분류
- 키워드 규칙과 LLM 타이브레이크로 GitHub 저장소 라우팅
- Scalekit 도구 호출 루프를 통한 관련 GitHub 이슈 검색
- Slack 알림과 이슈 생성/답변 전 사람 승인 대기
트러블슈팅
| Issue | Solution |
| execute_tool returns "connection not found" | The connection_name must match the exact label in Dashboard → AgentKit → Connections (including case). Use an env var instead of hardcoding. |
| Connected account stays in PENDING | The user hasn't completed the OAuth flow. Regenerate the authorization link and have them open it in a browser. |
| Model returns text instead of tool calls | Not all models support function calling. Use a model that does (GPT-4o, Claude Sonnet/Opus, Gemini Pro). Check supported providers. |
| litellm.completion() raises an auth error | Verify your LLM provider API key is set (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.) or that your proxy URL and key are correct. |
관련 리소스
- Scalekit Docs — 전체 문서
- Built-in Tools Reference — 100개 이상 커넥터의 도구 호출
- Supported Connectors — Gmail, GitHub, Slack, Salesforce 등
- LiteLLM Proxy Quick Start — 중앙 집중식 모델 라우팅 설정
- LiteLLM Function Calling — 함수 호출 문서