检查用户的每周日志、实现每周六日志总结的功能

实现每周六定时触发,自动检查周一到周四日志,通过AutoGen智能体生成周报总结,并提供三个钉钉日志接口的实现说明和代码示例。

要求实现

  • 根据现有的接口服务中的通过Fasiapi启动时候的定时任务(每周六20:30)进行触发,每周五可以自动检查本周一到周四所有的日志,通过autogen智能体实现总结-最终生成一个周五的周报总结日志
  • 也需要额外实现对应的3个接口
  • 直接检查当前本地数据库中第一个用户id对应的周一到周四的模版内容
  • 发送文本调用智能体直接生成周报总结后的模本
  • 将文本模版内容,通过调用的钉钉的日志接口-填充该模版日志并且进行发送,并且推送到钉钉机器人

钉钉日志接口说明:

  • 查询日志模版接口

POST https://oapi.dingtalk.com/topapi/report/list?access_token=ACCESS_TOKEN

响应:

  • 保存日志内容

POST https://oapi.dingtalk.com/topapi/report/savecontent?access_token=ACCESS_TOKEN

请求body:

响应示例

  • 创建日志接口

POST https://oapi.dingtalk.com/topapi/report/create?access_token=ACCESS_TOKEN

请求正文

响应示例

日志的智能体实现

实现案例的demo和对应的语法示例

json10 行
{
    "cursor": "0",
    "start_time": 1605064271000,
    "template_name": "产品研发中心组长日报及周报(导入上篇)",
    "size": 10,
    "end_time": 1605715199000,
    "modified_end_time": 1605715199000,
    "userid": "user123",
    "modified_start_time": 1605064271000
}
json35 行
{
    "errcode": 0,
    "errmsg":"ok",
    "result": {
        "data_list": [
            {
                "contents": [
                    {
                        "key": "今日完成工作",
                        "sort": "0",
                        "type": "1",
                        "value": "“今天已经完成的工作"
                    },
                    {
                        "key": "未完成工作",
                        "sort": "1",
                        "type": "1",
                        "value": "“未完成工作"
                    }
                ],
                "create_time": 1605680704000,
                "creator_id": "user123",
                "creator_name": "测试同学",
                "dept_name": "测试部",
                "modified_time": 1605680704000,
                "report_id": "175daxxxxxxfaa85c4",
                "template_name": "日报"
            }
        ],
        "has_more": false,
        "next_cursor": 2862455276,
        "size": 10
    },
    "request_id": "5c8q6ic6wyah"
}
json23 行
{
    "create_report_param": {
        "contents": [
            {
                "content_type": "markdown",
                "sort": "0",
                "type": "1",
                "content": "“这里是今天已经完成的工作。",
                "key": "今日完成工作"
            },
            {
                "content_type": "markdown",
                "sort": "1",
                "type": "1",
                "content": "“这是待处理的任务。",
                "key": "未完成工作"
            }
        ],
        "dd_from": "report",
        "template_id": "1734bff776fcc65ce6944f749e08500e",
        "userid": "user456"
    }
}
json5 行
{
     "errcode": 0,
     "result": "175da298c2d6eb61373bb314725ae15d",
     "request_id": "14g3ttfdbjfpv"
}
json29 行
{
    "create_report_param": {
        "contents": [
            {
                "content_type": "markdown",
                "sort": "0",
                "type": "1",
                "content": "“Mg+ZnS04=MgS04+Zn”你的镁偷走了我的锌",
                "key": "今日完成工作"
            },
            {
                "content_type": "markdown",
                "sort": "1",
                "type": "1",
                "content": "“哪有什么满眼星辰,分明就是满眼的你。",
                "key": "未完成工作"
            }
        ],
        "dd_from": "ygx",
        "template_id": "1734xxxxxxe08500e",
        "userid": "user123",
        "to_chat": true,
        "to_cids": "$DD_KExxxxxxYA==",
        "to_userids": [
            "user123",
            "user456"
        ]
    }
}
json5 行
{
    "errcode": 0,
    "result": "1734xxxxxxe08500e",
    "request_id": "5kaikoe9uc8i"
}
python102 行
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console # 用于在控制台显示流式输出
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_ext.models.gemini import GeminiChatCompletionClient # 导入 Gemini 客户端

