Using Tool Results in Chains
Once tools execute and return data, you need to effectively incorporate those results into your chain's processing. This lesson covers patterns for working with tool outputs.
Tool Result Flow
Chain Step → Tool Decision → Tool Execution → Result Processing → Next Step
│
▼
┌──────────────┐
│ Tool Result │
│ - Raw data │
│ - Status │
│ - Metadata │
└──────────────┘
Processing Tool Results
Raw Result Handling
Tool results come in various formats:
// API response
const apiResult = {
status: 200,
data: {
customers: [...],
pagination: { page: 1, total: 50 }
}
};
// Database query
const dbResult = {
rows: [...],
rowCount: 25,
duration: 45
};
// Web search
const searchResult = {
results: [
{ title: '...', snippet: '...', url: '...' },
// ...
],
totalResults: 1500
};
Result Transformation
Transform raw results for LLM consumption:
Loading Prompt Playground...
Result Validation
Verify tool results before use:
function validateToolResult(result, expectedSchema) {
const errors = [];
// Check required fields
if (expectedSchema.required) {
for (const field of expectedSchema.required) {
if (!(field in result)) {
errors.push(`Missing required field: ${field}`);
}
}
}
// Check types
for (const [field, value] of Object.entries(result)) {
const expected = expectedSchema.properties?.[field];
if (expected && typeof value !== expected.type) {
errors.push(`Type mismatch for ${field}: expected ${expected.type}`);
}
}
return {
valid: errors.length === 0,
errors
};
}
Combining Multiple Tool Results
Merging Complementary Results
async function mergeToolResults(results) {
// Results from different tools about the same entity
const [customerData, orderHistory, supportTickets] = results;
return {
customer: {
...customerData,
recentOrders: orderHistory.orders.slice(0, 5),
openTickets: supportTickets.filter(t => t.status === 'open'),
totalSpend: orderHistory.totalSpend,
ticketCount: supportTickets.length
},
metadata: {
sources: ['customer_db', 'order_system', 'support_system'],
fetchedAt: Date.now()
}
};
}
Reconciling Conflicting Results
Loading Prompt Playground...
Result-Aware Chain Steps
Conditional Processing Based on Results
async function conditionalToolProcessing(toolResult) {
// Different processing based on result status
if (toolResult.status === 'not_found') {
return await handleNotFound(toolResult);
}
if (toolResult.data.length === 0) {
return await handleEmptyResults(toolResult);
}
if (toolResult.data.length > 100) {
// Too many results - need to filter
return await handleLargeResultSet(toolResult);
}
return await standardProcessing(toolResult);
}
Iterative Tool Use
Use results to decide on further tool calls:
Loading Prompt Playground...
Formatting Results for LLMs
Structured to Natural Language
function formatResultsForLLM(toolResults, format = 'narrative') {
if (format === 'narrative') {
return `
Based on the data retrieved:
- Customer ${toolResults.customer.name} has been a member since ${toolResults.customer.joinDate}
- They have placed ${toolResults.orders.length} orders totaling ${toolResults.orders.total}
- Currently has ${toolResults.tickets.open} open support tickets
`.trim();
}
if (format === 'structured') {
return `
CUSTOMER DATA:
Name: ${toolResults.customer.name}
Member Since: ${toolResults.customer.joinDate}
ORDER HISTORY:
Total Orders: ${toolResults.orders.length}
Total Spend: ${toolResults.orders.total}
SUPPORT STATUS:
Open Tickets: ${toolResults.tickets.open}
`.trim();
}
}
Handling Large Results
async function formatLargeResults(results, maxTokens = 2000) {
if (estimateTokens(results) <= maxTokens) {
return results;
}
// Strategy 1: Truncate to top N
if (Array.isArray(results)) {
return results.slice(0, 10);
}
// Strategy 2: Summarize
return await summarizeResults(results, maxTokens);
}
Exercise: Build Result Processing Pipeline
Design a result processing pipeline:
Loading Prompt Playground...
Key Takeaways
- Transform raw tool results into LLM-friendly formats
- Validate results before incorporating into chains
- Merge complementary results from multiple tools
- Reconcile conflicts using recency and source reliability
- Adapt processing based on result status and size
- Use iterative tool calls when initial results need refinement
- Format large results to fit context windows
Next, we'll explore orchestrating multiple tools together.

