From ca190fb37028394045a3328488eb1da458a50f5c Mon Sep 17 00:00:00 2001 From: weimch Date: Mon, 6 Jul 2026 12:10:43 +0800 Subject: [PATCH] =?UTF-8?q?Bugfix:=20=E4=BF=AE=E5=A4=8DGraphAgent=E4=B8=AD?= =?UTF-8?q?AgentNode=E7=9A=84last=5Fresponse=E8=A2=AB=E8=AE=BE=E4=B8=BA?= =?UTF-8?q?=E3=80=8C=E6=80=9D=E8=80=83/=E4=B8=AD=E9=97=B4=E8=BD=AE?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E3=80=8D=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 原因:没有移除思考内容及做中间轮工具调用Event的检测 - 解决方案:使用Event.is_final_response保证是LLM最后一个结果,然后移除最后一个结果的思考内容 --- .../dsl/graph/_node_action/_agent.py | 18 ++++++++++++------ trpc_agent_sdk/dsl/graph/_node_action/_llm.py | 4 +++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/trpc_agent_sdk/dsl/graph/_node_action/_agent.py b/trpc_agent_sdk/dsl/graph/_node_action/_agent.py index adf1e7a7..85d064dc 100644 --- a/trpc_agent_sdk/dsl/graph/_node_action/_agent.py +++ b/trpc_agent_sdk/dsl/graph/_node_action/_agent.py @@ -181,11 +181,17 @@ async def execute(self, state: State) -> dict[str, Any]: if isinstance(candidate, str) and candidate: last_response = candidate - if (not self._is_graph_event(event)) and ( - not event.partial) and event.content and event.content.parts: - text_parts = [part.text for part in event.content.parts if part.text] - if text_parts: - last_response = text_parts[-1] + if (not self._is_graph_event(event)) and event.is_final_response(): + # Only clean final answers may become last_response. Skip + # thought parts (part.thought) so a thinking model's + # reasoning monologue is never surfaced as the answer. + # is_final_response() already excludes partial, function + # call/response, and code-execution events, so plan and + # transfer_to_agent rounds are naturally ignored. + if event.content and event.content.parts: + visible_text = [part.text for part in event.content.parts if part.text and not part.thought] + if visible_text: + last_response = "".join(visible_text) if not event.visible: if event.actions and event.actions.transfer_to_agent: @@ -246,7 +252,7 @@ async def execute(self, state: State) -> dict[str, Any]: node_response: Any = last_response structured_output: Any = None - if isinstance(self.agent, LlmAgent) and self.agent.output_schema is not None: + if isinstance(self.agent, LlmAgent) and self.agent.output_schema is not None and last_response: node_response = json.loads(last_response) structured_output = node_response diff --git a/trpc_agent_sdk/dsl/graph/_node_action/_llm.py b/trpc_agent_sdk/dsl/graph/_node_action/_llm.py index 631e4d2a..4c0bcb16 100644 --- a/trpc_agent_sdk/dsl/graph/_node_action/_llm.py +++ b/trpc_agent_sdk/dsl/graph/_node_action/_llm.py @@ -251,7 +251,9 @@ async def _run_model_round( continue response_parts = list(llm_response.content.parts) - text_parts = [part.text for part in response_parts if part.text] + # Exclude thought parts so a thinking model's reasoning does not + # leak into response_text / STATE_KEY_LAST_RESPONSE. + text_parts = [part.text for part in response_parts if part.text and not part.thought] response_text = "".join(text_parts) logger.debug(f"[{self.name}] LLM response received ({len(response_text)} chars)")