# 1. 定义模型客户端
# 请确保您已设置 OPENAI_API_KEY 和 GEMINI_API_KEY 环境变量
# 或者直接在这里替换为您的 API 密钥
openai_model_client = OpenAIChatCompletionClient(model="gpt-4o-mini") # 总结智能体使用 OpenAI
gemini_model_client = GeminiChatCompletionClient(model="gemini-1.5-flash-002") # 检察官智能体使用 Gemini

# 2. 创建总结智能体 (Summarizer Agent)
summarizer_agent = AssistantAgent(
    name="Summarizer",
    description="""你是一个专业的周报总结者。
    你的任务是根据用户提供的原始文本,生成一份正式、段落有序、且完全没有“AI味”的周报总结。
    请确保总结内容简洁明了,突出重点,并使用正式的商务语言。
    """,
    model_client=openai_model_client,
    # 允许智能体在必要时多次发言,以便根据反馈进行修改
    allow_repeated_speaker=True,
)

# 3. 创建检察官智能体 (Reviewer Agent)
# 检察官智能体是关键,它会决定循环是否继续
reviewer_agent = AssistantAgent(
    name="Reviewer",
    description="""你是一个严格的周报检察官。
    你的任务是审查Summarizer生成的周报总结。
    请检查以下几点:
    1. 格式:段落是否清晰有序?
    2. 语法:是否存在语法错误或拼写错误?
    3. 正式性:语言是否正式,符合商务报告的风格?
    4. “AI味”:是否完全去除了AI生成内容的痕迹,听起来像人类撰写?

    如果总结不符合要求,请明确指出问题所在,并提供具体的修改建议,然后等待Summarizer重新生成。
    例如:“格式问题:请将每个要点分段,并使用项目符号。”
    如果总结完全符合所有要求,请回复以下特定短语来批准并结束任务:
    "FINAL_REPORT_APPROVED: [这里是最终的周报总结内容]"
    """,
    model_client=gemini_model_client,
    # 允许智能体在必要时多次发言,以便提供持续的反馈
    allow_repeated_speaker=True,
)

# 4. 设置终止条件
# 当 Reviewer Agent 的消息中包含 "FINAL_REPORT_APPROVED:" 时,对话终止
termination_condition = TextMentionTermination("FINAL_REPORT_APPROVED:")

# 5. 创建 RoundRobinGroupChat
# 智能体将按 Summarizer -> Reviewer 的顺序轮流发言
# max_turns 用于防止无限循环,如果智能体无法达成一致,会在达到最大轮次后停止
group_chat = RoundRobinGroupChat(
    [summarizer_agent, reviewer_agent],
    termination_condition=termination_condition,
    max_turns=15, # 最多允许 15 轮交互,防止陷入死循环
)

# 6. 定义用户输入的原始文本
user_input_text = """
这个星期我们做了很多事情。首先,我们完成了项目A的初期设计,团队成员都觉得很棒。
然后,我们开了一个会,讨论了项目B的进展,发现了一些小问题,但是我们已经找到了解决方案。
我还和客户C进行了沟通,他们对我们的服务表示满意,并且可能会有新的合作机会。
最后,我花了一些时间研究了最新的AI技术,觉得对我们未来的产品开发很有帮助。
"""

# 7. 运行团队
async def run_weekly_report_workflow():
    print("--- 开始生成周报总结 ---")
    print(f"原始输入文本:\n{user_input_text}\n")

    # `run_stream` 返回一个异步生成器,用于流式传输中间消息
    stream = group_chat.run_stream(
        task=f"请根据以下文本生成一份周报总结:\n\n{user_input_text}"
    )

    # `Console` 是一个简单的 UI,用于显示流
    await Console(stream)

    print("\n--- 周报总结生成与审查完成 ---")
    # 可以在这里获取最终的总结内容
    # 遍历 stream 获取所有消息,找到 Reviewer 的最后一条批准消息
    final_summary = None
    async for message in stream:
        if isinstance(message, TextMessage) and message.source == "Reviewer" and "FINAL_REPORT_APPROVED:" in message.content:
            final_summary = message.content.replace("FINAL_REPORT_APPROVED:", "").strip()
            break # 找到批准消息后即可退出

    if final_summary:
        print("\n最终批准的周报总结:")
        print(final_summary)
    else:
        print("\n未能生成最终批准的周报总结。请检查日志以获取更多信息。")

# 运行异步主函数
if __name__ == "__main__":
    asyncio.run(run_weekly_report_workflow())