GuideIntermediate

Freshdesk: AI Assistant for Support Agents

March 10, 2026
13 min read
Ailog Team

Deploy a RAG AI assistant in Freshdesk to help your agents: response suggestions, intelligent search, and 35% reduction in handling time.

TL;DR

Freshdesk combined with a RAG system transforms your agents into instant experts. The AI assistant analyzes each ticket, searches your knowledge base, and suggests contextual responses. Result: 35% reduction in handling time and notable improvement in customer satisfaction. This guide covers technical integration, assistance workflows, and key metrics.

Freshdesk + RAG: The Winning Combo

Why Freshdesk is Ideal for RAG

Freshdesk offers several advantages for RAG integration:

Freshdesk FeatureRAG Usage
Complete REST APIBidirectional integration
Configurable webhooksReal-time triggering
Custom AppsIntegrated agent interface
Freddy AIPossible complementarity
Solutions articlesNatural data source

Measured ROI of Integration

Companies using RAG + Freshdesk report:

  • 35% reduction in average handling time (AHT)
  • 28% improvement in first contact resolution rate
  • 50% reduction in new agent onboarding time
  • 22% increase in CSAT score

Freshdesk Integration Architecture

Custom App Approach (Recommended)

Create a Freshdesk application that displays RAG suggestions:

DEVELOPERjavascript
// app/scripts/app.js - Freshdesk Custom App client.events.on("app.activated", async function() { const ticketData = await client.data.get("ticket"); await loadRAGSuggestions(ticketData); }); async function loadRAGSuggestions(ticket) { const query = `${ticket.subject}\n${ticket.description}`; try { // Call to your RAG backend const response = await fetch("https://your-rag-api.com/suggest", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${await client.iparams.get("rag_api_key")}` }, body: JSON.stringify({ query: query, ticket_id: ticket.id, requester_email: ticket.requester.email }) }); const suggestions = await response.json(); renderSuggestions(suggestions); } catch (error) { console.error("RAG suggestion error:", error); showFallback(); } } function renderSuggestions(suggestions) { const container = document.getElementById("suggestions-container"); // Suggested response if (suggestions.suggested_response) { container.innerHTML += ` <div class="suggestion-card"> <h4>Suggested Response</h4> <p class="confidence">Confidence: ${Math.round(suggestions.confidence * 100)}%</p> <div class="response-text">${suggestions.suggested_response}</div> <button onclick="insertResponse('${escapeQuotes(suggestions.suggested_response)}')"> Insert into response </button> </div> `; } // Relevant sources if (suggestions.sources && suggestions.sources.length > 0) { let sourcesHtml = '<div class="sources-list"><h4>Sources</h4><ul>'; suggestions.sources.forEach(source => { sourcesHtml += ` <li> <a href="${source.url}" target="_blank">${source.title}</a> <span class="score">${Math.round(source.score * 100)}%</span> </li> `; }); sourcesHtml += '</ul></div>'; container.innerHTML += sourcesHtml; } } async function insertResponse(text) { // Insert into Freshdesk response editor await client.interface.trigger("setValue", { id: "editor", value: text }); }

RAG Backend for Freshdesk

DEVELOPERpython
from fastapi import FastAPI, HTTPException, Depends from pydantic import BaseModel import httpx app = FastAPI() class FreshdeskTicketRequest(BaseModel): query: str ticket_id: int requester_email: str class RAGSuggestionResponse(BaseModel): suggested_response: str confidence: float sources: list[dict] similar_tickets: list[dict] @app.post("/suggest", response_model=RAGSuggestionResponse) async def get_suggestions(request: FreshdeskTicketRequest): """ Generates RAG suggestions for a Freshdesk ticket. """ # 1. Search knowledge base documents = await search_knowledge_base(request.query) # 2. Get customer context customer = await get_freshdesk_customer(request.requester_email) previous_tickets = await get_customer_tickets(customer["id"]) # 3. Find similar resolved tickets similar = await find_similar_resolved_tickets(request.query) # 4. Generate suggestion suggestion = await generate_response( query=request.query, documents=documents, customer_context=customer, similar_tickets=similar ) return RAGSuggestionResponse( suggested_response=suggestion["response"], confidence=suggestion["confidence"], sources=[{ "title": doc.metadata["title"], "url": doc.metadata["url"], "score": doc.score } for doc in documents[:3]], similar_tickets=[{ "id": t["id"], "subject": t["subject"], "resolution": t["resolution_note"] } for t in similar[:2]] )

Synchronization with Freshdesk Solutions

Importing Solutions Articles

