langchainrust
Rust
License
Crates.io
Documentation
CI
Crates.io Downloads
LLM 애플리케이션 구축을 위한 LangChain에서 영감을 받은 Rust 프레임워크입니다.
해결하는 문제점: 에이전트(Agents), RAG (검색 증강 생성), BM25 키워드 검색, 하이브리드 검색(Hybrid retrieval), LangGraph 워크플로우, MCP 도구, A2A 에이전트 간 프로토콜, 가드레일(Guardrails), 다중 에이전트 핸드오프(multi-agent Handoffs) 등 모든 것을 순수 Rust로 구축할 수 있습니다.
문서화 (Documentation)
| Docs | Content |
|---|
| 中文使用指南 | 모든 컴포넌트의 상세 사용법 (중국어) |
| ... | |
설계 원칙 (Design Principles)
이 프레임워크는 자체 설계 검토를 통해 도출된 몇 가지 엄격한 규칙을 중심으로 구축되었습니다. 이것이 수동으로 구현한 LLM 연결 코드와 다르게 느껴지게 하는 요소입니다:
| Principle | What it means in practice |
|---|
| Explicit over silent | 사일런트하게 성능 저하되는 일이 없습니다. API가 X를 약속했다면, X를 제공하거나 명확하게 실패합니다. 배치 임베딩 정렬(Batch-embedding alignment)은 빈 벡터/이동된 벡터 대신 명시적인 오류를 반환하며, EmbeddingMatcher의 키워드 폴백 기능은 제거되었습니다. 라우팅 실패는 흡수되는 Err(_) => {}가 아닌 오류로 표면화됩니다. |
| ... | |
핵심 기능 (Core Features)
LLM 및 제공자 (LLM & Providers)
| Component | Description |
|---|
| 통합된 LLM 접근성 | 하나의 BaseChatModel 트레이트 뒤에 11개의 제공자가 있습니다: OpenAI, Ollama, Anthropic Claude, Gemini, Azure, Cohere, DeepSeek, Qwen, Moonshot, Zhipu, Mistral. LLMClient::from_env()는 환경 변수에서 11개 중 하나를 자동으로 감지합니다. |
| ... | |
임베딩 (Embeddings)
| Component | Description |
|---|
통합된 Embeddings 트레이트 | embed_query / embed_documents / dimension / model_name을 제공하며, 트레이트의 기본 경로에서 빈 입력 및 배치 정렬(batch-alignment) 검사가 강제됩니다. |
| ... | |
구성: 체인 및 LCEL (Composition: Chains & LCEL)
LCEL
| Component | Description |
|---|
| LCEL | 4가지 기본 동작(invoke, batch, stream, transform)을 가진 Runnable. 연산자(Operators): pipe, RunnableLambda, RunnablePassthrough, RunnableParallel, RunnableBranch, RunnableBinding, RunnableWithFallbacks, RunnableAssign, with_retry, RunnableSequence. PhantomData를 사용한 타입 소거(Type-erased) — 컴파일러가 검사하는 타입 일치와 동적 구성. |
Agents & Multi-Agent
| Component | Description |
|---|
| BaseAgent / AgentExecutor | '번역가/집사' 분리 구조: BaseAgent는 모델 출력을 결정(Action / Actions / Finish)으로 변환하고, AgentExecutor는 실제 루프를 담당하며 — 도구 타임아웃, LLM 재시도, 동시성 세마포어, 그리고 max_iterations가 [1, 100]으로 제한됩니다. |
Retrieval & RAG
| Component | Description |
|---|
Unified RetrieverTrait | 모든 리트리버가 이를 구현합니다: SimilarityRetriever, BM25Retriever / ChunkedBM25Retriever, UnifiedHybridIndex, ParentDocumentRetriever — 따라서 어떤 검색 전략이든 RAG 파이프라인에 연결될 수 있습니다. |
Memory & Sessions
| Component | Description |
|---|
| Four memories | 네 가지 메모리: ConversationBufferMemory(전체 대화 기록), ConversationBufferWindowMemory(최근 k 턴), ConversationSummaryMemory(LLM 요약), ConversationSummaryBufferMemory(요약 + 최근 원본). 모두 BaseChatMemory를 구현합니다. |
Protocols: MCP & A2A
공식 MCP 전송 계층 및 A2A 통신
| Component | Description |
|---|
| Official MCP transports (v0.22.4) | 명세에 충실한 클라이언트인 StdioMcpClient (subprocess stdio)와 StreamableMcpClient (Streamable HTTP, stateless + Mcp-Session-Id 모드), 그리고 서버 측의 MCPServer::serve_streamable_http가 포함됩니다. 이는 공식 TypeScript SDK 1.30.0 및 Python SDK(4/4 시나리오)와 상호 운용성이 검증되었습니다. 원격 서버에 로그인이 필요한 경우 OAuth 2.1 인증 흐름(authorization server metadata, PKCE, token refresh)이 포함됩니다. |
| ... | |
| A2A WebSocket transport (v0.27.0) | ws 기능은 /events 옆에 GET /ws를 추가하며, 이는 bearer 인증, B7 크로스 테넌트(cross-tenant) notification_visible 가드 및 ?taskId= 제한을 공유합니다. 텍스트 프레임당 하나의 필터링된 TaskPushNotification이 전송됩니다. 클라이언트의 connect_ws / send_task_streaming_ws는 SSE 쌍(pair)을 미러링하며, A2AWebSocketStream::next()는 유휴 구독 상태를 유지하기 위해 프로토콜 핑(ping)에 응답합니다. |
| A2A scale (v0.27.0) | AgentFleet / SkillIndex (skill_affinity 의미론적 라우팅) + DelegationGuard / TaskSharder / CircuitBreaker; A2AClientBuilder::fleet(Arc<AgentFleet>)는 skill-affinity 라우팅을 send_task에 연결합니다 (fleet이 없는 경우 → 직접). |
| A2A vs MCP | A2A는 에이전트 ↔ 에이전트를 오케스트레이션하며; MCP는 에이전트가 도구를 호출할 수 있게 합니다. 이 둘은 조합됩니다: 에이전트 간에는 A2A를, 그 아래 레벨에서는 MCP를 사용합니다. |
품질: 가드레일(Guardrails), 평가(Evaluation), 관측 가능성(Observability)
| Component | Description |
|---|
| Guardrails | 모든 에이전트 또는 체인 주변의 입력/출력 안전 가드레일입니다. InputGuardrailResult (Pass/Block)와 OutputGuardrailResult (Pass/Block/Modify)는 타입별로 분리되어 있으며, Modify는 입력에 대해서는 컴파일 타임상 불가능합니다. Guardable 트레이트(trait)를 사용하면 모든 BaseChain을 래핑할 수 있습니다. |
| ... | |
| Component | Description |
|---|
| Built-in tools | Calculator, SimpleMathTool, DateTimeTool, URLFetchTool, WikipediaTool, DuckDuckGoSearchTool, PythonREPLTool. |
| ... | |
벡터 스토어 (Vector Stores)
| 컴포넌트 | 설명 |
|---|
통합 VectorStore 트레이트 | add_documents, similarity_search, similarity_search_with_min_score, similarity_search_with_filter (MetadataFilter with Eq/Ne/Gt/Gte/Lt/Lte/In/Nin + And/Or, v0.18), similarity_search_text (저장소(store)가 임베더를 소유한 경우 자동 임베딩, 그렇지 않으면 명시적 오류 발생), embed_query, get_document, delete_document, count, clear. |
| ... | |
아키텍처 (Architecture)
langchainrust는 공용 API를 재내보내는 단일 파사드(facade) 크레이트인 langchainrust(crates/lc)를 가진 23개 크레이트 워크스페이스입니다. 레이어들은 아래로 의존성을 가집니다 — lc-shared / lc-schema가 가장 하단에 위치하며 모든 구성 요소들이 이를 의존합니다. 이는 순환 참조(circular-dependency) 문제를 해결하는 정확한 방식입니다.
┌──────────────────────────────────────┐
│ langchainrust (facade, crates/lc) │
└──────────────────┬───────────────────┘
...
(lc-memory, lc-sessions, lc-testkit 및 lc-tools-derive는 명확성을 위해 다이어그램에서 생략되었으며, 아래 크레이트 테이블에 23개 전체 목록이 나열되어 있습니다.)
| 크레이트 | 역할 |
|---|
| lc-core | 실행 레이어: Runnable / LCEL 연산자, BaseChatModel/BaseLanguageModel, BaseTool/ToolRegistry, 출력 파서(output parsers), 구조화된 출력(structured output), 토큰 카운터, LLMCache, RouterLLM (+ ModelRegistry 가격/기능, ModelRateLimit, RouterBudget), 비용 원장(CostTracker, ModelPrice, PricingTable, ObsEvent::Cost), CancellationToken, StructuredJudge, BatchClient, cosine_similarity. |
| ... | |
설치 (Installation)
[dependencies]
langchainrust = "0.28.0"
tokio = { version = "1.0", features = ["full"] }
...
MSRV에 대한 참고 사항: Rust **1.85+**가 필요합니다.
빠른 시작 (Quick Start)
1. 기본 채팅 (Basic chat)
use langchainrust::{OpenAIChat, OpenAIConfig, BaseChatModel};
use langchainrust::schema::Message;
...
2. 다중 제공업체 지원 — 동일한 인터페이스, 설정만 변경하면 됨 (Multi-provider — same interface, swap config)
use langchainrust::{
DeepSeekChat, MoonshotChat, ZhipuChat, QwenChat,
AnthropicChat, OllamaChat,
...
}
3. LCEL — 모든 것을 하나의 체인으로 구성 (compose everything into one chain)
use langchainrust::{
ChatPromptTemplate, Message, OpenAIChat, OpenAIConfig, RunnableExt, StrOutputParser,
};
...
전체 다섯 가지 요소 조합(프롬프트 + 메모리 + LLM + 파서 + RAG)을 하나의 프로그램에서 확인하려면 lcel_compose를 참조하세요.
4. BM25 키워드 검색 (API 키 불필요)
use langchainrust::{BM25Retriever, Document};
let mut retriever = BM25Retriever::new();
...
더 많은 예제는 中文使用指南 또는 Usage Guide에서 확인할 수 있습니다.
예제 (Examples)
crates/lc/examples/ 디렉터리는 핵심 기능을 다루는 42개의 실행 가능한 예제를 제공합니다:
| 카테고리 | 예제 | API 키 필요 여부 |
|---|
| basic | chat / streaming / multi_provider / token_counter / quick_start / responses_api / batch_api / sandbox | 예 (Yes) |
| ... | | |
API 키가 필요한 예제는 환경 변수에서 읽어옵니다:
export OPENAI_API_KEY="your-key"
cargo run --example basic_chat
API 키가 필요 없는 예제(BM25 / LangGraph / Memory / Loader)는 즉시 실행할 수 있어 빠른 탐색에 매우 유용합니다.
프로덕션 고려 사항 (Production Considerations)
프레임워크의 설계 검토를 통해 얻은 몇 가지 중요한 지침입니다:
-
키워드 폴백(keyword fallback)에 의존하지 마십시오. local-embeddings 기능이 없는 LocalEmbeddings는 Bag-of-Words 방식의 폴백입니다. 실제 의미론적 검색(semantic retrieval)에는 사용하지 마세요. 해당 기능을 활성화하거나 API 제공업체를 사용하십시오.
-
임베딩 배치 정렬 오류는 명시적입니다. 누락되거나 이동된 벡터는 이제 빈 슬롯 대신 EmptyVectorInBatch 또는 BatchMismatch를 반환합니다. 이를 실패로 간주하고 건너뛰지 마십시오.
-
중국어 텍스트: Tiktoken 기반 토큰 계산을 선호하십시오. len/4 휴리스틱은 중국어를 과도하게 계산합니다. ContextWindow는 사용 가능한 경우 TiktokenCounter를 사용합니다.
-
요약 메모리: 이전 요약은 LLM 실패 시에도 유지됩니다. 실패한 요약은 이전 요약과 원본 메시지를 온전하게 남겨둡니다(last_summary_error()가 실패를 보고). 이력이 조용히 지워지는 일은 없습니다.
-
MCP / A2A 인증은 JSON-RPC 계층에서 이루어집니다. Bearer-token 인증의 경우 HTTP 200을 반환하지만 본문(body)에 {"error":{"code":401,...}}가 포함될 수 있으므로, 상태 코드뿐만 아니라 본문을 확인하십시오. Agent-card 검색은 의도적으로 공개되어 있습니다.
-
MCP 실패 의미론은 전송 방식별로 다릅니다. 상태 비저장(stateless) HTTP 트랙에는 핸드셰이크나 하트비트가 없습니다. 도달할 수 없는 서버는 요청 자체를 즉시 실패시키므로 대기할 재연결 과정이 없습니다. stdio 전송 방식은 아예 재연결 기능이 없습니다: 자식 프로세스 종료(child exit) 또는 파이프 EOF는 다음 호출에서 MCPError::connection_lost()로 나타납니다. 서브프로세스를 다시 시작하는 것은 호출자(caller)의 책임입니다. MRTR 왕복 횟수는 max_round_trips (-32003)에 의해 제한되며, 메서드 속도 제한은 -32002로 빠르게 실패합니다.
-
Pinecone은 의도적으로 ID로 검색하는 기능을 제공하지 않습니다. get_document / get_embedding / clear는 명시적인 StorageError를 반환하며, count는 describe_index_stats를 사용합니다. Pinecone을 사용할 때 이러한 작업(ops)들을 우회하도록 설계하지 마십시오.
-
SQLTool은 기본적으로 읽기 전용(read-only)이며, 매개변수화된 쿼리(parameterized queries)를 사용하십시오. Python 블랙리스트는 보안 경계가 아니라 노이즈 필터링 기능입니다. 실제 코드 실행은 LocalSandbox로 격리하십시오.
-
요약 메모리 및 세션은 특별한 배선이 필요하지 않습니다. 영구적인 다중 턴(multi-turn) 앱을 위해 EventSessionManager는 with_memory (또는 세션별 with_memory_factory)를 통해 BaseMemory를 받습니다. 레거시 SessionManager는 더 이상 사용되지 않으며 0.23.0 버전에서 제거됩니다.
-
알 수 없는 모델 가격은 $0을 청구하며, 실행을 중단시키지 않습니다. CostTracker는 PricingTable에 누락된 모델의 사용량을 0 비용으로 기록합니다. 만약 USD 예산 게이트가 실제로 해당 모델을 제약해야 한다면 모델 가격을 명시적으로 등록하십시오. 그렇지 않으면 이 게이트는 해당 모델에서 조용히 작동하지 않습니다 (never trips).
-
체크포인트 쓰기는 낙관적(optimistic)입니다. 동일한 LangGraph 체크포인트에 대한 동시의 오래된 쓰기(stale writes)는 GraphError::CheckpointVersionConflict를 반환합니다. 따라서 다시 읽고 재시도해야 하며, 절대 마지막 쓰기가 승리하는 방식(last-write-wins)이 아닙니다 (SQLite/Postgres/Redis 백엔드는 모두 compare-and-swap을 사용합니다).
테스트 (Testing)
기여 (Contributing)
기여 환영합니다! CONTRIBUTING.md를 참조하십시오.
라이선스 (License)
MIT 또는 Apache-2.0 중 선택 가능합니다.