Building Production-Ready Blockchain-Enabled Agents: Zero to Hero - Part 2
In our previous article, we established a foundational architecture for blockchain-enabled agents using LLMs. Now, we'll focus on optimizing two critical components - LLM Integration and Context Management - to create a more robust, production-ready system.
Enhanced LLM Integration with Langchain
Our initial implementation used a basic LLamaModel setup. While functional, production environments demand more sophisticated capabilities. Let's enhance our implementation using Langchain with the Qwen2.5-7B-Instruct model:
class OptimizedBlockchainLLM:
def __init__(self, model_config, web3_provider, context_manager):
# Initialize Qwen model through Langchain
self.llm = Qwen(
model_name="Qwen/Qwen2.5-7B-Instruct",
temperature=0.7,
max_tokens=2048,
streaming=True, # Enable streaming for better response handling
)
self.web3 = Web3(web3_provider)
self.context_manager = context_manager
# Create reusable prompt templates
self.tx_analysis_template = PromptTemplate(
input_variables=["network", "gas_price", "tx_data", "related_context"],
template="""
Network: {network}
Current Gas Price: {gas_price}
Related Context:
{related_context}
Analyze the following blockchain transaction:
{tx_data}
Provide insights on:
1. Transaction efficiency and gas optimization
2. Potential security implications
3. Impact on network conditions
""",
)
# Initialize analysis chain
self.analysis_chain = LLMChain(llm=self.llm, prompt=self.tx_analysis_template)
async def analyze_transaction(self, tx_hash):
try:
# Fetch transaction data
tx = await self.web3.eth.get_transaction(tx_hash)
network = await self.web3.eth.get_chain_id()
gas_price = await self.web3.eth.gas_price
# Fetch related context from EnhancedContextManager
related_context = await self.context_manager.retrieve_context(str(tx))
# Generate insights using LLMChain
response = await self.analysis_chain.arun(
{
"network": network,
"gas_price": gas_price,
"tx_data": tx,
"related_context": related_context
or "No related context available",
}
)
# Add generated insights to context manager for future use
await self.context_manager.add_context(
{
"tx_hash": tx_hash,
"analysis": response,
"network": network,
"gas_price": gas_price,
}
)
return response
except Exception as e:
logger.error(f"Transaction analysis failed: {str(e)}")
raise TransactionAnalysisError(f"Analysis failed: {str(e)}")
Benefits of Langchain Integration
Langchain serves as an intelligent orchestration layer that significantly enhances our blockchain agent's capabilities when working with the model. It transforms raw LLM interactions into a structured framework, similar to how modern web frameworks streamline web development. Instead of writing complex custom code for prompt management, error handling, and context maintenance, Langchain provides these features out of the box.
The framework introduces reusable prompt templates that can be versioned and refined, robust error handling with automatic retries, and real-time streaming of model outputs. Its memory management system maintains conversation history and context across multiple transaction analyses, ensuring each analysis benefits from previous insights. This makes our blockchain agent not just more capable, but also more reliable and maintainable in production environments.
Benefits of Qwen Model
Qwen2.5-7B offers significant advantages over LLaMA models when it comes to production deployment. The model stands out for its exceptional throughput performance, particularly when processing medium to large amounts of text - it consistently achieves higher tokens-per-second rates compared to similarly-sized LLaMA models. This translates to faster real-world response times, which is crucial for blockchain applications where timely analysis matters.
The time-to-first-token (TTFT) performance of Qwen2.5 is notably superior, meaning your blockchain agent will start generating responses more quickly, enhancing the overall user experience. These characteristics make Qwen2.5 particularly well-suited for high-performance production environments where both speed and reliability are essential.
Advanced Context Management
Vector Database
In LLM applications, circular buffers lack the scalability and advanced querying required for production use cases. Replacing them with vector databases like Qdrant enables efficient hybrid searches combining semantic understanding and metadata filtering, as more explained in the previous article.
Context Management and Resolution
In blockchain environments, context management isn't just about storing data – it's about maintaining accurate and meaningful information that influences critical decisions. When multiple transactions or events occur, we often encounter duplicate information that could skew our analysis if not properly handled. For instance, the same transaction might be reported through different channels, or similar market conditions might be recorded multiple times.
Conflicting information presents an even bigger challenge. Consider a scenario where two different sources report different gas prices for the same time period – without proper handling, our agent might make decisions based on incorrect or outdated information. Similarly, when dealing with similar but distinct pieces of content (like related transactions from the same address), we need sophisticated mechanisms to maintain the subtle differences while recognizing their relationships.
Most importantly, missing context can lead to incomplete or incorrect analysis. By implementing proper context handling, our system can identify gaps in information and either seek to fill them or explicitly account for these uncertainties in its analysis.
The following functions were added to ensure our blockchain agent makes decisions based on accurate, complete, and properly deduplicated information:
handle_duplicate_information
manages cases where the same information appears multiple times, maintaining a history of changes.handle_conflicting_information
resolves conflicts between different pieces of information using timestamps and source reliability.handle_similar_content
processes related but distinct pieces of information while preserving their relationships.handle_missing_context
identifies gaps in the context and suggests potential sources for completing the missing information.from sentence_transformers import SentenceTransformer
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams
class EnhancedContextManager:
def __init__(self, qdrant_url):
self.embedding_model = SentenceTransformer(
"sentence-transformers/all-MiniLM-L12-v2"
)
self.vector_store = QdrantClient(url=qdrant_url)
# Create collection with appropriate vector parameters
self.vector_store.create_collection(
collection_name="blockchain_context",
vectors_config=VectorParams(size=384, distance=Distance.COSINE),
)
async def retrieve_context(self, query_data):
# Generate embedding for the query
query_embedding = self.embedding_model.encode(str(query_data))
# Search for related contexts
similar_contexts = await self.vector_store.search(
collection_name="blockchain_context",
query_vector=query_embedding,
limit=5,
score_threshold=0.85,
)
# Combine related context information into a single string
return "\n".join([context.payload for context in similar_contexts])
async def handle_duplicate_information(self, new_context, existing_context):
"""
Resolve duplicate information by keeping the most recent version
and maintaining a history of changes.
"""
if new_context['timestamp'] > existing_context['timestamp']:
merged_context = {
**existing_context,
**new_context,
'history': existing_context.get('history', []) + [existing_context]
}
return merged_context
return existing_context
async def handle_conflicting_information(self, contexts):
"""
Resolve conflicts between different pieces of information
using timestamp, source reliability, and consensus mechanisms.
"""
# Sort contexts by reliability score and timestamp
sorted_contexts = sorted(
contexts,
key=lambda x: (x['source_reliability'], x['timestamp']),
reverse=True
)
# Use the most reliable and recent information
primary_context = sorted_contexts[0]
# Store conflicting versions in metadata
primary_context['conflicts'] = sorted_contexts[1:]
return primary_context
async def handle_similar_content(self, new_context, similar_contexts, similarity_threshold=0.95):
"""
Process similar but distinct pieces of content while preserving
important differences and relationships.
"""
if not similar_contexts:
return new_context
# Group very similar contexts together
for similar in similar_contexts:
if cosine_similarity(new_context['vector'], similar['vector']) > similarity_threshold:
# Create a relationship between similar contexts
new_context['related_contexts'] = new_context.get('related_contexts', []) + [similar['id']]
# Update existing context with new relationships
await self.vector_store.update(
collection_name="blockchain_context",
points=[{
'id': similar['id'],
'payload': {
'related_contexts': similar.get('related_contexts', []) + [new_context['id']]
}
}]
)
return new_context
async def handle_missing_context(self, context_data):
"""
Identify and handle missing information in the context.
Returns context with missing fields marked and potential sources for completion.
"""
required_fields = {'timestamp', 'block_number', 'gas_price', 'network_state'}
missing_fields = required_fields - set(context_data.keys())
if missing_fields:
context_data['missing_fields'] = list(missing_fields)
context_data['completion_sources'] = {
field: self.get_completion_source(field)
for field in missing_fields
}
return context_data
async def add_context(self, context_data):
# Generate embedding for the new context
context_embedding = self.embedding_model.encode(str(context_data))
# Check for similar existing contexts
similar = await self.vector_store.search(
collection_name="blockchain_context",
query_vector=context_embedding,
limit=5,
score_threshold=0.90
)
# Process the context through our handling pipeline
processed_context = context_data
# Handle missing information first
processed_context = await self.handle_missing_context(processed_context)
if similar:
# Check for and handle duplicates
for existing in similar:
if existing.score > 0.98: # Very similar - potential duplicate
processed_context = await self.handle_duplicate_information(
processed_context, existing.payload
)
# Handle conflicting information if multiple similar contexts exist
if len(similar) > 1:
processed_context = await self.handle_conflicting_information(
[s.payload for s in similar] + [processed_context]
)
# Process similar but distinct content
processed_context = await self.handle_similar_content(
processed_context, [s.payload for s in similar]
)
# Store the processed context
await self.vector_store.upsert(
collection_name="blockchain_context",
points=[{
"id": generate_uuid(),
"vector": context_embedding,
"payload": processed_context
}]
)
Why different model for Embeddings?
While Qwen2.5 excels at reasoning and analysis tasks, it's not the optimal choice for generating embeddings in our system. Instead, we use all-MiniLM-L12-v2, which is specifically designed for the task of converting text into numerical vectors. This model creates compact 384-dimensional vectors, compared to the much larger 1024+ dimensional vectors from models like Qwen2.5. Think of it as having a specialized tool for a specific job – while Qwen2.5 is like a powerful general-purpose engine, all-MiniLM-L12-v2 is like a finely-tuned instrument for measuring text similarity.
Main Processing Engine: Qwen2.5-7B-Instruct
Context Processing Engine: all-MiniLM-L12-v2
User and Data Flow
Stage 1: Initial Data Reception
Stage 2: Context Retrieval
Stage 3: Analysis Processing
Stage 4: Knowledge Update
Conclusion
To build production-ready blockchain-enabled agents, optimizing LLM integration and context management is critical. By integrating Langchain with the Qwen2.5-7B-Instruct model, we enhanced the agent’s capabilities, leveraging reusable prompt templates, robust error handling, and efficient streaming for better reliability and maintainability.
The Qwen model’s performance advantages make it ideal for real-world deployments where speed and scalability are essential. Advanced context management using vector databases like Qdrant ensures accurate, complete, and deduplicated insights by addressing duplicates, conflicts, and missing data. Together, these enhancements create a more robust framework for deploying intelligent blockchain agents in production environments.
Comments
Post a Comment