Generering av strukturerade rapporter
Mallbaserade rapporter: sammanfattning för ledningen, resultat, belägg och rekommendationer.
Generering av strukturerade rapporter är en gratis lektion i AI-agenter på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för AI-agenter, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i AI-agenter innehåller totalt 4 lektioner.
Från fakta till en lättläst rapport
En research-agent som bara matar ut en lista med fakta är svår att använda. Beslutsfattare behöver strukturerade rapporter: en sammanfattning för ledningen, ett bakgrundsavsnitt, viktiga resultat, belägg och rekommendationer.
Den här lektionen behandlar hur professionella rapporter genereras av verifierade fakta, avsnitt för avsnitt.
Rapportmallen
Definiera rapportstrukturen från början. LLM syntetiserar ett avsnitt i taget, håller varje avsnitt fokuserat och undviker upprepningar.
REPORT_SECTIONS = [
'executive_summary',
'background',
'key_findings',
'evidence',
'recommendations',
'sources'
]
SECTION_PROMPTS = {
'executive_summary': 'Write a 2-3 sentence executive summary of the key findings. Business audience.',
'background': 'Provide background context for the research topic (3-5 sentences).',
'key_findings': 'List 3-5 key findings as bullet points, each with one supporting fact.',
'evidence': 'Summarize the evidence for each finding with inline source citations.',
'recommendations': 'Based on the findings, provide 2-4 actionable recommendations.',
'sources': 'List all sources cited in the report, formatted as numbered URLs.'
}
if __name__ == '__main__':
print('Report sections:', REPORT_SECTIONS)
for section in REPORT_SECTIONS:
print(f'{section}: {SECTION_PROMPTS[section]}')
Generera ett avsnitt i taget
Att generera hela rapporten i en enda prompt är opålitligt — LLM tappar överblicken över fakta och struktur. Generera rapporten avsnitt för avsnitt och skicka tidigare avsnitt som kontext.
import openai
client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')
def generate_section(section_name: str, question: str,
facts: list[dict], prior_sections: dict) -> str:
facts_text = '\n'.join(
f'- {f["fact"]} (source: {f["source"]})' for f in facts[:25]
)
prior_text = '\n\n'.join(
f'## {k.replace("_"," ").title()}\n{v}'
for k, v in prior_sections.items()
)
prompt = (
f'Research question: "{question}"\n\n'
f'Verified facts:\n{facts_text}\n\n'
f'Report so far:\n{prior_text}\n\n'
f'Now write the "{section_name}" section.\n'
f'Instructions: {SECTION_PROMPTS[section_name]}'
)
resp = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.contentBygga rapporten iterativt
Iterera genom alla avsnitt och skicka med den ackumulerade kontexten. Varje avsnitt känner till det som kom före, vilket säkerställer sammanhang och förhindrar motsägelser i rapporten.
def build_report(question: str, facts: list[dict]) -> dict:
report = {}
sections_to_generate = [s for s in REPORT_SECTIONS if s != 'sources']
for section in sections_to_generate:
print(f'Generating section: {section}...')
report[section] = generate_section(
section_name=section,
question=question,
facts=facts,
prior_sections={k: v for k, v in report.items()}
)
# Sources section: generate citation list from fact URLs
unique_sources = list(dict.fromkeys(f['source'] for f in facts))
report['sources'] = '\n'.join(
f'{i+1}. {url}' for i, url in enumerate(unique_sources[:20])
)
return reportInfoga inline-citeringar
Ersätt faktareferenser i de genererade avsnitten med numrerade citeringar som länkar tillbaka till källistan. Då blir varje påstående spårbart.
import re
def inject_citations(section_text: str, facts: list[dict]) -> str:
source_index = {} # url -> int
for i, fact in enumerate(facts):
url = fact['source']
if url not in source_index:
source_index[url] = len(source_index) + 1
annotated = section_text
for fact in facts:
if fact['fact'] in annotated:
num = source_index[fact['source']]
annotated = annotated.replace(
fact['fact'],
f'{fact["fact"]} [{num}]',
1 # replace first occurrence only
)
return annotated
if __name__ == '__main__':
demo_text = 'Revenue grew 12% last quarter. The team also launched two new products.'
demo_facts = [{'fact': 'Revenue grew 12% last quarter', 'source': 'https://example.com/report'}]
print(inject_citations(demo_text, demo_facts))
Formatera som Markdown
Rendera rapportavsnitten som Markdown. Då kan resultatet konverteras till HTML eller PDF, eller visas direkt i verktyg som Notion eller Confluence.
def render_markdown(report: dict, title: str) -> str:
section_titles = {
'executive_summary': 'Executive Summary',
'background': 'Background',
'key_findings': 'Key Findings',
'evidence': 'Evidence',
'recommendations': 'Recommendations',
'sources': 'Sources'
}
lines = [f'# {title}', '']
for key in REPORT_SECTIONS:
if key in report:
lines.append(f'## {section_titles[key]}')
lines.append('')
lines.append(report[key])
lines.append('')
return '\n'.join(lines)
# Usage:
# md = render_markdown(report, 'Causes of Inflation in 2024')
# with open('report.md', 'w') as f: f.write(md)Generera en rapport med källänkar
Konvertera käll-URL:er till hyperlänkar när rapporten renderas för webben. Lägg även till ett metadata-block med rapportens genereringsdatum, antalet källor och verifieringsgraden.
from datetime import date
def render_html_report(report: dict, title: str,
facts: list[dict], question: str) -> str:
meta = (
f'<p><em>Generated: {date.today()} | '
f'Sources: {len(set(f["source"] for f in facts))} | '
f'Research question: {question}</em></p>'
)
html_parts = [f'<h1>{title}</h1>', meta]
section_titles = {
'executive_summary': 'Executive Summary',
'background': 'Background',
'key_findings': 'Key Findings',
'evidence': 'Evidence',
'recommendations': 'Recommendations',
'sources': 'Sources'
}
for key in REPORT_SECTIONS:
if key in report:
content = report[key].replace('\n', '<br>')
html_parts.append(f'<h2>{section_titles[key]}</h2><p>{content}</p>')
return '\n'.join(html_parts)Kvalitetskontroller före publicering
Kör automatiserade kvalitetskontroller innan rapporten levereras: minsta ordantal per avsnitt, minst N citeringar, att alla rekommendationer är handlingsverb och att ingen platshållartext som ”[INSERT]” förekommer.
def quality_check(report: dict) -> list[str]:
issues = []
for section in ['executive_summary', 'background', 'key_findings']:
word_count = len(report.get(section, '').split())
if word_count < 30:
issues.append(f'{section} too short: {word_count} words (min 30)')
if report.get('sources', '').count('http') < 3:
issues.append('Less than 3 cited sources')
if '[INSERT]' in str(report) or 'TODO' in str(report):
issues.append('Report contains placeholder text')
recs = report.get('recommendations', '')
if recs and not any(verb in recs.lower()
for verb in ['should', 'recommend', 'consider', 'implement']):
issues.append('Recommendations may not be actionable')
return issues
if __name__ == '__main__':
demo_report = {
'executive_summary': 'Too short.',
'background': 'Also short.',
'key_findings': 'Short too.',
'sources': 'http://a.com',
'recommendations': 'Looks fine as is.',
}
for issue in quality_check(demo_report):
print('-', issue)
Sammanfattning för ledningen: strikta begränsningar
Sammanfattningen för ledningen ska vara självständig: någon som bara läser detta avsnitt ska förstå det viktigaste resultatet och den rekommenderade åtgärden. Använd en strikt prompt med en ordgräns.
def generate_executive_summary(question: str, facts: list[dict],
max_words: int = 80) -> str:
top_facts = '\n'.join(f'- {f["fact"]}' for f in facts[:10])
prompt = (
f'Research question: "{question}"\n\n'
f'Key facts:\n{top_facts}\n\n'
f'Write an executive summary in EXACTLY {max_words} words or fewer.\n'
f'Format: [Main finding]. [Why it matters]. [Recommended action].'
)
resp = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.contentRapporter för flera målgrupper
Samma research kan behöva olika rapportstilar för olika målgrupper: en teknisk djupdykning för ingenjörer, en sammanfattning för ledningen eller en lättbegriplig översikt för icke-specialister. Generera varje variant utifrån samma uppsättning fakta.
AUDIENCE_STYLES = {
'executive': 'Brief, strategic. Avoid jargon. Focus on business impact and decisions.',
'technical': 'Detailed, precise. Include methodology, caveats, and data sources.',
'general': 'Plain language. Avoid technical terms. Use analogies where helpful.'
}
def generate_for_audience(facts: list[dict], question: str, audience: str) -> str:
style = AUDIENCE_STYLES.get(audience, AUDIENCE_STYLES['general'])
facts_text = '\n'.join(f'- {f["fact"]}' for f in facts[:20])
prompt = (
f'Synthesize these facts into a report for a {audience} audience.\n'
f'Style guide: {style}\n'
f'Question: "{question}"\n\n'
f'Facts:\n{facts_text}'
)
resp = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.contentSpara och versionshantera rapporter
Spara rapporter med en tidsstämpel och en hash av forskningsfrågan. Då kan ni jämföra rapportversioner om researchen körs igen med uppdaterade källor.
import hashlib, json, os
from datetime import datetime, timezone
def save_report(report: dict, question: str, output_dir: str = '/tmp/reports'):
os.makedirs(output_dir, exist_ok=True)
q_hash = hashlib.md5(question.encode()).hexdigest()[:8]
timestamp = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M')
filename = f'{output_dir}/report_{q_hash}_{timestamp}.json'
with open(filename, 'w') as f:
json.dump({
'question': question,
'generated': timestamp,
'sections': report
}, f, indent=2)
print(f'Report saved: {filename}')
return filename
if __name__ == '__main__':
import tempfile
demo_dir = tempfile.mkdtemp()
save_report({'executive_summary': 'AI agent adoption grew significantly in 2026.'},
'What are the key AI agent trends in 2026?', output_dir=demo_dir)
Vilket avsnitt ska alltid vara självständigt i rapportstrukturen?
Rapportstrukturen är utformad så att läsare med ont om tid kan få ut värde utan att läsa hela dokumentet. Att förstå vilket avsnitt som måste stå på egna ben är viktigt för rapportdesignen.
Sammanfattning av strukturerad rapportgenerering
Generera rapporter avsnitt för avsnitt med en fast mall (Sammanfattning för ledningen → Bakgrund → Viktiga resultat → Belägg → Rekommendationer → Källor). Infoga inline-citeringar, kör kvalitetskontroller och stöd flera målgruppsanpassade stilar utifrån samma uppsättning fakta.
Spara alltid rapporter med tidsstämplar och frågehashar för versionshantering.
Lär dig AI-agenter med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 60
- Lektioner
- 239
Vanliga frågor
Är lektionen ”Generering av strukturerade rapporter” gratis?
Ja – hela texten till ”Generering av strukturerade rapporter” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i AI-agenter, kan Ni uppgradera till CoddyKit PRO. Kursen i AI-agenter innehåller totalt 4 lektioner.
Vad lär jag mig i ”Generering av strukturerade rapporter”?
Mallbaserade rapporter: sammanfattning för ledningen, resultat, belägg och rekommendationer. Ni övar på AI-agenter med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig AI-agenter?
Du behöver inga förkunskaper. Utbildningen i AI-agenter på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Generering av strukturerade rapporter”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här AI-agenter-lektionen?
Ja. Varje AI-agenter-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Design av forskningsloopar i flera steg
- Källverifiering och källhänvisningar
- Generering av strukturerade rapporter
- Faktagranskning och förebyggande av hallucinationer