-
Notifications
You must be signed in to change notification settings - Fork 134
feat: Implement Enhanced FAQ Handler with Web Search for Organization… #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9439cf9
33e2924
fb9f2a9
98a709d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,121 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import logging | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Dict, Any, List | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from app.agents.state import AgentState | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from langchain_core.messages import HumanMessage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from app.agents.devrel.prompts.organizational_faq_prompt import ORGANIZATIONAL_SYNTHESIS_PROMPT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger = logging.getLogger(__name__) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def handle_organizational_faq_node( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state: AgentState, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enhanced_faq_tool: Any, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| llm: Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Dict[str, Any]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Handle organizational FAQ requests with web search and LLM synthesis""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.info(f"Handling organizational FAQ for session {state.session_id}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| latest_message = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if state.messages: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| latest_message = state.messages[-1].get("content", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif state.context.get("original_message"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| latest_message = state.context["original_message"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get response from enhanced FAQ tool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| faq_response = await enhanced_faq_tool.get_response(latest_message) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If it's an organizational query, enhance with LLM synthesis | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if faq_response.get("type") == "organizational_faq": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| search_results = faq_response.get("sources", []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if search_results: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Format search results for LLM | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| formatted_results = _format_search_results_for_llm(search_results) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Use LLM to synthesize a better response | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| synthesis_prompt = ORGANIZATIONAL_SYNTHESIS_PROMPT.format( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| question=latest_message, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| search_results=formatted_results | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| llm_response = await llm.ainvoke([HumanMessage(content=synthesis_prompt)]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| synthesized_answer = llm_response.content.strip() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Update the response with the synthesized answer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| faq_response["response"] = synthesized_answer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| faq_response["synthesis_method"] = "llm_enhanced" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f"Enhanced organizational response with LLM synthesis " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f"for session {state.session_id}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except (ValueError, AttributeError, TypeError) as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.error(f"Error in LLM synthesis: {str(e)}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Keep the original response if LLM synthesis fails | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| faq_response["synthesis_method"] = "basic" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.error(f"Unexpected error in LLM synthesis: {str(e)}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| faq_response["synthesis_method"] = "basic" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "task_result": { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "type": "organizational_faq", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "response": faq_response.get("response"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "source": faq_response.get("source", "enhanced_faq"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "sources": faq_response.get("sources", []), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "search_queries": faq_response.get("search_queries", []), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "synthesis_method": faq_response.get("synthesis_method", "none"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "query_type": faq_response.get("type", "unknown") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "current_task": "organizational_faq_handled" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _format_search_results_for_llm(search_results: List[Dict[str, Any]]) -> str: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Format search results for LLM synthesis""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not search_results: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "No search results available." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| formatted_parts = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i, result in enumerate(search_results, 1): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title = result.get('title', 'No title') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url = result.get('url', 'No URL') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content = result.get('content', 'No content available') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| formatted_part = f""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Result {i}: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Title: {title} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| URL: {url} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Content: {content[:500]}{"..." if len(content) > 500 else ""} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| formatted_parts.append(formatted_part) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "\n".join(formatted_parts) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+73
to
+92
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add input validation for search results. The function should validate the structure of search results to prevent runtime errors. def _format_search_results_for_llm(search_results: List[Dict[str, Any]]) -> str:
"""Format search results for LLM synthesis"""
if not search_results:
return "No search results available."
+
+ if not isinstance(search_results, list):
+ logger.warning("Search results is not a list, returning empty message")
+ return "No search results available."
formatted_parts = []
for i, result in enumerate(search_results, 1):
+ if not isinstance(result, dict):
+ logger.warning(f"Invalid search result format at index {i-1}")
+ continue
+
title = result.get('title', 'No title')
url = result.get('url', 'No URL')
content = result.get('content', 'No content available')📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def create_organizational_response(task_result: Dict[str, Any]) -> str: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not very much sure on this too. This seems very much like aligning a separate function for a separate response, but I think the LLM can directly align the response. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Create a user-friendly response string from organizational FAQ results""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response = task_result.get("response", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sources = task_result.get("sources", []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| query_type = task_result.get("query_type", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not response: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ("I couldn't find specific information about that. Please try rephrasing your " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "question or check our official documentation.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Start with the main response | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response_parts = [response] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Add sources if available | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if sources: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response_parts.append("\n\n**Sources:**") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for i, source in enumerate(sources[:3], 1): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title = source.get('title', 'Source') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url = source.get('url', '') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response_parts.append(f"{i}. [{title}]({url})") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Add helpful footer for organizational queries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if query_type == "organizational_faq": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response_parts.append( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "\n\nFor more information, you can also visit our official website or GitHub repository." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "\n".join(response_parts) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # Prompts for organizational FAQ handling and synthesis | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These much of prompts are very much overhead. As of now, one query takes at max 4-5 calls for the model (with proper thinking, tool usage, results alignment, and whole workflow), and including all these would be very heavy on the API usage part. The interaction can go back and forth between two nodes (cycle) and does not need to be aligned in a flow-based way. |
||
|
|
||
| # Prompt for detecting organizational queries | ||
| ORGANIZATIONAL_QUERY_DETECTION_PROMPT = """You are an AI assistant that helps classify user questions. | ||
| Determine if the following question is asking about organizational information (about the company, | ||
| projects, mission, goals, etc.) or technical support. | ||
|
|
||
| User Question: "{question}" | ||
|
|
||
| Classification Guidelines: | ||
| - ORGANIZATIONAL: Questions about the company, its mission, projects, team, goals, platforms, | ||
| general information about what the organization does | ||
| - TECHNICAL: Questions about how to use the product, troubleshooting, implementation details, | ||
| contribution guidelines, specific feature requests | ||
|
|
||
| Examples of ORGANIZATIONAL questions: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are very much aligned with DevR. We want a generalized handler as this product will be used by an organization that will have multiple repos and not just DevR. |
||
| - "What is Devr.AI?" | ||
| - "What projects does this organization work on?" | ||
| - "What are the main goals of Devr.AI?" | ||
| - "What platforms does Devr.AI support?" | ||
| - "Tell me about this organization" | ||
|
|
||
| Examples of TECHNICAL questions: | ||
| - "How do I contribute to the project?" | ||
| - "How do I report a bug?" | ||
| - "What is LangGraph?" | ||
| - "How do I get started with development?" | ||
|
|
||
| Respond with only: ORGANIZATIONAL or TECHNICAL""" | ||
|
|
||
| # Prompt for generating targeted search queries for organizational information | ||
| ORGANIZATIONAL_SEARCH_QUERY_GENERATION_PROMPT = """You are an AI assistant that helps generate effective | ||
| search queries. Based on the user's organizational question, generate 2-3 specific search queries that | ||
| would find relevant information about Devr.AI. | ||
|
|
||
| User Question: "{question}" | ||
|
|
||
| Guidelines for search queries: | ||
| 1. Include "Devr.AI" in each query | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any clarifications on this? Why DevR need to be in each query? |
||
| 2. Focus on official sources (website, GitHub, documentation) | ||
| 3. Be specific to the type of information requested | ||
| 4. Avoid overly broad or generic terms | ||
|
|
||
| Generate search queries that would find information about: | ||
| - Official website content | ||
| - GitHub repositories and documentation | ||
| - Project descriptions and goals | ||
| - Platform integrations and capabilities | ||
|
|
||
| Format your response as a JSON list of strings: | ||
| ["query1", "query2", "query3"]""" | ||
|
|
||
| # Enhanced synthesis prompt for organizational responses | ||
| ORGANIZATIONAL_SYNTHESIS_PROMPT = """You are the official AI representative for Devr.AI. | ||
| Your task is to provide a comprehensive, accurate, and helpful answer to the user's question about | ||
| our organization based on the search results provided. | ||
|
|
||
| User Question: "{question}" | ||
|
|
||
| Search Results: | ||
| {search_results} | ||
|
|
||
| Instructions: | ||
| 1. **Accuracy First**: Only use information directly found in the search results | ||
| 2. **Comprehensive Coverage**: Address all aspects of the user's question if information is available | ||
| 3. **Professional Tone**: Maintain a friendly but professional tone appropriate for developer relations | ||
| 4. **Structured Response**: Organize information logically with clear sections if needed | ||
| 5. **Source Attribution**: If specific claims are made, they should be traceable to the search results | ||
| 6. **Acknowledge Limitations**: If search results don't contain enough information, be honest about it | ||
| 7. **Call to Action**: When appropriate, guide users to official resources for more information | ||
|
|
||
| Response Format: | ||
| - Start with a direct answer to the main question | ||
| - Provide supporting details from search results | ||
| - Include relevant examples or specifics when available | ||
| - End with helpful next steps or resources if appropriate | ||
|
|
||
| Avoid: | ||
| - Making up information not present in search results | ||
| - Being overly promotional or sales-like | ||
| - Providing outdated information | ||
| - Generic or vague responses | ||
|
|
||
| Response:""" | ||
|
|
||
| # Prompt for fallback responses when search results are insufficient | ||
| ORGANIZATIONAL_FALLBACK_PROMPT = """You are the AI representative for Devr.AI. The user asked an | ||
| organizational question, but the search results didn't provide sufficient information to answer | ||
| comprehensively. | ||
|
|
||
| User Question: "{question}" | ||
|
|
||
| Provide a helpful fallback response that: | ||
| 1. Acknowledges their question | ||
| 2. Provides any basic information you know about Devr.AI (AI-powered DevRel assistant) | ||
| 3. Directs them to official sources for complete information | ||
| 4. Maintains a helpful and professional tone | ||
|
|
||
| Keep the response concise but useful, and avoid making specific claims without evidence. | ||
|
|
||
| Response:""" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is any need for segregation of FAQ types as long as they get answered, right? I mean the node itself should be able to determine out on it's own whether this search result is enough for answering on not?