Spaces:
Runtime error
Runtime error
Support bulk analysis of TILs
Browse files- crew/til.py +51 -38
- test.py +10 -8
crew/til.py
CHANGED
|
@@ -3,6 +3,7 @@ from langchain_core.messages import SystemMessage
|
|
| 3 |
from pydantic import BaseModel, Field
|
| 4 |
from langchain_core.output_parsers import JsonOutputParser
|
| 5 |
from langchain_openai import ChatOpenAI
|
|
|
|
| 6 |
import pprint
|
| 7 |
|
| 8 |
HIGH_IMPACT_THRESHOLD = 8
|
|
@@ -16,59 +17,66 @@ class TilCrew:
|
|
| 16 |
return self._final_call_on_feedback()
|
| 17 |
|
| 18 |
def _final_call_on_feedback(self):
|
| 19 |
-
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
"feedback": "not_ok",
|
| 22 |
-
"feedback_criteria": "factuality_feedback",
|
| 23 |
-
"reason": self.feedback["factuality_reason"],
|
| 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 |
def _gather_feedback(self):
|
| 54 |
feedback_chain = self._build_feedback_chain()
|
| 55 |
pprint.pp("Analysing the TIL.....")
|
| 56 |
-
self.
|
| 57 |
print("Feedback: ")
|
| 58 |
-
pprint.pp(self.
|
| 59 |
|
| 60 |
def _build_feedback_chain(self):
|
| 61 |
-
feedback_parser = JsonOutputParser(pydantic_object=
|
| 62 |
feedback_prompt = ChatPromptTemplate.from_messages([
|
| 63 |
SystemMessage(
|
| 64 |
"You are a 'Personal TIL Reviewer' who works in an Product Engineering Services company, you responsibility is to guide the user to write better TILs. "
|
| 65 |
-
"Your personal goal is to review a user's
|
| 66 |
"1. Is the TIL insightful?"
|
| 67 |
-
"2. Is the TIL factually correct?"
|
| 68 |
"3. Is the TIL written in simple english?"
|
| 69 |
"4. Is the TIL grammatically correct?"
|
| 70 |
|
| 71 |
-
"Can you provide a score for on the scale of 10 for each of these criteria and provide reasons for the score, the reason should be presented in the POV of the Personal TIL Reviewer."
|
| 72 |
f"Formatting Instructions: {feedback_parser.get_format_instructions()}"
|
| 73 |
),
|
| 74 |
HumanMessagePromptTemplate.from_template("{til_content}")
|
|
@@ -82,17 +90,22 @@ class TilCrew:
|
|
| 82 |
|
| 83 |
|
| 84 |
class TilFeedbackResult(BaseModel):
|
|
|
|
| 85 |
insightful_score: int = Field(
|
| 86 |
description="TIL score on insightful criteria")
|
| 87 |
-
insightful_reason: str = Field(description="Reason for insightful_score")
|
| 88 |
factuality_score: int = Field(
|
| 89 |
-
description="TIL score on factuality criteria")
|
| 90 |
-
factuality_reason: str = Field(description="Reason for factuality_score")
|
| 91 |
simplicity_score: int = Field(
|
| 92 |
description="TIL score on simplicity criteria")
|
| 93 |
-
simplicity_reason: str = Field(description="Reason for simplicity_score")
|
| 94 |
grammatical_score: int = Field(
|
| 95 |
description="TIL score on grammatical criteria")
|
| 96 |
-
grammatical_reason: str = Field(description="Reason for grammatical_score")
|
| 97 |
final_suggestion: str = Field(
|
| 98 |
description="Final suggested version of the TIL")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
from pydantic import BaseModel, Field
|
| 4 |
from langchain_core.output_parsers import JsonOutputParser
|
| 5 |
from langchain_openai import ChatOpenAI
|
| 6 |
+
from typing import List
|
| 7 |
import pprint
|
| 8 |
|
| 9 |
HIGH_IMPACT_THRESHOLD = 8
|
|
|
|
| 17 |
return self._final_call_on_feedback()
|
| 18 |
|
| 19 |
def _final_call_on_feedback(self):
|
| 20 |
+
final_results = []
|
| 21 |
+
for feedback in self.feedback_results:
|
| 22 |
+
print("Final analysis of:")
|
| 23 |
+
pprint.pp(feedback)
|
| 24 |
+
result = {
|
| 25 |
+
"til": feedback.get('til', ""),
|
| 26 |
"feedback": "not_ok",
|
|
|
|
|
|
|
| 27 |
}
|
| 28 |
+
if feedback["factuality_score"] < HIGH_IMPACT_THRESHOLD:
|
| 29 |
+
result["feedback_criteria"] = "factuality_feedback"
|
| 30 |
+
result["reason"] = feedback["factuality_reason"]
|
| 31 |
+
final_results = final_results + [result]
|
| 32 |
+
continue
|
| 33 |
|
| 34 |
+
if feedback["insightful_score"] < HIGH_IMPACT_THRESHOLD:
|
| 35 |
+
result["feedback_criteria"] = "insightful_feedback"
|
| 36 |
+
result["reason"] = feedback["insightful_reason"]
|
| 37 |
+
final_results = final_results + [result]
|
| 38 |
+
continue
|
|
|
|
| 39 |
|
| 40 |
+
if feedback["simplicity_score"] < LOW_IMPACT_THRESHOLD:
|
| 41 |
+
result["feedback_criteria"] = "simplicity_feedback"
|
| 42 |
+
result["reason"] = feedback["simplicity_reason"]
|
| 43 |
+
result["suggestion"] = feedback["final_suggestion"]
|
| 44 |
+
final_results = final_results + [result]
|
| 45 |
+
continue
|
|
|
|
| 46 |
|
| 47 |
+
if feedback["grammatical_score"] < LOW_IMPACT_THRESHOLD:
|
| 48 |
+
result["feedback_criteria"] = "grammatical_feedback"
|
| 49 |
+
result["reason"] = feedback["grammatical_reason"]
|
| 50 |
+
result["suggestion"] = feedback["final_suggestion"]
|
| 51 |
+
final_results = final_results + [result]
|
| 52 |
+
continue
|
| 53 |
+
|
| 54 |
+
result["feedback"] = "ok"
|
| 55 |
+
final_results = final_results + [result]
|
| 56 |
|
| 57 |
+
print("Final Results:")
|
| 58 |
+
pprint.pp(final_results)
|
| 59 |
+
return final_results
|
| 60 |
|
| 61 |
def _gather_feedback(self):
|
| 62 |
feedback_chain = self._build_feedback_chain()
|
| 63 |
pprint.pp("Analysing the TIL.....")
|
| 64 |
+
self.feedback_results = feedback_chain.invoke({"til_content": self.content})['tils']
|
| 65 |
print("Feedback: ")
|
| 66 |
+
pprint.pp(self.feedback_results)
|
| 67 |
|
| 68 |
def _build_feedback_chain(self):
|
| 69 |
+
feedback_parser = JsonOutputParser(pydantic_object=TilFeedbackResults)
|
| 70 |
feedback_prompt = ChatPromptTemplate.from_messages([
|
| 71 |
SystemMessage(
|
| 72 |
"You are a 'Personal TIL Reviewer' who works in an Product Engineering Services company, you responsibility is to guide the user to write better TILs. "
|
| 73 |
+
"Your personal goal is to review a user's list of TILs and suggeste edits based on the following criteria:\n"
|
| 74 |
"1. Is the TIL insightful?"
|
| 75 |
+
"2. Is the TIL factually correct and accurate?"
|
| 76 |
"3. Is the TIL written in simple english?"
|
| 77 |
"4. Is the TIL grammatically correct?"
|
| 78 |
|
| 79 |
+
"Can you provide a score for on the scale of 10 for each of the TIL on each of these criteria and provide reasons for the score, the reason should be presented in the POV of the Personal TIL Reviewer."
|
| 80 |
f"Formatting Instructions: {feedback_parser.get_format_instructions()}"
|
| 81 |
),
|
| 82 |
HumanMessagePromptTemplate.from_template("{til_content}")
|
|
|
|
| 90 |
|
| 91 |
|
| 92 |
class TilFeedbackResult(BaseModel):
|
| 93 |
+
til: str = Field(description="TIL content the user has provided on which we are performing the analysis.")
|
| 94 |
insightful_score: int = Field(
|
| 95 |
description="TIL score on insightful criteria")
|
| 96 |
+
insightful_reason: str = Field(description="Reason for low insightful_score if it is not 10")
|
| 97 |
factuality_score: int = Field(
|
| 98 |
+
description="TIL score on factuality criteria and correctness of the statement")
|
| 99 |
+
factuality_reason: str = Field(description="Reason for low factuality_score if it is not 10")
|
| 100 |
simplicity_score: int = Field(
|
| 101 |
description="TIL score on simplicity criteria")
|
| 102 |
+
simplicity_reason: str = Field(description="Reason for low simplicity_score if it is not 10")
|
| 103 |
grammatical_score: int = Field(
|
| 104 |
description="TIL score on grammatical criteria")
|
| 105 |
+
grammatical_reason: str = Field(description="Reason for low grammatical_score if it is not 10")
|
| 106 |
final_suggestion: str = Field(
|
| 107 |
description="Final suggested version of the TIL")
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
class TilFeedbackResults(BaseModel):
|
| 111 |
+
tils: List[TilFeedbackResult]
|
test.py
CHANGED
|
@@ -21,7 +21,7 @@ def main():
|
|
| 21 |
""",
|
| 22 |
unsafe_allow_html=True
|
| 23 |
)
|
| 24 |
-
til_content = st.
|
| 25 |
|
| 26 |
if st.button("Get Feedback"):
|
| 27 |
with st.status(
|
|
@@ -32,19 +32,21 @@ def main():
|
|
| 32 |
with stdout(log_container.code, terminator=""):
|
| 33 |
feedback = TilCrew()
|
| 34 |
inputs = {"content": til_content}
|
| 35 |
-
|
| 36 |
status.update(
|
| 37 |
label="✅ Feedback ready!",
|
| 38 |
state="complete",
|
| 39 |
expanded=False,
|
| 40 |
)
|
| 41 |
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
st.markdown(f"**
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
st.markdown(f"**
|
|
|
|
|
|
|
| 48 |
|
| 49 |
if __name__ == "__main__":
|
| 50 |
main()
|
|
|
|
| 21 |
""",
|
| 22 |
unsafe_allow_html=True
|
| 23 |
)
|
| 24 |
+
til_content = st.text_area('Enter what you learnt today:', 'Upon delving into the intricacies of Docker, I have acquired the capability to encapsulate our application within containers, thereby streamlining the deployment process across a multitude of heterogeneous environments.', key='til_content', help='Enter what you learnt today')
|
| 25 |
|
| 26 |
if st.button("Get Feedback"):
|
| 27 |
with st.status(
|
|
|
|
| 32 |
with stdout(log_container.code, terminator=""):
|
| 33 |
feedback = TilCrew()
|
| 34 |
inputs = {"content": til_content}
|
| 35 |
+
results = feedback.kickoff(inputs=inputs)
|
| 36 |
status.update(
|
| 37 |
label="✅ Feedback ready!",
|
| 38 |
state="complete",
|
| 39 |
expanded=False,
|
| 40 |
)
|
| 41 |
|
| 42 |
+
for result in results:
|
| 43 |
+
st.markdown(f"#### TIL: {result['til']}")
|
| 44 |
+
st.markdown(f"**Feedback:** {result['feedback']}")
|
| 45 |
+
if result['feedback'] == "not_ok":
|
| 46 |
+
st.markdown(f"**Criteria:** {result['feedback_criteria']}")
|
| 47 |
+
st.markdown(f"**Reason:** {result['reason']}")
|
| 48 |
+
if result.get('suggestion') is not None:
|
| 49 |
+
st.markdown(f"**Suggestion:** {result['suggestion']}")
|
| 50 |
|
| 51 |
if __name__ == "__main__":
|
| 52 |
main()
|