- Minor changes to the SPIN_SPECIALIST

This commit is contained in:
Josako
2025-02-20 11:35:14 +01:00
parent 25213f2004
commit c037d4135e
7 changed files with 54 additions and 27 deletions

View File

@@ -4,13 +4,15 @@ task_description: >
You are asked to gather lead information in a conversation with a new prospect. This is information about the person
participating in the conversation, and information on the company he or she is working for. Try to be as precise as
possible.
Take into account information already gathered in the history (between triple backquotes) and add information found in
the latest reply.
Take into account information already gathered in the historic lead info (between triple backquotes) and add
information found in the latest reply. Also, some identification information may be given by the end user.
history:
```{history}```
historic lead info:
```{historic_lead_info}```
latest reply:
{query}
identification:
{identification}
{custom_description}
expected_output: >

View File

@@ -1,11 +1,11 @@
version: "1.0.0"
name: "Define Identification Questions"
task_description: >
Gather the identification information gathered by your team mates , take into account the history (in between triple
backquotes) of the conversation, and the latest reply of the user.
Gather the identification information gathered by your team mates. Ensure no information in the historic lead
information (in between triple backquotes) and the latest reply of the user is lost.
Define questions to be asked to complete the personal and company information for the end user in the conversation.
history:
```{history}```
historic lead info:
```{historic_lead_info}```
latest reply:
{query}

View File

@@ -2,10 +2,11 @@ version: "1.0.0"
name: "Rag Consolidation"
task_description: >
Your teams have collected answers to a user's query (in between triple backquotes), and collected additional follow-up
questions (in between triple %) to reach their goals. Ensure the answers are provided, and select the additional
questions to be asked in order not to overwhelm the user. Make a selection of maximum {nr_of_questions} questions to
be returned to the user. You ensure both answers and additional questions are bundled into 1 clear communication back
to the user. Use {language} for your consolidated communication.
questions (in between triple %) to reach their goals. Ensure the answers are provided, and select a maximum of
{nr_of_questions} out of the additional questions to be asked in order not to overwhelm the user. The questions are
in no specific order, so don't just pick the first ones, but the ones most appropriate in your opinion!
Questions are to be asked when your team proposes questions. You ensure both answers and additional questions are
bundled into 1 clear communication back to the user. Use {language} for your consolidated communication.
{custom_description}
Anwers:

View File

@@ -1,13 +1,12 @@
version: "1.0.0"
name: "SPIN Information Detection"
task_description: >
Detect the SPIN-context, taking into account the history of the discussion (in between triple backquotes) with main focus on
the latest reply (which can contain answers on previously asked questions by the user). Spin elements may already be
provided in the history. Add or refine these with the new input provided in the latest reply of the end user.
Complement the historic SPIN context (in between triple backquotes) with information found in the latest reply of the
end user.
{custom_description}
Use the following {tenant_language} to define the SPIN-elements.
History:
```{history}```
Historic SPIN:
```{historic_spin}```
Latest reply:
{query}
expected_output: >
@@ -16,8 +15,8 @@ expected_output: >
- Problem information: a description of the customer's problems uncovering it's challenges and pain points.
- Implication information: implications of situation / identified problems, i.e. of the consequences of those problems.
- Need-payoff information: Customer's needs, helping customers realize value of solutions.
- Additional info: Information that does not fit in the above SPIN-categories, but that can be commercially interesting.
{custom_expected_output}
- Additional info: Information that does not fit in the above SPIN-categories, but that can be commercially
interesting, including if provided: {custom_expected_output}
metadata:
author: "Josako"
date_added: "2025-01-08"

View File

@@ -1,14 +1,14 @@
version: "1.0.0"
name: "SPIN Question Identification"
task_description: >
Define, taking into account the history of the discussion (in between triple backquotes) and the latest reply and the
currently known SPIN-elements, the top questions that need to be asked to understand the full SPIN context
Revise the final SPIN provided by your colleague, and ensure no information is lost from the histoic SPIN and the
latest reply from the user. Define the top questions that need to be asked to understand the full SPIN context
of the customer. If you think this user could be a potential customer, please indicate so.
{custom_description}
Use the following {tenant_language} to define the SPIN-elements. If you have a full SPIN context, just skip and don't
ask for more information or confirmation.
History:
```{history}```
Use the following {tenant_language} to define the SPIN-elements. If you have a satisfying SPIN context, just skip and
don't ask for more information or confirmation.
Historic SPIN:
```{historic_spin}```
Latest reply:
{query}
expected_output: >

View File

@@ -126,7 +126,9 @@ class SpecialistExecutor(CrewAIBaseSpecialistExecutor):
"query": arguments.query,
"context": formatted_context,
"citations": citations,
"history": self._formatted_history,
"history": self.formatted_history,
"historic_spin": json.dumps(self.latest_spin, indent=2),
"historic_lead_info": json.dumps(self.latest_lead_info, indent=2),
"name": self.specialist.configuration.get('name', ''),
"company": self.specialist.configuration.get('company', ''),
"products": self.specialist.configuration.get('products', ''),
@@ -134,6 +136,7 @@ class SpecialistExecutor(CrewAIBaseSpecialistExecutor):
"engagement_options": self.specialist.configuration.get('engagement_options', ''),
"tenant_language": self.specialist.configuration.get('tenant_language', ''),
"nr_of_questions": self.specialist.configuration.get('nr_of_questions', ''),
"identification": arguments.identification,
}
# crew_results = self.rag_crew.kickoff(inputs=flow_inputs)
# current_app.logger.debug(f"Test Crew Output received: {crew_results}")
@@ -167,6 +170,8 @@ class SPINSpecialistInput(BaseModel):
context: Optional[str] = Field(None, alias="context")
citations: Optional[List[int]] = Field(None, alias="citations")
history: Optional[str] = Field(None, alias="history")
historic_spin: Optional[str] = Field(None, alias="historic_spin")
historic_lead_info: Optional[str] = Field(None, alias="historic_lead_info")
name: Optional[str] = Field(None, alias="name")
company: Optional[str] = Field(None, alias="company")
products: Optional[str] = Field(None, alias="products")
@@ -174,6 +179,7 @@ class SPINSpecialistInput(BaseModel):
engagement_options: Optional[str] = Field(None, alias="engagement_options")
tenant_language: Optional[str] = Field(None, alias="tenant_language")
nr_of_questions: Optional[int] = Field(None, alias="nr_of_questions")
identification: Optional[str] = Field(None, alias="identification")
class SPINSpecialistResult(SpecialistResult):
@@ -266,6 +272,7 @@ class SPINFlow(EveAICrewAIFlow[SPINFlowState]):
additional_questions = self.state.lead_info.questions + "\n"
if self.state.spin:
additional_questions = additional_questions + self.state.spin.questions
current_app.logger.debug(f"Additional Questions: {additional_questions}")
inputs["additional_questions"] = additional_questions
try:
crew_output = self.rag_consolidation_crew.kickoff(inputs=inputs)

View File

@@ -71,6 +71,14 @@ class CrewAIBaseSpecialistExecutor(BaseSpecialistExecutor):
for interaction in self._cached_session.interactions
])
@property
def formatted_history(self) -> str:
formatted_history = "\n\n".join([
f"HUMAN:\n{interaction.specialist_results.get('query')}\n\n"
f"AI:\n{interaction.specialist_results.get('rag_output').get('answer', '')}"
for interaction in self._cached_session.interactions
])
def _add_task_agent(self, task_name: str, agent_name: str):
self._task_agents[task_name.lower()] = agent_name
@@ -155,7 +163,10 @@ class CrewAIBaseSpecialistExecutor(BaseSpecialistExecutor):
pass
def __getattr__(self, name: str) -> Any:
"""Enable dynamic access to agents as attributes"""
"""
- Enable dynamic access to agents, tasks or tools as attributes
- Enable dynamic access to latest information in interactions in the cached session
"""
try:
if name.endswith('_agent'):
return self._agents[name]
@@ -166,6 +177,13 @@ class CrewAIBaseSpecialistExecutor(BaseSpecialistExecutor):
if name.endswith('_tool'):
return self._tools[name]
if name.startswith('latest_'):
element = name[len('latest_'):]
if self._cached_session.interactions:
return self._cached_session.interactions[-1].get(element, '')
else:
return {}
# Not a known component request
raise AttributeError(f"'{self.__class__.__name__}' has no attribute '{name}'")
except KeyError: