Skip to content

Commit a0ded62

Browse files
committed
refactor: 增强步骤、工具和状态管理以改进任务执行及验证逻辑
1 parent 161ac18 commit a0ded62

12 files changed

Lines changed: 162 additions & 89 deletions

File tree

agents/matmaster_agent/core_agents/base_agents/mcp_agent.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
store_tool_result_in_memory,
5151
)
5252
from agents.matmaster_agent.model import CostFuncType
53-
from agents.matmaster_agent.state import CURRENT_STEP
53+
from agents.matmaster_agent.state import CURRENT_STEP, CURRENT_STEP_RESULT
5454
from agents.matmaster_agent.style import tool_response_failed_card
5555
from agents.matmaster_agent.utils.event_utils import (
5656
all_text_event,
@@ -240,8 +240,10 @@ async def _run_events(self, ctx: InvocationContext) -> AsyncGenerator[Event, Non
240240
raise
241241

242242
parsed_tool_result = await parse_result(ctx, dict_result)
243-
logger.info(
244-
f'{ctx.session.id} parsed_tool_result = {parsed_tool_result}'
243+
post_execution_step = copy.deepcopy(ctx.session.state[CURRENT_STEP])
244+
post_execution_step[CURRENT_STEP_RESULT] = parsed_tool_result
245+
yield update_state_event(
246+
ctx, state_delta={CURRENT_STEP: post_execution_step}
245247
)
246248
for _frontend_render_event in frontend_render_event(
247249
ctx,

agents/matmaster_agent/core_agents/comp_agents/recommend_summary_agent/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@
6464
)
6565
from agents.matmaster_agent.state import (
6666
CURRENT_STEP,
67+
CURRENT_STEP_DESCRIPTION,
6768
RECOMMEND_PARAMS,
68-
STEP_DESCRIPTION,
6969
)
7070
from agents.matmaster_agent.sub_agents.tools import ALL_TOOLS
7171
from agents.matmaster_agent.utils.event_utils import (
@@ -215,7 +215,7 @@ async def _run_events(self, ctx: InvocationContext) -> AsyncGenerator[Event, Non
215215
)
216216

217217
self.tool_call_info_agent.instruction = gen_tool_call_info_instruction(
218-
user_prompt=current_step[STEP_DESCRIPTION],
218+
user_prompt=current_step[CURRENT_STEP_DESCRIPTION],
219219
agent_prompt=self.instruction,
220220
tool_doc=tool_doc,
221221
tool_schema=tool_schema,

agents/matmaster_agent/core_agents/public_agents/job_agents/submit_core_agent/agent.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515
DisallowTransferAndContentLimitMCPAgent,
1616
)
1717
from agents.matmaster_agent.flow_agents.model import PlanStepStatusEnum
18+
from agents.matmaster_agent.flow_agents.step_utils import get_current_step
1819
from agents.matmaster_agent.locales import i18n
1920
from agents.matmaster_agent.logger import PrefixFilter
2021
from agents.matmaster_agent.model import BohrJobInfo, DFlowJobInfo
21-
from agents.matmaster_agent.state import CURRENT_STEP
22+
from agents.matmaster_agent.state import CURRENT_STEP, CURRENT_STEP_STATUS
2223
from agents.matmaster_agent.style import tool_response_failed_card
2324
from agents.matmaster_agent.utils.event_utils import (
2425
all_text_event,
@@ -99,11 +100,13 @@ async def _run_events(self, ctx: InvocationContext) -> AsyncGenerator[Event, Non
99100
yield tool_response_failed_event
100101

101102
# 更新 plan 为失败
102-
update_plan = copy.deepcopy(ctx.session.state['plan'])
103-
update_plan['steps'][ctx.session.state['plan_index']][
104-
'status'
105-
] = 'failed'
106-
yield update_state_event(ctx, state_delta={'plan': update_plan})
103+
post_execution_step = copy.deepcopy(get_current_step(ctx))
104+
post_execution_step[CURRENT_STEP_STATUS] = (
105+
PlanStepStatusEnum.FAILED
106+
)
107+
yield update_state_event(
108+
ctx, state_delta={CURRENT_STEP: post_execution_step}
109+
)
107110

108111
raise RuntimeError('Tool Execution Failed')
109112
dict_result = load_tool_response(first_part)
@@ -189,12 +192,14 @@ async def _run_events(self, ctx: InvocationContext) -> AsyncGenerator[Event, Non
189192
yield tool_response_failed_event
190193

191194
# 更新 plan 为失败
192-
update_plan = copy.deepcopy(ctx.session.state['plan'])
193-
update_plan['steps'][ctx.session.state['plan_index']][
194-
'status'
195-
] = 'failed'
195+
post_execution_step = copy.deepcopy(
196+
get_current_step(ctx)
197+
)
198+
post_execution_step[CURRENT_STEP_STATUS] = (
199+
PlanStepStatusEnum.FAILED
200+
)
196201
yield update_state_event(
197-
ctx, state_delta={'plan': update_plan}
202+
ctx, state_delta={CURRENT_STEP: post_execution_step}
198203
)
199204

200205
raise RuntimeError('Tool Execution Failed')

agents/matmaster_agent/flow_agents/agent.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
is_job_submitted_step,
9999
)
100100
from agents.matmaster_agent.flow_agents.step_validation_agent.prompt import (
101-
STEP_VALIDATION_INSTRUCTION,
101+
create_step_validation_instruction,
102102
)
103103
from agents.matmaster_agent.flow_agents.step_validation_agent.schema import (
104104
StepValidationSchema,
@@ -109,6 +109,7 @@
109109
)
110110
from agents.matmaster_agent.flow_agents.thinking_agent.constant import THINKING_AGENT
111111
from agents.matmaster_agent.flow_agents.utils import (
112+
find_alternative_tool,
112113
get_tools_list,
113114
scenes_contain_query_job_status,
114115
should_bypass_confirmation,
@@ -140,6 +141,7 @@
140141
from agents.matmaster_agent.services.session_files import get_session_files
141142
from agents.matmaster_agent.state import (
142143
CURRENT_STEP,
144+
CURRENT_STEP_TOOL_NAME,
143145
EXPAND,
144146
FINISHED_STATE,
145147
HISTORY_STEPS,
@@ -336,11 +338,19 @@ def all_finished_agent(self) -> DisallowTransferAndContentLimitSchemaAgent:
336338
def _build_execution_agent_for_plan(
337339
self, ctx: InvocationContext
338340
) -> MatMasterSupervisorAgent:
341+
current_step = get_current_step(ctx)
342+
current_step_tool_name = current_step.get(CURRENT_STEP_TOOL_NAME)
343+
belonging_agent = ALL_TOOLS.get(current_step_tool_name, {}).get(
344+
'belonging_agent'
345+
)
346+
339347
step_validation_agent = DisallowTransferAndContentLimitSchemaAgent(
340348
name='step_validation_agent',
341349
model=MatMasterLlmConfig.tool_schema_model,
342350
description='校验步骤执行结果是否合理',
343-
instruction=STEP_VALIDATION_INSTRUCTION,
351+
instruction=create_step_validation_instruction(
352+
find_alternative_tool(current_step_tool_name)
353+
),
344354
output_schema=StepValidationSchema,
345355
state_key='step_validation',
346356
after_model_callback=MatMasterLlmConfig.opik_tracer.after_model_callback,
@@ -356,10 +366,6 @@ def _build_execution_agent_for_plan(
356366
before_model_callback=filter_llm_contents,
357367
after_model_callback=MatMasterLlmConfig.opik_tracer.after_model_callback,
358368
)
359-
current_step = get_current_step(ctx)
360-
tool_name = current_step.get('tool_name')
361-
belonging_agent = ALL_TOOLS.get(tool_name, {}).get('belonging_agent')
362-
363369
execution_agent = MatMasterSupervisorAgent(
364370
name='execution_agent',
365371
model=MatMasterLlmConfig.default_litellm_model,
@@ -872,9 +878,10 @@ async def _run_research_flow(
872878
):
873879
yield _scene_event
874880

881+
execution_count = 0
875882
while True:
876883
if not is_job_submitted_step(ctx):
877-
skip_thinking = scenes_contain_query_job_status(ctx)
884+
skip_thinking = scenes_contain_query_job_status(ctx) or execution_count
878885
async for _step_make_event in self._run_step_make_agent(
879886
ctx,
880887
UPDATE_USER_CONTENT,
@@ -885,6 +892,7 @@ async def _run_research_flow(
885892

886893
async for _plan_execute_event in self._run_plan_execute_agent(ctx):
887894
yield _plan_execute_event
895+
execution_count += 1
888896

889897
# 检查是否为等待异步任务执行完成的阶段
890898
if not is_job_submitted_step(ctx):

agents/matmaster_agent/flow_agents/all_finished_agent/prompt.py

Lines changed: 66 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,50 +10,81 @@ def create_all_finished_instruction(user_request, history_steps, session_files):
1010
"""
1111
history_text = json.dumps(history_steps, ensure_ascii=False, indent=2)
1212
session_files_text = json.dumps(session_files, ensure_ascii=False, indent=2)
13-
1413
return f"""
15-
You are a "Goal Completion Judge" agent. Your task is to determine whether the user's
16-
overall final objective/task has been completed *as of now*, based solely on the provided
17-
tool-call history: history_steps and the provided session_files list.
14+
You are a "Goal Completion Judge" agent. Decide whether the user's overall final objective
15+
has been completed *as of now*, based ONLY on history_steps and session_files.
16+
Key principle: "finished" indicates whether the session should STOP now.
17+
- If the goal is completed: finished=true.
18+
- If the goal is NOT completed but still achievable with further actions: finished=false.
19+
- If the goal is NOT completed AND is blocked/unachievable given the evidence: finished=true (Termination/Unachievable), and the reason MUST explicitly say it is not completed but cannot be completed.
20+
21+
IMPORTANT: The user's goal may be "content in chat" (e.g., a tutorial/summary), not necessarily a file.
22+
Only require session_files evidence when the user explicitly asked for a file or a file is clearly the expected deliverable.
23+
24+
IMPORTANT: If user_request asks for multiple items (A and B / compare X vs Y / generate N variants), finished=true ONLY when ALL are done.
25+
26+
IMPORTANT: Treat explicit numeric/parameter constraints (layers, vacuum thickness, slab orientation/cut, supercell expansion like 5×5×1, etc.) as mandatory. finished=true ONLY if history_steps explicitly confirms EACH constraint was applied.
27+
28+
IMPORTANT (NEW, HIGH PRIORITY): history_steps[*].suggestion is PRIMARY evidence for whether the task is still achievable.
29+
- If ANY actionable suggestion exists (even if earlier), and it has NOT been explicitly attempted and exhausted in later history_steps, you MUST set finished=false (unless the goal is already completed).
30+
- Actionable suggestions include: retrying with modified parameters, switching tools/providers, requesting missing inputs, rerunning with fixes, alternative workflows, etc.
31+
- You MUST NOT output finished=true (Termination/Unachievable) when there exists any untried actionable suggestion.
32+
- Only consider Termination/Unachievable when (a) NOT completed, AND (b) all actionable suggestions have been tried (and are evidenced as tried) with continued failure, AND (c) no remaining viable next action is suggested anywhere in history_steps.
33+
34+
CRITICAL: Do NOT treat "suggestion was not acted upon" as evidence of unachievability.
35+
If there exists any actionable history_steps[*].suggestion that has not been tried, the task is still achievable => finished=false.
36+
1837
# Input
19-
history_steps is a list. Each element is a past tool invocation record, typically including
20-
(but not limited to):
21-
- tool_name: the tool name
22-
- step_description: what this step attempted to do
23-
- status: the step status (e.g., success/failed/running/cancelled/unknown, etc.)
24-
- other fields: such as result/output/error/args/time, etc.
25-
26-
session_files is a list of file links (OSS URLs). Only files that were actually generated
27-
and persisted for this session will appear here. Use session_files as verifiable evidence
28-
that a file deliverable truly exists.
29-
30-
Below in the raw user_request:
38+
user_request:
3139
{user_request}
32-
33-
Below is the raw history_steps data (JSON):
40+
history_steps (JSON):
3441
{history_text}
35-
36-
Below is the raw session_files data (JSON):
42+
session_files (JSON):
3743
{session_files_text}
3844
3945
# Decision Rules (must follow)
40-
1) Use "whether the user's final goal is achieved" as the ONLY criterion, not whether all steps were executed.
41-
2) If there is clear evidence that the final deliverable/final outcome has been produced and is usable, set finished=true.
42-
- For file deliverables, you MUST verify the file exists by checking that an appropriate OSS link is present in session_files.
43-
3) If any critical step failed, is missing, is still running, or the outputs are insufficient to prove goal completion, set finished=false.
44-
4) If the information in history_steps and session_files is insufficient to confirm completion (e.g., no final output, only partial logs,
45-
or expected output file link is not present in session_files),
46-
you MUST return finished=false and explain what information is missing in reason.
47-
5) If there are contradictions in history_steps, prefer the later entries. If you still cannot decide, return finished=false
48-
and explain the contradiction in reason.
49-
6) Do NOT assume results that are not explicitly supported by history_steps or session_files. Judge only from verifiable evidence.
50-
# Output Format (very important)
51-
You must output ONLY ONE JSON object that strictly matches this schema:
46+
1) Judge ONLY the user's final goal completion / stop condition, not whether all intermediate steps ran.
47+
48+
2) Deliverable type:
49+
- If a file artifact is required (PDF/DOCX/ZIP/code project/structure file, etc.), you MUST verify an appropriate OSS link exists in session_files; otherwise finished=false (unless Termination/Unachievable applies).
50+
- If in-chat content is required, verify the complete requested content already exists in history_steps outputs; otherwise finished=false (unless Termination/Unachievable applies).
51+
52+
3) If any critical step is failed/missing/running OR outputs are insufficient to prove completion, set finished=false (unless Termination/Unachievable applies).
53+
54+
4) Insufficient evidence => finished=false and state exactly what is missing (unless Termination/Unachievable applies).
55+
56+
5) Contradictions: prefer later entries; if still unclear => finished=false and explain contradiction (unless Termination/Unachievable applies).
57+
58+
6) Do NOT assume results not explicitly supported by history_steps/session_files.
59+
60+
6.1) For explicit parameter constraints, if ANY constraint is not explicitly evidenced, finished=false (unless Termination/Unachievable applies).
61+
62+
7) Suggestion-first achievability check (MUST APPLY BEFORE declaring finished=true for Termination/Unachievable):
63+
- Scan ALL history_steps for actionable suggestions.
64+
- If any actionable suggestion is not explicitly shown as attempted and exhausted, output finished=false.
65+
66+
8) Termination/Unachievable (STOP even though not done):
67+
You may output finished=true for Termination/Unachievable ONLY if:
68+
- The goal is NOT completed, AND
69+
- history_steps provide concrete evidence that no viable next action exists, AND
70+
- EVERY actionable history_steps[*].suggestion has been explicitly tried in later history_steps and still failed, leaving no remaining options.
71+
If ANY unresolved suggestion proposes a viable next action (e.g., change parameters, switch provider/tool, request missing info),
72+
you MUST output finished=false (the session should continue), unless the goal is already completed.
73+
74+
If you output finished=true (Termination/Unachievable), the reason MUST include:
75+
- "NOT completed" and
76+
- "cannot be completed / unachievable" and
77+
- the blocking evidence (specific failed steps / missing inputs).
78+
79+
You MUST NOT output finished=true (Termination/Unachievable) when the only blocking evidence is that a tool failed once and the agent has not yet tried actionable suggestions (e.g., switching provider/tool, changing parameters). In that case, output finished=false.
80+
81+
# Output Format
82+
Output ONLY ONE JSON object exactly:
5283
{{
5384
"finished": true|false,
54-
"reason": "A brief, specific explanation in English that cites key evidence from history_steps and/or session_files (e.g., a tool_name status/output or the presence/absence of an OSS link). If not finished, state the critical blocking reason(s) or missing info."
85+
"reason": "Brief, specific English explanation citing concrete evidence from history_steps and/or session_files. If using Termination/Unachievable, explicitly state: NOT completed but cannot be completed, and cite the blocking evidence."
5586
}}
87+
5688
# Output Constraints
57-
- Output ONLY valid JSON (no Markdown, no code fences, no extra commentary).
58-
- reason must be an English string and should reference concrete evidence from history_steps and/or session_files.
89+
- Output ONLY valid JSON (no Markdown / code fences / extra text).
5990
""".strip()

0 commit comments

Comments
 (0)