Trade finance is the backbone of global commerce, yet it remains one of the most document-heavy and friction-prone sectors in fintech. A single letter of credit (LC) transaction can involve dozens of documents, multiple jurisdictions, and complex UCP600 compliance rules. Traditional keyword-based search fails here; a query for "risk mitigation for agricultural exports to Brazil" won't match a document titled "Soybean Shipment Guarantee Structure." To solve this, modern fintechs are moving toward Semantic Recommendation Engines. However, a simple RAG (Retrieval-Augmented Generation) pipeline is insufficient for enterprise trade finance. These workflows require state management, regulatory compliance checks, and multi-step reasoning. This article demonstrates how to build an Enterprise Multi-Agent RAG System using LangGraph, ChromaDB, and Semantic Similarity. We will build a "Trade Structuring Advisor" that recommends optimal financing instruments based on unstructured client requests, maintaining conversation state and audit trails.
Architecture Overview
Our system uses a cyclic graph architecture rather than a linear chain. This allows agents to critique their own work, retrieve additional context, and maintain persistent memory across sessions.
The Agent Topology
Intake & Memory Agent: Classifies the user request, loads historical client state, and determines if clarification is needed.
Semantic Retrieval Agent: Queries ChromaDB using dense embeddings to find similar past deals, policy documents, and product sheets.
Structuring Advisor Agent: Synthesizes retrieved context to recommend specific trade finance products (e.g., SBLC, Factoring, Forfaiting).
Compliance Critic Agent: Validates recommendations against internal risk appetite and sanctions lists. If validation fails, the graph loops back to the Advisor.
State Manager: Persists the interaction to Chroma’s metadata store and external DB for auditability.
Tech Stack
Orchestration: LangGraph (Stateful, cyclic agent workflows)
Vector Store: ChromaDB (Semantic similarity + metadata filtering)
Embeddings:
text-embedding-3-large(High-dimensional semantic capture)LLM: GPT-4o / Claude 3.5 Sonnet (Reasoning & Synthesis)
Memory: LangGraph Checkpointer + Chroma Metadata
Real-Time Use Case: The Mid-Market Exporter
Scenario: A relationship manager at a fintech receives a vague email from a mid-market exporter:
"We have a new buyer in Vietnam for our machinery. They want 90-day terms but our bank won't extend more credit. We need to secure payment without hurting cash flow. What did we do for Apex Manufacturing last year?"
The Challenge:
Retrieve the specific "Apex Manufacturing" deal structure from unstructured PDFs.
Match the current Vietnam/machinery scenario to relevant products semantically.
Ensure the recommendation complies with current Vietnam exposure limits.
Remember this conversation for future follow-ups.
Implementation
1. Environment Setup
pip install langgraph langchain-chroma chromadb langchain-openai \
langchain-community tiktoken python-dotenv2. Defining the Enterprise State
In LangGraph, state is the single source of truth. For trade finance, we need more than just messages; we need structured deal parameters and compliance flags.
from typing import Annotated, TypedDict, List
from langgraph.graph.message import add_messages
from langchain_core.documents import Document
class TradeFinanceState(TypedDict):
"""State schema for the Trade Finance Multi-Agent Graph"""
messages: Annotated[list, add_messages]
# Structured extraction from user query
client_name: str | None
counterparty_country: str | None
tenor_days: int | None
product_type: str | None
# RAG & Recommendation Context
retrieved_docs: List[Document]
recommended_products: List[str]
# Compliance & Control Flow
compliance_passed: bool | None
critic_feedback: str | None
iteration_count: int
# Memory
session_id: str
previous_deals_referenced: List[str]3. Semantic Indexing with Chroma
Before querying, we must ingest trade finance documents with rich metadata. Semantic similarity alone isn't enough; we need hybrid filtering.
import chromadb
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
def initialize_trade_vector_store():
"""Initialize Chroma with trade finance specific configuration"""
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
vectorstore = Chroma(
collection_name="trade_finance_knowledge_base",
embedding_function=embeddings,
persist_directory="./chroma_trade_db",
# Enable HNSW index for enterprise-scale performance
collection_metadata={"hnsw:space": "cosine"}
)
return vectorstore
# Example ingestion with critical metadata
sample_docs = [
Document(
page_content="Structured forfaiting facility for Vietnamese machinery exports...",
metadata={
"doc_type": "deal_summary",
"client": "Apex Manufacturing",
"country": "Vietnam",
"product": "Forfaiting",
"year": 2025,
"risk_rating": "B+"
}
),
# ... more documents
]
vectorstore = initialize_trade_vector_store()
vectorstore.add_documents(sample_docs)4. Building the Agent Nodes
Semantic Retrieval Node
This node performs semantic search and metadata filtering based on extracted state.
async def retrieval_node(state: TradeFinanceState):
"""Retrieve relevant docs using semantic similarity + metadata filters"""
query = state["messages"][-1].content
# Build dynamic metadata filter from state
where_filter = {}
if state.get("counterparty_country"):
where_filter["country"] = state["counterparty_country"]
if state.get("client_name"):
where_filter["client"] = state["client_name"]
# Semantic search with enterprise filters
docs = vectorstore.similarity_search(
query=query,
k=5,
filter=where_filter if where_filter else None
)
return {
"retrieved_docs": docs,
"previous_deals_referenced": [
d.metadata.get("client") for d in docs
if d.metadata.get("doc_type") == "deal_summary"
]
}
Structuring Advisor Node
Generates recommendations grounded in retrieved context.

Join the conversation! Your thoughts help the community grow.