DEVELOPERpython
class FreshdeskKBSync: """ Synchronizes Freshdesk Solutions articles with RAG. """ def __init__(self, domain: str, api_key: str, rag_client): self.base_url = f"https://{domain}.freshdesk.com/api/v2" self.headers = {"Authorization": f"Basic {api_key}"} self.rag = rag_client async def sync_all_articles(self) -> dict: """ Synchronizes all categories and articles. """ stats = {"categories": 0, "folders": 0, "articles": 0} async with httpx.AsyncClient() as client: # Get categories categories = await self._get_categories(client) stats["categories"] = len(categories) for category in categories: # Get folders for each category folders = await self._get_folders(client, category["id"]) stats["folders"] += len(folders) for folder in folders: # Get and index articles articles = await self._get_articles(client, folder["id"]) for article in articles: if article["status"] == 2: # Published await self._index_article(article, category, folder) stats["articles"] += 1 return stats async def _index_article(self, article: dict, category: dict, folder: dict): """ Indexes an article in the RAG system. """ # Clean HTML content clean_content = self._strip_html(article["description"]) metadata = { "source": "freshdesk_solutions", "article_id": article["id"], "title": article["title"], "url": f"https://{self.domain}.freshdesk.com/support/solutions/articles/{article['id']}", "category": category["name"], "folder": folder["name"], "tags": article.get("tags", []), "created_at": article["created_at"], "updated_at": article["updated_at"] } await self.rag.index_document( content=f"# {article['title']}\n\n{clean_content}", metadata=metadata, doc_id=f"freshdesk_article_{article['id']}" ) async def _get_categories(self, client: httpx.AsyncClient) -> list: response = await client.get( f"{self.base_url}/solutions/categories", headers=self.headers ) return response.json() async def _get_folders(self, client: httpx.AsyncClient, category_id: int) -> list: response = await client.get( f"{self.base_url}/solutions/categories/{category_id}/folders", headers=self.headers ) return response.json() async def _get_articles(self, client: httpx.AsyncClient, folder_id: int) -> list: response = await client.get( f"{self.base_url}/solutions/folders/{folder_id}/articles", headers=self.headers ) return response.json()

Webhook for Real-time Updates

DEVELOPERpython
@app.post("/freshdesk/webhook/article") async def handle_article_update(payload: dict): """ Receives article update webhooks. """ event = payload.get("event") article_id = payload.get("data", {}).get("article_id") if event == "article.created" or event == "article.updated": # Fetch and reindex article article = await fetch_article(article_id) await sync.index_article(article) return {"status": "indexed"} elif event == "article.deleted": # Remove from RAG await rag.delete_document(f"freshdesk_article_{article_id}") return {"status": "deleted"} return {"status": "ignored"}

Agent Assistance Workflows

Workflow 1: Suggestion on Ticket Open

DEVELOPERpython
class TicketOpenWorkflow: """ Triggered when an agent opens a ticket. """ async def execute(self, ticket_id: int) -> dict: # Get ticket ticket = await self.freshdesk.get_ticket(ticket_id) # Prepare context context = await self._build_context(ticket) # Generate suggestions suggestions = await self.rag_assistant.suggest( query=f"{ticket['subject']}\n{ticket['description']}", context=context ) # Enrich with metrics suggestions["priority_suggestion"] = self._suggest_priority( ticket, suggestions ) suggestions["group_suggestion"] = self._suggest_group( ticket, suggestions ) return suggestions async def _build_context(self, ticket: dict) -> dict: """ Builds complete context for RAG. """ # Customer history requester = await self.freshdesk.get_contact(ticket["requester_id"]) previous_tickets = await self.freshdesk.get_tickets( requester_id=requester["id"], status=["resolved", "closed"], limit=5 ) # Associated product/company company = None if ticket.get("company_id"): company = await self.freshdesk.get_company(ticket["company_id"]) return { "requester": requester, "previous_tickets": previous_tickets, "company": company, "custom_fields": ticket.get("custom_fields", {}) }

Workflow 2: Assistance During Writing

DEVELOPERpython
class RealtimeAssistWorkflow: """ Provides real-time assistance during writing. """ async def assist_typing( self, ticket_id: int, partial_response: str ) -> dict: """ Called while the agent types their response. """ ticket = await self.freshdesk.get_ticket(ticket_id) # Analyze the intent of current response intent = await self.analyze_response_intent(partial_response) # Suggest completions if intent == "needs_procedure": return await self._suggest_procedures(ticket, partial_response) elif intent == "needs_article": return await self._suggest_articles(ticket, partial_response) elif intent == "needs_template": return await self._suggest_templates(ticket, partial_response) return {"suggestions": []} async def _suggest_procedures( self, ticket: dict, partial: str ) -> dict: """ Suggests relevant procedures. """ procedures = await self.rag.search( query=partial, filter={"type": "procedure"}, top_k=3 ) return { "type": "procedures", "suggestions": [{ "title": p.metadata["title"], "steps": self._extract_steps(p.text), "insert_text": self._format_procedure(p) } for p in procedures] }

Workflow 3: Pre-send Validation

DEVELOPERpython
class PreSendValidationWorkflow: """ Validates response before sending. """ async def validate( self, ticket: dict, response: str ) -> dict: """ Checks quality and relevance of the response. """ validations = {} # 1. Check completeness questions = await self._extract_questions(ticket["description"]) answered = await self._check_questions_answered(questions, response) validations["completeness"] = { "score": len(answered) / len(questions) if questions else 1.0, "unanswered": [q for q in questions if q not in answered] } # 2. Check KB consistency kb_check = await self._verify_against_kb(response) validations["kb_consistency"] = kb_check # 3. Check tone and style tone_check = await self._check_tone(response) validations["tone"] = tone_check # 4. Overall score overall_score = ( validations["completeness"]["score"] * 0.4 + validations["kb_consistency"]["score"] * 0.4 + validations["tone"]["score"] * 0.2 ) return { "valid": overall_score >= 0.7, "score": overall_score, "validations": validations, "suggestions": self._generate_improvement_suggestions(validations) }

