检查用户的每周日志、实现每周六日志总结的功能
实现每周六定时触发,自动检查周一到周四日志,通过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和对应的语法示例
{
"cursor": "0",
"start_time": 1605064271000,
"template_name": "产品研发中心组长日报及周报(导入上篇)",
"size": 10,
"end_time": 1605715199000,
"modified_end_time": 1605715199000,
"userid": "user123",
"modified_start_time": 1605064271000
}{
"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"
}{
"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"
}
}{
"errcode": 0,
"result": "175da298c2d6eb61373bb314725ae15d",
"request_id": "14g3ttfdbjfpv"
}{
"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"
]
}
}{
"errcode": 0,
"result": "1734xxxxxxe08500e",
"request_id": "5kaikoe9uc8i"
}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())