Skip to content

[Bug] cron表达式描述应推荐使用明确的星期几格式(mon-fri),以避免星期几偏移 #5680

@ddfnuist

Description

@ddfnuist

What happened / 发生了什么

问题

astrbot/core/tools/cron_tools.py 中,cron_expression 的工具描述目前为:

“定义重复计划的 Cron 表达式(例如,'0 8 * * *')。”

然而,Cron 中的星期几(DOW)字段在不同实现中常存在歧义(例如,星期日是 0 还是 7;或 1-5 是否代表周一至周五)。当 LLM 生成 Cron 表达式时,可能输出数字形式的 DOW,如 1-5,这导致我设置的工作日任务在时间上错位。

Image

代码参考:

"description": "Cron expression defining recurring schedule (e.g., '0 8 * * *').",

建议

  1. 更新 cron_expression 的描述,明确推荐使用无歧义的 DOW 字符串,例如 mon-frisat,sun 等。
  2. (可选)在 Cron 解析层添加验证/规范化逻辑,拒绝含歧义的数字 DOW,或明确记录所接受的格式。

期望结果

引导 LLM/用户使用 mon-fri 样式的 DOW,避免意外的工作日偏移。

额外上下文

这一点对于 LLM 工具调用尤为重要,因为微小的歧义可能悄无声息地导致错误的调度。

Reproduce / 如何复现?

我在当前20:30时对astrbot说: 为了测试不同cron表达式写法对定时任务的影响,现在设置两个测试任务,均为每个工作日23时提醒我睡觉。一个cron表达式写法为数字形式,另一个写法使用明确的星期几格式。
得到如下回复:有趣的现象!我发现了一个小差异:

  1. 测试任务-星期格式(mon-fri):下次执行时间是 今天 23:00(2026-03-02 23:00:00)
  2. 测试任务-数字形式(1-5):下次执行时间是 明天 23:00(2026-03-03 23:00:00)

这说明两种写法在计算下一次执行时间时可能有不同的逻辑!

让我分析一下:

  • 今天是2026-03-02,星期一(假设)
  • mon-fri 写法可能识别今天是周一,所以今天23:00就执行
  • 1-5 写法可能从明天开始计算,所以明天23:00才执行

这确实是个有趣的测试!您可以通过观察这两个任务的实际执行情况来了解不同cron表达式写法的影响。两个任务都设置为工作日23:00提醒睡觉,但启动时间点似乎有差异呢!

AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器

AstrBot版本:v4.18.3、部署方式:AstrBot Launcher、模型提供商:DeepSeek V3.2、消息平台:飞书

OS

Windows

Logs / 报错日志

