mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 00:11:59 +00:00
相对日期一律按运行当天算:助手节点手册的搭图规则(画布、问数据共用)加第 6 条——「今天、昨天、上周、本月、去年」按运行当天算,SQL 用方言里取当天的写法、agent 先调 current_time,不用 MAX(日期) 去推「上周」,要说数据最新到哪天就另取一列;报告写作规则加一条(period_rule),告诉写作者今天是哪天、上周是哪几天:数据没覆盖问的那段时间时先照实说、写明数据最新到哪天,最近一段的数可以给但写具体起止日期,不叫它「上周」「本月」
This commit is contained in:
@@ -289,6 +289,10 @@ NODE_REFERENCE = """\
|
||||
4. 不要用 transform 解析 agent / llm 的文字:口径卡读 cell(nodes.查库节点id, 行, '列名') 或 vars.<agent 的 assign_to>.字段
|
||||
5. 数据在两个库、要按行对齐时:两个 tool 节点各自聚合到相同的键和粒度 → merge 按键合并 → 口径卡算派生指标 → report。
|
||||
同一个库写成一条 SQL;只组合几个单值用口径卡的 cell();不要用 code 节点合并(出处会断,喂给口径卡时核对不了)
|
||||
6. 问题里的「今天、昨天、上周、本月、去年」这类相对日期一律按运行当天算:SQL 用数据源方言里取当天的写法(CURRENT_DATE、
|
||||
CURDATE()、date('now')、SYSDATE),agent 先调 current_time 拿到当天日期再写条件(agent 的 prompt 里写明这一点、tools 绑上
|
||||
current_time)。不要用表里最大的日期(MAX(日期))去推「上周」「本月」:数据没更新到那段时间时,推出来的是另一段,报告还会
|
||||
把它当成上周来写。想让报告说清数据最新到哪天,另取一列 MAX(日期) AS 数据最新日期
|
||||
|
||||
模型字段(llm / agent / supervisor / report 的 config.model):
|
||||
- **不要填**。留空表示跟随当前供应商的默认模型,这几乎总是对的。
|
||||
|
||||
@@ -50,6 +50,7 @@ import unicodedata
|
||||
from collections import Counter
|
||||
from collections.abc import Callable, Iterable
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import date, timedelta
|
||||
from decimal import ROUND_HALF_UP, Context, Decimal
|
||||
from typing import Any, Literal, TypedDict
|
||||
|
||||
@@ -3306,6 +3307,24 @@ SEE_AND_CODE_RULES = (
|
||||
"(「状态为 9」「类型 1」):码值是没有出处的数字,系统会当成裸数字打回重写。"
|
||||
)
|
||||
|
||||
#: 相对日期(「今天、昨天、上周、本月、去年」)一律按运行当天算(period_rule)。部署上撞过:数据只更新到两周前,查库时拿表里
|
||||
#: 最大的日期往前推七天当「上周」,写作者照着写成「上周产量……」。写作者不知道今天是哪天,就分不出数据有没有覆盖问的那段,
|
||||
#: 所以把运行当天和上周的起止日期直接告诉它:没覆盖时先照实说、写明数据最新到哪天;最近一段的数可以给,但写具体起止日期
|
||||
PERIOD_RULE = (
|
||||
"相对日期:今天是 {today}({weekday}),上周是 {week_start} 至 {week_end}。问题里的「今天、昨天、上周、本月、去年」"
|
||||
"这类说法一律按今天算,不按数据里最新的日期推。查到的数据没覆盖问的那段时间时,先照实说没覆盖、数据最新到哪天"
|
||||
"(写具体日期);可以接着给出数据里最近一段的数,但写明它的起止日期,不要把它叫作「上周」「本月」这类相对的说法。"
|
||||
)
|
||||
_WEEKDAYS = ("周一", "周二", "周三", "周四", "周五", "周六", "周日")
|
||||
|
||||
|
||||
def period_rule(today: date) -> str:
|
||||
"""写作规则里讲相对日期的那一条(PERIOD_RULE),按运行当天 today 填好:上周是上周一到上周日。"""
|
||||
monday = today - timedelta(days=today.weekday() + 7)
|
||||
return PERIOD_RULE.format(today=today.isoformat(), weekday=_WEEKDAYS[today.weekday()],
|
||||
week_start=monday.isoformat(), week_end=(monday + timedelta(days=6)).isoformat())
|
||||
|
||||
|
||||
#: 句中的 [[see:]]:前面是介词、后面接着句子的写法(「以 [[see:Q1]] 为依据」「根据 [[see:Q1]],」「详见 [[see:Q1]]」)。
|
||||
#: 只认这几种拿得准的:「以」前面是「所、可、加……」的是另一个词(所以、可以),不算;「依据 [[see:…]]。」可能是
|
||||
#: 「这是结论的依据」,不算。认出来就交回写作者重写(report.REWRITE_ONLY:重写不好也不判失败)
|
||||
|
||||
@@ -38,6 +38,7 @@ import re
|
||||
import time
|
||||
from collections import Counter
|
||||
from collections.abc import Iterable, Mapping
|
||||
from datetime import date, datetime
|
||||
from typing import Any
|
||||
|
||||
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage
|
||||
@@ -56,6 +57,7 @@ from app.engine.evidence import (
|
||||
ENTITY_KINDS,
|
||||
MARKER_RULES,
|
||||
SEE_AND_CODE_RULES,
|
||||
period_rule,
|
||||
StreamRenderer,
|
||||
WriterCatalog,
|
||||
build_catalog,
|
||||
@@ -634,12 +636,17 @@ def _repair_request(violations: list[dict[str, Any]], failed_rule: str | None =
|
||||
)
|
||||
|
||||
|
||||
def run_today() -> date:
|
||||
"""写作规则里的「今天」(period_rule):服务端所在时区的日期,和查库时 CURRENT_DATE 一类按运行当天现算的写法同一天。"""
|
||||
return datetime.now().astimezone().date()
|
||||
|
||||
|
||||
def _messages(ctx: NodeContext, state: GraphState, writer: WriterCatalog, claims: str = "off",
|
||||
failed: str | None = None) -> list[BaseMessage]:
|
||||
system = ctx.render_str(ctx.cfg("system", ""), state)
|
||||
instructions = ctx.render_str(ctx.cfg("instructions", ""), state).strip() \
|
||||
or "根据下面的证据写一份简洁的报告,先总后分。"
|
||||
rules = f"{MARKER_RULES}\n{SEE_AND_CODE_RULES}"
|
||||
rules = f"{MARKER_RULES}\n{SEE_AND_CODE_RULES}\n{period_rule(run_today())}"
|
||||
if writer.guarded:
|
||||
# 写作者看不全证据(目录有省略、有来源的结构化结论为空):「没有查到」这类结论没有依据
|
||||
rules = f"{rules}\n{ABSENCE_RULE}"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
"""「今天、昨天、上周、本月、去年」一律按运行当天算。
|
||||
|
||||
部署上撞过:问「上周各条线的产量」,数据只更新到两周前;查库时拿表里最大的日期往前推七天当「上周」,报告照着写成
|
||||
「上周产量……」,读的人以为是上周的数。现在:
|
||||
- 助手的节点手册(画布、问数据共用)的搭图规则里有一条:相对日期按运行当天算(SQL 用当天的写法,agent 先调
|
||||
current_time),不用 MAX(日期) 去推;
|
||||
- 报告写作规则告诉写作者运行当天是哪天、上周是哪几天:数据没覆盖问的那段时间时先照实说、写明数据最新到哪天;可以给出
|
||||
最近一段的数,但写具体起止日期,不叫它「上周」。
|
||||
数据、日期都是虚构的。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date
|
||||
|
||||
from app.api.copilot import NODE_REFERENCE
|
||||
from app.engine.evidence import period_rule
|
||||
from tests.test_report_node import engine_up, finish, node, script # noqa: F401
|
||||
|
||||
|
||||
def _build_rules() -> str:
|
||||
start = NODE_REFERENCE.index("搭图规则(有数字结论时必须遵守)")
|
||||
return NODE_REFERENCE[start:NODE_REFERENCE.index("\n\n模型字段", start)]
|
||||
|
||||
|
||||
def test_the_copilot_reckons_relative_dates_from_the_run_day():
|
||||
rules = _build_rules()
|
||||
assert "今天、昨天、上周、本月、去年" in rules and "运行当天" in rules
|
||||
assert "CURRENT_DATE" in rules and "current_time" in rules # SQL 用当天的写法;agent 先取当天日期
|
||||
assert "MAX(日期)" in rules and "不要" in rules # 点名不要拿数据里最大的日期去推
|
||||
|
||||
|
||||
def test_the_writer_rule_names_the_run_day_and_last_week():
|
||||
rule = period_rule(date(2031, 3, 12)) # 虚构的一天:周三
|
||||
assert "2031-03-12(周三)" in rule
|
||||
assert "上周是 2031-03-03 至 2031-03-09" in rule # 上周一到上周日
|
||||
assert "不按数据里最新的日期推" in rule
|
||||
assert "数据最新到哪天" in rule and "起止日期" in rule and "不要把它叫作「上周」" in rule
|
||||
|
||||
|
||||
def test_last_week_on_a_monday_and_a_sunday():
|
||||
assert "上周是 2031-03-03 至 2031-03-09" in period_rule(date(2031, 3, 10)) # 周一
|
||||
assert "上周是 2031-03-03 至 2031-03-09" in period_rule(date(2031, 3, 16)) # 周日:本周还没过完,上周照旧是前一周
|
||||
|
||||
|
||||
async def test_the_report_prompt_carries_the_run_day(monkeypatch):
|
||||
from app.engine.nodes import report as report_mod
|
||||
|
||||
monkeypatch.setattr(report_mod, "run_today", lambda: date(2031, 3, 12))
|
||||
seen = script(monkeypatch, "没有数据。")
|
||||
graph = {
|
||||
"nodes": [
|
||||
node("start", "input", fields=[{"name": "q", "default": "上周的产量是多少"}]),
|
||||
node("write", "report", instructions="回答:{{ input.q }}"),
|
||||
node("out", "output", fields=[{"name": "答案", "value": "{{ nodes.write.text }}"}]),
|
||||
],
|
||||
"edges": [{"source": "start", "target": "write"}, {"source": "write", "target": "out"}],
|
||||
}
|
||||
await finish(graph)
|
||||
prompt = "\n".join(str(m.content) for m in seen[0])
|
||||
assert "今天是 2031-03-12(周三)" in prompt and "上周是 2031-03-03 至 2031-03-09" in prompt
|
||||
Reference in New Issue
Block a user