Recommendations are now generated by AI, changed format for key findings, risks names are now bold
This commit is contained in:
@@ -210,6 +210,61 @@ def get_controls_for_risk(risk, organization):
|
||||
if not remaining_controls:
|
||||
break
|
||||
return selected_controls if len(selected_controls) == 10 else []
|
||||
|
||||
|
||||
def generate_recommendations(risks_with_controls, organization):
|
||||
|
||||
client = OpenAI(api_key=settings.OPENAI_API_KEY)
|
||||
|
||||
organization_details = extract_organization_details(organization)
|
||||
|
||||
prompt = f"""
|
||||
You are an AI assistant tasked with generating the Recommendations section for a cybersecurity assessment report. Use the organization’s context and the list of risks with their proposed controls to produce concise, actionable, and prioritized guidance.
|
||||
|
||||
Inputs:
|
||||
- Organization details:
|
||||
{organization_details}
|
||||
|
||||
- Risks with controls (Python-like list of dicts). Each item includes:
|
||||
risk: id, name, category, risk_description (or similar)
|
||||
r_impact (inherent impact 1–5), r_likelihood (inherent likelihood 1–5), risk_score
|
||||
residual_impact, residual_likelihood, residual_risk_score (may be present)
|
||||
controls: list of controls, each with control__name, weight (1–5 effectiveness), likelihood (1–5 occurrence modifier)
|
||||
|
||||
Task:
|
||||
1) Compute a priority score per control = weight × likelihood. Aggregate scores across all risks and cluster into 3–5 thematic areas that best match the actual controls and risk names (e.g., Access Control & MFA, Patch & Vulnerability Management, Vendor/Third-Party Risk Management, Network Security & Segmentation, Logging/Monitoring/Detection, Incident Response & BCDR, Ransomware Prevention & Recovery, Cryptography & Key Management). Do not invent themes without support in the inputs.
|
||||
2) For each chosen theme, produce 3–5 concrete actions derived from the highest-priority controls. Tailor to the organization_details where appropriate. Prefer steps that reduce both likelihood and impact.
|
||||
3) Each bullet should be 1–2 sentences: start with a clear, imperative recommendation, and (optionally) add a brief explanation or context. Still keep it concise and actionable.
|
||||
4) Use only the control__name for reference—do NOT include or reference control IDs, years (e.g., 2024), or quarter references (Q1, Q2, Q3, Q4) anywhere in the output.
|
||||
5) Do not introduce controls that are not represented in the provided controls list.
|
||||
|
||||
Output format (STRICT):
|
||||
<2–3 sentence paragraph explaining that recommendations are prioritized by expected risk reduction based on the provided controls and aligned to the organization’s context.>
|
||||
|
||||
<h3>Theme Title</h3>
|
||||
- Bullet 1 (1–2 sentences, no IDs, years, or quarters)
|
||||
- Bullet 2
|
||||
- Bullet 3
|
||||
- Bullet 4 (optional)
|
||||
- Bullet 5 (optional)
|
||||
|
||||
Constraints:
|
||||
- 3–5 themed subsections, each with 3–5 bullets.
|
||||
- No preamble or postscript beyond the sections above.
|
||||
- Do NOT reference or display control IDs, years, or quarters in any form.
|
||||
|
||||
Now produce the final Recommendations section using the actual inputs above.
|
||||
Risks with controls:
|
||||
{risks_with_controls}
|
||||
"""
|
||||
|
||||
response = client.chat.completions.create(
|
||||
model="gpt-4o-mini",
|
||||
messages=[{"role": "system", "content": prompt}]
|
||||
)
|
||||
|
||||
recommendations = response.choices[0].message.content.strip()
|
||||
return recommendations
|
||||
|
||||
def generate_key_findings(document, top_10_risks):
|
||||
|
||||
@@ -254,11 +309,11 @@ def generate_key_findings(document, top_10_risks):
|
||||
The [Concise, professionally phrased description] part must be synthesized from the provided risk_description field (e.g., {{ item.risk_description }}) associated with that risk. Aim to create a polished, impactful summary that clearly explains the risk's context, severity, or contributing factors.
|
||||
|
||||
Return it as plain text in the following format:
|
||||
Example Output Format:
|
||||
Output Format(STRICT):
|
||||
Introduction
|
||||
- Risk 1: Brief description of Risk 1
|
||||
- Risk 2: Brief description of Risk 2
|
||||
- Risk 3: Brief description of Risk 3
|
||||
- <b> Risk 1 </b> : Brief description of Risk 1
|
||||
- <b> Risk 2 </b> : Brief description of Risk 2
|
||||
- <b> Risk 3 </b> : Brief description of Risk 3
|
||||
"""
|
||||
|
||||
response = client.chat.completions.create(
|
||||
|
||||
Reference in New Issue
Block a user