[2026-03-02 20:31:50.540] [Core] [INFO] [core.event_bus:59]: [default] [lark(lark)] ou_dc7f5/ou_dc7f597703a1d49a93a718a80fdc2f2e: 为了测试不同cron表达式写法对定时任务的影响,现在设置两个测试任务,均为每个工作日23时提醒我睡觉。一个cron表达式写法为数字形式,另一个写法使用明确的星期几格式。
[2026-03-02 20:31:50.541] [Core] [DBUG] [waking_check.stage:157]: enabled_plugins_name: ['*']
[2026-03-02 20:31:51.057] [Core] [DBUG] [method.star_request:44]: plugin -> session_controller - handle_session_control_agent
[2026-03-02 20:31:51.057] [Core] [DBUG] [method.star_request:44]: plugin -> session_controller - handle_empty_mention
[2026-03-02 20:31:51.057] [Core] [DBUG] [method.star_request:44]: plugin -> meme_manager - handle_upload_image
[2026-03-02 20:31:51.058] [Core] [DBUG] [method.star_request:44]: plugin -> astrbot - on_message
[2026-03-02 20:31:51.060] [Core] [DBUG] [agent_sub_stages.internal:152]: ready to request llm provider
[2026-03-02 20:31:51.060] [Core] [DBUG] [agent_sub_stages.internal:158]: acquired session lock for llm request
[2026-03-02 20:31:51.096] [Core] [DBUG] [core.astr_main_agent_resources:418]: [知识库] 使用全局配置,知识库数量: 0
[2026-03-02 20:31:51.097] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnLLMRequestEvent) -> astrbot - decorate_llm_req
[2026-03-02 20:31:51.098] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnLLMRequestEvent) -> astrbot-web-searcher - edit_web_search_tools
[2026-03-02 20:31:51.100] [Core] [DBUG] [runners.base:64]: Agent state transition: AgentState.IDLE -> AgentState.RUNNING
[2026-03-02 20:31:51.100] [Core] [DBUG] [runners.tool_loop_agent_runner:278]: [BefCompact] RunCtx.messages -> [22] system,user,assistant,tool,assistant,user,assistant,user,assistant,tool,tool,tool,tool,assistant,tool,tool,tool,tool,assistant,tool,assistant,user
[2026-03-02 20:31:51.100] [Core] [DBUG] [runners.tool_loop_agent_runner:278]: [AftCompact] RunCtx.messages -> [22] system,user,assistant,tool,assistant,user,assistant,user,assistant,tool,tool,tool,tool,assistant,tool,tool,tool,tool,assistant,tool,assistant,user
[2026-03-02 20:32:05.054] [Core] [DBUG] [sources.openai_source:262]: completion: ChatCompletion(id='ae902a0a-1d98-4c85-9c19-60a1daf4fc0b', choices=[Choice(finish_reason='tool_calls', index=0, logprobs=None, message=ChatCompletionMessage(content='&&happy&& 好的!我来帮您创建两个测试任务,都是每个工作日23时提醒睡觉,但使用不同的cron表达式写法来测试效果。\n\n任务1:数字形式写法 - 使用 0 23 * * 1-5\n任务2:明确的星期几格式 - 使用 0 23 * * mon-fri\n\n让我来创建这两个测试任务:', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_Wrg3H62dyfXkTDQaEfUVqccP', function=Function(arguments='{"name": "测试任务-数字形式", "cron_expression": "0 23 * * 1-5", "note": "测试任务:工作日23:00睡觉提醒(数字形式写法:1-5)"}', name='create_future_task'), type='function', index=0), ChatCompletionMessageFunctionToolCall(id='call_01_glPKYjWoSmzF5deGUZIO31hU', function=Function(arguments='{"name": "测试任务-星期格式", "cron_expression": "0 23 * * mon-fri", "note": "测试任务:工作日23:00睡觉提醒(星期格式:mon-fri)"}', name='create_future_task'), type='function', index=1)]))], created=1772454718, model='deepseek-chat', object='chat.completion', service_tier=None, system_fingerprint='fp_eaab8d114b_prod0820_fp8_kvcache', usage=CompletionUsage(completion_tokens=286, prompt_tokens=5206, total_tokens=5492, completion_tokens_details=None, prompt_tokens_details=PromptTokensDetails(audio_tokens=None, cached_tokens=5120), prompt_cache_hit_tokens=5120, prompt_cache_miss_tokens=86))
[2026-03-02 20:32:05.055] [Core] [DBUG] [result_decorate.stage:165]: hook(on_decorating_result) -> meme_manager - on_decorating_result
[2026-03-02 20:32:05.055] [Core] [DBUG] [astrbot_plugin_meme_manager.main:874]: [meme_manager] on_decorating_result 开始处理
[2026-03-02 20:32:05.056] [Core] [DBUG] [astrbot_plugin_meme_manager.main:1025]: [meme_manager] on_decorating_result 处理完成
[2026-03-02 20:32:05.058] [Core] [INFO] [respond.stage:184]: Prepare to send - ou_dc7f5/ou_dc7f597703a1d49a93a718a80fdc2f2e: 好的!我来帮您创建两个测试任务,都是每个工作日23时提醒睡觉,但使用不同的cron表达式写法来测试效果。

任务1:数字形式写法 - 使用 0 23 * * 1-5
任务2:明确的星期几格式 - 使用 0 23 * * mon-fri

让我来创建这两个测试任务:
[2026-03-02 20:32:05.674] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnAfterMessageSentEvent) -> meme_manager - after_message_sent
[2026-03-02 20:32:05.674] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnAfterMessageSentEvent) -> astrbot - after_message_sent
[2026-03-02 20:32:05.674] [Core] [INFO] [runners.tool_loop_agent_runner:584]: Agent 使用工具: ['create_future_task', 'create_future_task']
[2026-03-02 20:32:05.675] [Core] [INFO] [runners.tool_loop_agent_runner:621]: 使用工具:create_future_task,参数:{'name': '测试任务-数字形式', 'cron_expression': '0 23 * * 1-5', 'note': '测试任务:工作日23:00睡觉提醒(数字形式写法:1-5)'}
[2026-03-02 20:32:05.685] [Core] [INFO] [runners.tool_loop_agent_runner:621]: 使用工具:create_future_task,参数:{'name': '测试任务-星期格式', 'cron_expression': '0 23 * * mon-fri', 'note': '测试任务:工作日23:00睡觉提醒(星期格式:mon-fri)'}
[2026-03-02 20:32:06.293] [Core] [INFO] [runners.tool_loop_agent_runner:826]: Tool create_future_task Result: Scheduled future task f290270c-f28c-40e7-a8d1-a10a610dd285 (测试任务-星期格式) expression '0 23 * * mon-fri' (next None).
[2026-03-02 20:32:06.294] [Core] [DBUG] [runners.tool_loop_agent_runner:278]: [BefCompact] RunCtx.messages -> [25] system,user,assistant,tool,assistant,user,assistant,user,assistant,tool,tool,tool,tool,assistant,tool,tool,tool,tool,assistant,tool,assistant,user,assistant,tool,tool
[2026-03-02 20:32:06.294] [Core] [DBUG] [runners.tool_loop_agent_runner:278]: [AftCompact] RunCtx.messages -> [25] system,user,assistant,tool,assistant,user,assistant,user,assistant,tool,tool,tool,tool,assistant,tool,tool,tool,tool,assistant,tool,assistant,user,assistant,tool,tool
[2026-03-02 20:32:10.504] [Core] [DBUG] [sources.openai_source:262]: completion: ChatCompletion(id='a6328672-fda1-44ef-b494-8dc436d9420d', choices=[Choice(finish_reason='tool_calls', index=0, logprobs=None, message=ChatCompletionMessage(content='&&work&& 完成!两个测试任务都已经创建好了。让我查看一下现在的任务列表,确认两个任务都正确设置了:', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageFunctionToolCall(id='call_00_MsHp3IozfdkE2dHme9sbTNmw', function=Function(arguments='{}', name='list_future_tasks'), type='function', index=0)]))], created=1772454733, model='deepseek-chat', object='chat.completion', service_tier=None, system_fingerprint='fp_eaab8d114b_prod0820_fp8_kvcache', usage=CompletionUsage(completion_tokens=56, prompt_tokens=5609, total_tokens=5665, completion_tokens_details=None, prompt_tokens_details=PromptTokensDetails(audio_tokens=None, cached_tokens=5440), prompt_cache_hit_tokens=5440, prompt_cache_miss_tokens=169))
[2026-03-02 20:32:10.504] [Core] [DBUG] [result_decorate.stage:165]: hook(on_decorating_result) -> meme_manager - on_decorating_result
[2026-03-02 20:32:10.504] [Core] [DBUG] [astrbot_plugin_meme_manager.main:874]: [meme_manager] on_decorating_result 开始处理
[2026-03-02 20:32:10.504] [Core] [DBUG] [astrbot_plugin_meme_manager.main:1025]: [meme_manager] on_decorating_result 处理完成
[2026-03-02 20:32:10.506] [Core] [INFO] [respond.stage:184]: Prepare to send - ou_dc7f5/ou_dc7f597703a1d49a93a718a80fdc2f2e: 完成!两个测试任务都已经创建好了。让我查看一下现在的任务列表,确认两个任务都正确设置了:
[2026-03-02 20:32:11.071] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnAfterMessageSentEvent) -> meme_manager - after_message_sent
[2026-03-02 20:32:11.071] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnAfterMessageSentEvent) -> astrbot - after_message_sent
[2026-03-02 20:32:11.071] [Core] [INFO] [runners.tool_loop_agent_runner:584]: Agent 使用工具: ['list_future_tasks']
[2026-03-02 20:32:11.071] [Core] [INFO] [runners.tool_loop_agent_runner:621]: 使用工具:list_future_tasks,参数:{}
[2026-03-02 20:32:11.601] [Core] [INFO] [runners.tool_loop_agent_runner:826]: Tool list_future_tasks Result: f290270c-f28c-40e7-a8d1-a10a610dd285 | 测试任务-星期格式 | active_agent | run_once=False | enabled=True | next=2026-03-02 23:00:00
44ab14a8-b144-464e-80b0-f1434df3d001 | 测试任务-数字形式 | active_agent | run_once=False | enabled=True | next=2026-03-03 23:00:00
0bf96b29-b947-4bd0-94e5-eb811077473e | 下班打卡提醒 | active_agent | run_once=False | enabled=True | next=2026-03-03 17:45:00
1386a4e0-6a7a-45a0-bbf6-362320e3b8ec | 下午上班打卡提醒 | active_agent | run_once=False | enabled=True | next=2026-03-03 13:40:00
63968bab-31e2-4763-ab05-1e051a52feed | 午休前打卡提醒 | active_agent | run_once=False | enabled=True | next=2026-03-03 11:45:00
fd13b421-84b6-44ee-a7ff-aa710758f3f4 | 早上打卡提醒 | active_agent | run_once=False | enabled=True | next=2026-03-03 08:15:00
064c4f60-37b3-4e91-891d-d0e0c61cceb6 | 每日DeepSeek余额查询 | active_agent | run_once=False | enabled=True | next=2026-03-03 09:00:00
[2026-03-02 20:32:11.604] [Core] [DBUG] [runners.tool_loop_agent_runner:278]: [BefCompact] RunCtx.messages -> [27] system,user,assistant,tool,assistant,user,assistant,user,assistant,tool,tool,tool,tool,assistant,tool,tool,tool,tool,assistant,tool,assistant,user,assistant,tool,tool,assistant,tool
[2026-03-02 20:32:11.604] [Core] [DBUG] [runners.tool_loop_agent_runner:278]: [AftCompact] RunCtx.messages -> [27] system,user,assistant,tool,assistant,user,assistant,user,assistant,tool,tool,tool,tool,assistant,tool,tool,tool,tool,assistant,tool,assistant,user,assistant,tool,tool,assistant,tool
[2026-03-02 20:32:23.260] [Core] [DBUG] [sources.openai_source:262]: completion: ChatCompletion(id='d04c6270-788e-44aa-8dd2-a27b95574507', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='&&surprised&& 有趣的现象!我发现了一个小差异:\n\n1. 测试任务-星期格式(mon-fri):下次执行时间是 今天 23:00(2026-03-02 23:00:00)\n2. 测试任务-数字形式(1-5):下次执行时间是 明天 23:00(2026-03-03 23:00:00)\n\n这说明两种写法在计算下一次执行时间时可能有不同的逻辑!&&confused&&\n\n让我分析一下:\n- 今天是2026-03-02,星期一(假设)\n- mon-fri 写法可能识别今天是周一,所以今天23:00就执行\n- 1-5 写法可能从明天开始计算,所以明天23:00才执行\n\n这确实是个有趣的测试!您可以通过观察这两个任务的实际执行情况来了解不同cron表达式写法的影响。两个任务都设置为工作日23:00提醒睡觉,但启动时间点似乎有差异呢!&&see&&', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=None))], created=1772454738, model='deepseek-chat', object='chat.completion', service_tier=None, system_fingerprint='fp_eaab8d114b_prod0820_fp8_kvcache', usage=CompletionUsage(completion_tokens=215, prompt_tokens=6071, total_tokens=6286, completion_tokens_details=None, prompt_tokens_details=PromptTokensDetails(audio_tokens=None, cached_tokens=5632), prompt_cache_hit_tokens=5632, prompt_cache_miss_tokens=439))
[2026-03-02 20:32:23.260] [Core] [DBUG] [runners.base:64]: Agent state transition: AgentState.RUNNING -> AgentState.DONE
[2026-03-02 20:32:23.260] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnLLMResponseEvent) -> meme_manager - resp
[2026-03-02 20:32:23.261] [Core] [DBUG] [astrbot_plugin_meme_manager.main:607]: [meme_manager] 重复检测阶段找到的表情: []
[2026-03-02 20:32:23.261] [Core] [DBUG] [astrbot_plugin_meme_manager.main:636]: [meme_manager] 松散匹配阶段找到的表情: []
[2026-03-02 20:32:23.261] [Core] [INFO] [astrbot_plugin_meme_manager.main:692]: [meme_manager] 去重后的最终表情列表: ['surprised']
[2026-03-02 20:32:23.261] [Core] [DBUG] [astrbot_plugin_meme_manager.main:697]: [meme_manager] 清理后的最终文本内容长度: 365
[2026-03-02 20:32:23.261] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnLLMResponseEvent) -> astrbot - record_llm_resp_to_ltm
[2026-03-02 20:32:23.261] [Core] [DBUG] [result_decorate.stage:165]: hook(on_decorating_result) -> meme_manager - on_decorating_result
[2026-03-02 20:32:23.262] [Core] [DBUG] [astrbot_plugin_meme_manager.main:874]: [meme_manager] on_decorating_result 开始处理
[2026-03-02 20:32:23.262] [Core] [DBUG] [astrbot_plugin_meme_manager.main:1025]: [meme_manager] on_decorating_result 处理完成
[2026-03-02 20:32:23.263] [Core] [INFO] [respond.stage:184]: Prepare to send - ou_dc7f5/ou_dc7f597703a1d49a93a718a80fdc2f2e: 有趣的现象!我发现了一个小差异:

  1. 测试任务-星期格式(mon-fri):下次执行时间是 今天 23:00(2026-03-02 23:00:00)
  2. 测试任务-数字形式(1-5):下次执行时间是 明天 23:00(2026-03-03 23:00:00)

这说明两种写法在计算下一次执行时间时可能有不同的逻辑!

让我分析一下:

  • 今天是2026-03-02,星期一(假设)
  • mon-fri 写法可能识别今天是周一,所以今天23:00就执行
  • 1-5 写法可能从明天开始计算,所以明天23:00才执行

这确实是个有趣的测试!您可以通过观察这两个任务的实际执行情况来了解不同cron表达式写法的影响。两个任务都设置为工作日23:00提醒睡觉,但启动时间点似乎有差异呢!
[2026-03-02 20:32:23.853] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnAfterMessageSentEvent) -> meme_manager - after_message_sent
[2026-03-02 20:32:23.853] [Core] [DBUG] [pipeline.context_utils:95]: hook(OnAfterMessageSentEvent) -> astrbot - after_message_sent
[2026-03-02 20:32:23.890] [Core] [DBUG] [pipeline.scheduler:93]: pipeline 执行完毕。

Are you willing to submit a PR? / 你愿意提交 PR 吗?

  • Yes!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:coreThe bug / feature is about astrbot's core, backendbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions