agent开发-日志agent开发日志 day4
这一篇是整个系统中最核心的文件
这个方法是调取llm,然后把llm返回的产品经理需求内容抠出来,转换成json格式,并且进行Pydantic校验,判断是模型类还是list列表,然后接下来采用不同的方法
点击查看代码
def _invoke_and_parse(llm, messages, schema) -> Any:
"""
调 LLM → 从 raw text 提取 JSON → Pydantic 校验 → 返回 Python 对象
────────────────────────────────────────────────────────────
参数:
llm - ChatOpenAI 实例(未经 structured_output 绑定)
messages - [SystemMessage, HumanMessage] 列表
schema - Pydantic BaseModel 子类 或 list[BaseModel] 泛型
返回:
校验后的 Pydantic 对象(如 Requirement)或对象列表(如 list[DevTask])
异常:
ValueError — JSON 解析失败或 Schema 校验失败
"""
# ① 调 LLM,拿到 raw text
response = llm.invoke(messages)
raw_text = response.content if hasattr(response, "content") else str(response)
# ② 从 raw text 里提取 JSON 片段
json_str = _extract_json_from_text(raw_text)
# ③ Pydantic 校验
try:
# 判断是模型类还是 list 泛型
if isinstance(schema, type) and issubclass(schema, BaseModel):
return schema.model_validate_json(json_str)
else:
# list[DevTask] 等泛型,用 TypeAdapter
return TypeAdapter(schema).validate_json(json_str)
except Exception as parse_error:
# 校验失败 — 把原始 LLM 输出也带上,方便调试
raise ValueError(
f"JSON 解析失败: {parse_error}\n"
f"LLM 原始输出(前500字):\n{raw_text[:500]}"
)
这一段是检查产品经理的需求,然后把ai生成的转化为json,拼接进HumanMessage ,在调用llm解析进行任务拆解
点击查看代码
# =============================================================================
# 节点2:任务拆解器
# =============================================================================
def breakdown_tasks_node(state: AgentState) -> dict[str, Any]:
"""
第二步"拆解开发任务"对应的节点函数
──────────────────────────────────
调用时机:节点1完成后自动触发
前置条件:state.requirement 必须非空
依赖:state.requirement + state.task_count
产出:一个 list[DevTask],写回 state.tasks
副作用:state.current_stage 从 "breakdown" 变为 "review"
"""
# 前置条件检查
if state.requirement is None:
return {
"error_message": "任务拆解失败:缺少前置需求(requirement 为空)",
"current_stage": "error",
}
try:
llm = get_llm()
requirement_json = state.requirement.model_dump_json(indent=2)
messages = [
SystemMessage(content=BREAKDOWN_TASKS_SYSTEM),
HumanMessage(content=build_task_breakdown_user_message(
requirement_json=requirement_json,
task_count=state.task_count,
)),
]
# 调 LLM → 提取 JSON 数组 → 校验为 list[DevTask]
tasks = _invoke_and_parse(llm, messages, list[DevTask])
return {
"tasks": tasks,
"current_stage": "review",
}
except Exception as e:
return {
"error_message": f"任务拆解失败: {e}",
"current_stage": "error",
}
最后这个方法就是根据前面的生成日志了还是先做验证,解析json,然后调用大模型生成
点击查看代码
# =============================================================================
# 节点3:日志生成
# =============================================================================
def generate_log_node(state: AgentState) -> dict[str, Any]:
"""
第三步"生成每日工作日志"对应的节点函数
────────────────────────────────────────
调用时机:用户在前端点击"一键生成今日日志"按钮
前置条件:state.requirement 和 state.tasks 都必须非空
依赖:state.requirement + state.tasks + state.task_marks
产出:一个 DailyLog 对象,写回 state.daily_log
副作用:state.current_stage 从 "review" 变为 "done"
"""
if state.requirement is None:
return {
"error_message": "日志生成失败:缺少前置需求(requirement 为空)",
"current_stage": "error",
}
if not state.tasks:
return {
"error_message": "日志生成失败:缺少开发任务列表(tasks 为空)",
"current_stage": "error",
}
try:
llm = get_llm()
# 序列化 requirement 为 JSON
requirement_json = state.requirement.model_dump_json(indent=2)
# 构造任务列表数据(移除 task_id 减少噪声)
tasks_for_prompt = []
for t in state.tasks:
d = t.model_dump()
d.pop("task_id", None)
tasks_for_prompt.append(d)
tasks_json = json.dumps(tasks_for_prompt, ensure_ascii=False, indent=2)
# 完成状态标记
marks_for_prompt = [m.model_dump() for m in state.task_marks]
marks_json = json.dumps(marks_for_prompt, ensure_ascii=False, indent=2)
messages = [
SystemMessage(content=GENERATE_LOG_SYSTEM),
HumanMessage(content=build_log_generation_user_message(
requirement_json=requirement_json,
tasks_json=tasks_json,
marks_json=marks_json,
)),
]
# 调 LLM → 提取 JSON → 校验为 DailyLog 对象
daily_log = _invoke_and_parse(llm, messages, DailyLog)
# --- 后处理:用代码覆盖 LLM 可能编造的字段 ---
# 1. 日期:用今天的真实日期覆盖 LLM 编造的日期
# 2. source_task_ids:用实际的 task_id 列表覆盖(LLM 会编造不存在的ID)
# model_copy(update={...}) 创建一个新对象,只改指定字段,其余保持 LLM 输出
corrected = daily_log.model_copy(update={
"date": datetime.date.today().isoformat(),
"source_task_ids": [t.task_id for t in state.tasks],
})
return {
"daily_log": corrected,
"current_stage": "done",
}
except Exception as e:
return {
"error_message": f"日志生成失败: {e}",
"current_stage": "error",
}

浙公网安备 33010602011771号