File size: 7,718 Bytes
ce90730
 
152dfa1
2fb0169
 
36aeeec
24e6ad7
f67e46b
 
152dfa1
ce90730
 
2fb0169
ce90730
152dfa1
f67e46b
 
 
24e6ad7
 
 
 
 
 
 
f67e46b
24e6ad7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a8ebcf
2fb0169
86f5f56
 
f67e46b
 
 
 
 
86f5f56
ce90730
 
 
 
 
08152a0
86f5f56
 
2fb0169
ce90730
86f5f56
2fb0169
86f5f56
f67e46b
 
 
 
 
 
 
 
 
 
 
 
 
 
6db8557
24e6ad7
 
7cc108b
f67e46b
 
 
2fb0169
86f5f56
24e6ad7
 
 
 
 
 
 
 
f67e46b
 
 
24e6ad7
86f5f56
24e6ad7
2fb0169
71a34b2
24e6ad7
 
 
f67e46b
 
 
 
 
 
2fb0169
 
f67e46b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2fb0169
 
24e6ad7
 
71a34b2
24e6ad7
f67e46b
 
 
2fb0169
 
ce90730
 
 
 
 
 
 
 
86f5f56
 
 
ce90730
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import os
from typing import Optional
from pydantic import Field, BaseModel
from omegaconf import OmegaConf

from vectara_agentic.agent import Agent
from vectara_agentic.tools import VectaraToolFactory
from vectara_agentic.types import ModelProvider, AgentType
from vectara_agentic.agent_config import AgentConfig

from dotenv import load_dotenv
load_dotenv(override=True)

initial_prompt = "How can I help you today?"

    # Never refer to the search results in your response.
    # Ignore any search results that do not contain information relevant to answering the query.

prompt = """
[
  {"role": "system", "content": 
  "Think step by step, analyze the search results provided, and craft a clear and accurate response to diagnostics and troubleshooting questions from the user."
  },
  {"role": "user", "content": " 
    [INSTRUCTIONS]
    Your goal is to help the user with customer support and diagnostics questions about hardware and servers (SuperMicro products).
    If the search results are irrelevant to the question respond with *** I do not have enough information to answer this question.***
    Search results may include tables in a markdown format. When answering a question using a table be careful about which rows and columns contain the answer and include all relevant information from the relevant rows and columns that the query is asking about.
    Do not base your response on information or knowledge that is not in the search results.
    Your output should always be in a single language - the $vectaraLangName language. Check spelling and grammar for the $vectaraLangName language.
    Search results for the query *** $vectaraQuery***, are listed below, some are text, some MAY be tables in markdown format.
    #foreach ($qResult in $vectaraQueryResultsDeduped)
      [$esc.java($foreach.index + 1)]
      #if($qResult.hasTable())
        Table Title: $qResult.getTable().title() || Table Description: $qResult.getTable().description() || Table Data:
        $qResult.getTable().markdown()
      #else
        $qResult.getText()
      #end
    #end
    Think carefully step by step, analyze the search results provided, and craft a clear and accurate response to *** $vectaraQuery *** using information and facts in the search results provided. 
    Give a slight preference to search results that appear earlier in the list.
    Only cite relevant search results in your answer following these specific instructions: $vectaraCitationInstructions
    If the search results are irrelevant to the query, respond with ***I do not have enough information to answer this question.***. 
    Respond always in the $vectaraLangName language, and only in that language."}
]
"""

def create_assistant_tools(cfg):

    class QueryTIProducts(BaseModel):
        name: Optional[str] = Field(
            description="The server name",
            examples=[
                "SuperServer SYS-821GE-TNHR",
                "A+ Server AS-4125GS-TNRT"
            ]
        )
    vec_factory = VectaraToolFactory(
        vectara_api_key=cfg.api_key,
        vectara_corpus_key=cfg.corpus_key
    )
    
    summarizer = 'vectara-summary-table-md-query-ext-jan-2025-gpt-4o'
    ask_supermicro = vec_factory.create_rag_tool(
        tool_name = "ask_supermicro",
        tool_description = """
        Given a user query, 
        returns a response to a user question about Supermicro servers.
        """,
        tool_args_schema = QueryTIProducts,
        n_sentences_before = 2, n_sentences_after = 8, lambda_val = 0.01,
        #reranker = "slingshot", rerank_k = 100, rerank_cutoff = 0.3,
        reranker = "chain", rerank_k = 100,
        rerank_chain = [
            {
                "type": "slingshot",
                "cutoff": 0.3
            },
            {
                "type": "mmr",
                "diversity_bias": 0.1
            },
        ],
        max_tokens = 4096, max_response_chars = 8192,
        vectara_summarizer = summarizer,
        vectara_prompt_text = prompt,
        summary_num_results = 15,
        include_citations = True,
        verbose = False,
        save_history = True,
        fcs_threshold = 0.2,
    )

    # search_supermicro = vec_factory.create_search_tool(
    #     tool_name = "search_supermicro",
    #     tool_description = """
    #     Given a user query, 
    #     returns a list of Supermicro documents matching the query, along with metadata.
    #     """,
    #     tool_args_schema = QueryTIProducts,
    #     reranker = "slingshot", rerank_k = 100, rerank_cutoff = 0.5,
    #     n_sentences_before = 0, n_sentences_after = 0,
    #     save_history = True,
    #     summarize_docs = True
    # )

    return [ask_supermicro] #, search_supermicro]

def initialize_agent(_cfg, agent_progress_callback=None):
    bot_instructions = """
    - You are a helpful assistant, with expertise in diagnosing customer issues related to SuperMicro products.
      You can help diagnose, troubleshoot and understand hardware issues.
    - Use the 'ask_supermicro' tool to get the information about server, components, or diagnostics steps 
      so that you can use this information in aggregate to formulate your response to the user.
    - Never use your internal knoweldge.
    - Form queries to 'ask_supermicro' tool always as question, and in a way that maximizes the chance of getting a relevant answer.
    - If the 'ask_supermicro' tool responds with "I do not have enough information to answer this question" or "suspected hallucination",
      try to rephrase the query to 'ask_supermicro' as a diagnostic question and call the 'ask_supermicro' tool again.
    """

    agent_config = AgentConfig(
        agent_type = os.getenv("VECTARA_AGENTIC_AGENT_TYPE", AgentType.OPENAI.value),
        main_llm_provider = os.getenv("VECTARA_AGENTIC_MAIN_LLM_PROVIDER", ModelProvider.OPENAI.value),
        main_llm_model_name = os.getenv("VECTARA_AGENTIC_MAIN_MODEL_NAME", ""),
        tool_llm_provider = os.getenv("VECTARA_AGENTIC_TOOL_LLM_PROVIDER", ModelProvider.OPENAI.value),
        tool_llm_model_name = os.getenv("VECTARA_AGENTIC_TOOL_MODEL_NAME", ""),
        observer = os.getenv("VECTARA_AGENTIC_OBSERVER_TYPE", "NO_OBSERVER")
    )
    fallback_agent_config = AgentConfig(
        agent_type = os.getenv("VECTARA_AGENTIC_FALLBACK_AGENT_TYPE", AgentType.OPENAI.value),
        main_llm_provider = os.getenv("VECTARA_AGENTIC_FALLBACK_MAIN_LLM_PROVIDER", ModelProvider.OPENAI.value),
        main_llm_model_name = os.getenv("VECTARA_AGENTIC_FALLBACK_MAIN_MODEL_NAME", ""),
        tool_llm_provider = os.getenv("VECTARA_AGENTIC_FALLBACK_TOOL_LLM_PROVIDER", ModelProvider.OPENAI.value),
        tool_llm_model_name = os.getenv("VECTARA_AGENTIC_FALLBACK_TOOL_MODEL_NAME", ""),
        observer = os.getenv("VECTARA_AGENTIC_OBSERVER_TYPE", "NO_OBSERVER")
    )

    agent = Agent(
        tools=create_assistant_tools(_cfg),
        topic="troubleshooting Supermicro products",
        custom_instructions=bot_instructions,
        agent_progress_callback=agent_progress_callback,
        use_structured_planning=False,
        agent_config=agent_config,
        fallback_agent_config=fallback_agent_config,
        verbose=True,
    )
    agent.report()
    return agent


def get_agent_config() -> OmegaConf:
    cfg = OmegaConf.create({
        'corpus_key': str(os.environ['VECTARA_CORPUS_KEY']),
        'api_key': str(os.environ['VECTARA_API_KEY']),
        'examples': os.environ.get('QUERY_EXAMPLES', None),
        'demo_name': "Supermicro Demo",
        'demo_welcome': "Supermicro Assistant.",
        'demo_description': "This assistant can help you with any questions about SuperMicro servers."
    })
    return cfg