0Pricing
AI Agents · 课时

结构化报告生成

模板化报告:执行摘要、调查结果、证据和建议

结构化报告生成 是 CoddyKit 上的免费 AI Agents 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Agents 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Agents 课程共包含 4 节课。

从事实到易读的报告

只输出事实列表的研究代理很难使用。决策者需要结构化报告:执行摘要、背景部分、关键发现、证据和建议。

本课将介绍如何根据已验证的事实,逐个部分生成专业报告。

报告模板

请预先定义报告结构。LLM 一次综合一个章节,使每个章节保持重点明确并避免重复。

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]}')

一次生成一个章节

在一个提示词中生成整份报告并不可靠——LLM 容易无法继续准确追踪事实和结构。请逐个章节生成,并将前面的章节作为上下文传入。

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.content

迭代构建报告

遍历所有章节,并传入不断累积的上下文。每个章节都能了解前面已经出现的内容,从而确保报告连贯,避免内部矛盾。

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 report

注入行内引用

将生成章节中的事实引用替换为带编号的引用,并链接回来源列表。这样可以追溯每一条论断。

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))

格式化为 Markdown

将报告章节渲染为 Markdown。这样可以将输出转换为 HTML、PDF,或直接显示在 Notion、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)

生成带来源链接的报告

面向网页进行渲染时,请将来源网址转换为超链接。此外,添加一个元数据块,其中包含报告生成日期、来源数量和验证率。

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)

发布前的质量检查

交付报告前,请运行自动化质量检查:每个章节达到最低字数、至少包含 N 个引用、所有建议都使用行动动词,并且不包含“[INSERT]”之类的占位文本。

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)

执行摘要:严格限制

执行摘要应当自成一体:只阅读这一章节的人也应理解核心发现和建议采取的行动。请使用带有字数限制的严格提示词。

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.content

面向多种受众的报告

同一项研究可能需要针对不同受众采用不同的报告风格:面向工程师的技术深度分析、面向管理层的执行摘要,以及面向非专业人士的通俗说明。请根据同一组事实生成每个版本。

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.content

保存报告并进行版本管理

请使用时间戳和研究问题哈希保存报告。这样,如果使用更新后的来源重新运行研究,就可以比较不同版本的报告。

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)

报告结构中哪个章节应始终自成一体

报告结构经过设计,使时间有限的读者无需阅读完整文档也能获取有价值的信息。理解哪个章节必须独立成篇,对于报告设计十分重要。

结构化报告生成回顾

请使用固定模板(执行摘要 → 背景 → 关键发现 → 证据 → 建议 → 来源),逐个章节生成报告。注入行内引用,运行质量检查,并根据同一组事实支持多种受众风格。

请始终使用时间戳和问题哈希保存报告,以便进行版本管理。

常见问题解答

「结构化报告生成」课时是免费的吗?

是的 — 「结构化报告生成」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Agents 课程的其余内容,请升级到 CoddyKit PRO。 AI Agents 课程共包含 4 节课。

「结构化报告生成」这节课中我会学到什么?

模板化报告:执行摘要、调查结果、证据和建议 你通过在浏览器中直接运行的动手代码来练习 AI Agents,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Agents 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Agents 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「结构化报告生成」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Agents 课中编写并运行代码吗?

能。每节 AI Agents 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 多步骤研究循环设计
  2. 来源核验与引用
  3. 结构化报告生成
  4. 事实核查与防止幻觉
← 返回 AI Agents