Integration with Freddy AI

Freshdesk offers Freddy AI, which can complement RAG:

DEVELOPERpython
class FreddyRAGHybrid: """ Combines Freddy AI and custom RAG. """ async def get_hybrid_suggestions( self, ticket: dict ) -> dict: """ Combines Freddy and RAG suggestions. """ # Get Freddy suggestions freddy_suggestions = await self.get_freddy_suggestions(ticket["id"]) # Get RAG suggestions rag_suggestions = await self.rag.suggest( query=f"{ticket['subject']}\n{ticket['description']}" ) # Merge intelligently merged = self._merge_suggestions(freddy_suggestions, rag_suggestions) return merged def _merge_suggestions( self, freddy: dict, rag: dict ) -> dict: """ Strategy for merging suggestions. """ # Prioritize RAG if high confidence if rag["confidence"] > 0.85: return { "primary": rag["suggested_response"], "alternative": freddy.get("suggested_response"), "source": "rag", "articles": rag["sources"] + freddy.get("articles", []) } # Prioritize Freddy if RAG has low confidence if rag["confidence"] < 0.5 and freddy.get("confidence", 0) > 0.7: return { "primary": freddy["suggested_response"], "alternative": rag["suggested_response"], "source": "freddy", "articles": freddy.get("articles", []) + rag["sources"] } # Otherwise, offer both return { "rag_suggestion": rag["suggested_response"], "freddy_suggestion": freddy.get("suggested_response"), "rag_confidence": rag["confidence"], "source": "both" }

Metrics and Continuous Improvement

Agent Dashboard

DEVELOPERpython
class AgentPerformanceMetrics: """ Agent performance metrics with RAG. """ async def get_agent_metrics( self, agent_id: int, period: str = "week" ) -> dict: tickets = await self._get_agent_tickets(agent_id, period) rag_assisted = [t for t in tickets if t.get("rag_used")] manual = [t for t in tickets if not t.get("rag_used")] return { "agent_id": agent_id, "period": period, "total_tickets": len(tickets), "rag_usage": { "count": len(rag_assisted), "percentage": len(rag_assisted) / len(tickets) * 100, "avg_resolution_time": self._avg_time(rag_assisted), "first_contact_resolution": self._fcr_rate(rag_assisted) }, "manual": { "count": len(manual), "avg_resolution_time": self._avg_time(manual), "first_contact_resolution": self._fcr_rate(manual) }, "improvement": { "time_saved": self._calculate_time_saved(rag_assisted, manual), "fcr_improvement": self._fcr_improvement(rag_assisted, manual) } }

Feedback Loop

DEVELOPERpython
class RAGFeedbackLoop: """ Collects and uses agent feedback. """ async def record_feedback( self, ticket_id: int, suggestion_id: str, action: str, # "used", "modified", "rejected" modification: str = None ): """ Records feedback on a suggestion. """ feedback = { "ticket_id": ticket_id, "suggestion_id": suggestion_id, "action": action, "modification": modification, "timestamp": datetime.utcnow() } await self.db.insert("rag_feedback", feedback) # If modified, learn from modification if action == "modified" and modification: await self._learn_from_modification(suggestion_id, modification) async def _learn_from_modification( self, suggestion_id: str, modification: str ): """ Improves RAG based on agent modifications. """ original = await self._get_original_suggestion(suggestion_id) # Analyze difference analysis = await self.analyze_modification( original=original["response"], modified=modification ) # If recurring pattern, create a rule if await self._is_recurring_pattern(analysis): await self._create_improvement_rule(analysis)

Integration with Ailog

Ailog simplifies Freshdesk integration:

DEVELOPERpython
from ailog import AilogClient client = AilogClient(api_key="your-key") # One-line configuration client.integrations.freshdesk.connect( domain="your-company", api_key="freshdesk-api-key", sync_solutions=True, enable_agent_assist=True, webhook_url="https://your-app.com/freshdesk/webhook" ) # Assistant is ready suggestions = client.support.suggest( ticket_id=12345, include_similar=True )

Conclusion

RAG + Freshdesk integration transforms both agent and customer experience. Intelligent suggestions reduce agent cognitive load while improving response quality and consistency. Start with Custom App deployment, measure adoption, then refine models with feedback.

Additional Resources


Ready to boost your Freshdesk agents? Try Ailog - Ready-to-use Custom App, AI suggestions in 5 minutes.

Tags

RAGFreshdeskcustomer supportAI assistantautomation

Related Posts

Ailog Assistant

Ici pour vous aider

Salut ! Pose-moi des questions sur Ailog et comment intégrer votre RAG dans vos projets !