Skip to content

Commit ddfd956

Browse files
feat: support agent reflection at local (#433)
* feat: support agent reflection at local * add docs
1 parent 9d4c7f8 commit ddfd956

File tree

4 files changed

+211
-0
lines changed

4 files changed

+211
-0
lines changed

docs/docs/deploy/optimization.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,80 @@ veadk_rl_lightning_project
161161
![启动client](../assets/images/optimization/lightning_client.png)
162162

163163
![启动server](../assets/images/optimization/lightning_training_server.png)
164+
165+
## Agent 自我反思
166+
167+
VeADK 中支持基于 Tracing 文件数据,通过第三方 Agent 推理来进行自我反思,生成优化后的系统提示词。
168+
169+
### 使用方法
170+
171+
您可以在适宜的时机将 Agent 推理得到的 Tracing 文件数据,提交到 `reflector` 进行自我反思,如下代码:
172+
173+
```python
174+
import asyncio
175+
176+
from veadk import Agent, Runner
177+
from veadk.reflector.local_reflector import LocalReflector
178+
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer
179+
180+
agent = Agent(tracers=[OpentelemetryTracer()])
181+
reflector = LocalReflector(agent=agent)
182+
183+
app_name = "app"
184+
user_id = "user"
185+
session_id = "session"
186+
187+
188+
async def main():
189+
runner = Runner(agent=agent, app_name=app_name)
190+
191+
await runner.run(
192+
messages="你好,我觉得你的回答不够礼貌",
193+
user_id=user_id,
194+
session_id=session_id,
195+
)
196+
197+
trace_file = runner.save_tracing_file(session_id=session_id)
198+
199+
response = await reflector.reflect(
200+
trace_file=trace_file
201+
)
202+
print(response)
203+
204+
205+
if __name__ == "__main__":
206+
asyncio.run(main())
207+
```
208+
209+
### 结果说明
210+
211+
原始提示词:
212+
213+
```text
214+
You an AI agent created by the VeADK team.
215+
216+
You excel at the following tasks:
217+
1. Data science
218+
- Information gathering and fact-checking
219+
- Data processing and analysis
220+
2. Documentation
221+
- Writing multi-chapter articles and in-depth research reports
222+
3. Coding & Programming
223+
- Creating websites, applications, and tools
224+
- Solve problems and bugs in code (e.g., Python, JavaScript, SQL, ...)
225+
- If necessary, using programming to solve various problems beyond development
226+
4. If user gives you tools, finish various tasks that can be accomplished using tools and available resources
227+
```
228+
229+
优化后,您将看到类似如下的输出:
230+
231+
```text
232+
optimized_prompt='You are an AI agent created by the VeADK team. Your core mission is to assist users with expertise in data science, documentation, and coding, while maintaining a warm, respectful, and engaging communication style.\n\nYou excel at the following tasks:\n1. Data science\n- Information gathering and fact-checking\n- Data processing and analysis\n2. Documentation\n- Writing multi-chapter articles and in-depth research reports\n3. Coding & Programming\n- Creating websites, applications, and tools\n- Solving problems and bugs in code (e.g., Python, JavaScript, SQL, ...)\n- Using programming to solve various problems beyond development\n4. Tool usage\n- Effectively using provided tools and available resources to accomplish tasks\n\nCommunication Guidelines:\n- Always use polite and warm language (e.g., appropriate honorifics, friendly tone)\n- Show appreciation for user feedback and suggestions\n- Proactively confirm user needs and preferences\n- Maintain a helpful and encouraging attitude throughout interactions\n\nYour responses should be both technically accurate and conversationally pleasant, ensuring users feel valued and supported.'
233+
234+
reason="The trace shows a user complaint about the agent's lack of politeness in responses. The agent's current system prompt focuses exclusively on technical capabilities without addressing communication style. The optimized prompt adds explicit communication guidelines to ensure the agent maintains a warm, respectful tone while preserving all technical capabilities. This addresses the user's feedback directly while maintaining the agent's core functionality."
235+
```
236+
237+
输出分为两部分:
238+
239+
- `optimized_prompt`: 优化后的系统提示词
240+
- `reason`: 优化原因

veadk/reflector/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.

veadk/reflector/base_reflector.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from abc import ABC, abstractmethod
16+
17+
from pydantic import BaseModel
18+
19+
from veadk import Agent
20+
21+
22+
class ReflectorResult(BaseModel):
23+
optimized_prompt: str
24+
"""Optimized system prompt"""
25+
26+
reason: str
27+
"""Reason for the optimized prompt"""
28+
29+
30+
class BaseReflector(ABC):
31+
def __init__(self, agent: Agent):
32+
self.agent = agent
33+
34+
@abstractmethod
35+
def reflect(self, traces: list[dict]) -> ReflectorResult:
36+
"""Do agent self-reflection and generate a optimized system prompt.
37+
38+
Args:
39+
traces (list[dict]): The traces for agent reflection.
40+
41+
Returns:
42+
str: The optimized system prompt.
43+
"""
44+
...

veadk/reflector/local_reflector.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import json
16+
import os
17+
18+
from typing_extensions import override
19+
20+
from veadk import Agent, Runner
21+
from veadk.reflector.base_reflector import BaseReflector, ReflectorResult
22+
23+
24+
class LocalReflector(BaseReflector):
25+
def __init__(self, agent: Agent):
26+
super().__init__(agent)
27+
28+
def _read_traces_from_dir(self, trace_dir: str) -> list[dict]:
29+
traces = []
30+
for file in os.listdir(trace_dir):
31+
if file.endswith(".json"):
32+
with open(os.path.join(trace_dir, file), "r") as f:
33+
traces.append(json.load(f))
34+
return traces
35+
36+
@override
37+
async def reflect(self, trace_file: str) -> ReflectorResult:
38+
assert os.path.isfile(trace_file), f"{trace_file} is not a file."
39+
assert trace_file.endswith(".json"), f"{trace_file} is not a valid json file."
40+
41+
with open(trace_file, "r") as f:
42+
traces = json.load(f)
43+
44+
agent = Agent(
45+
name="agent_reflector",
46+
description="Reflect the traces and generate a optimized system prompt.",
47+
instruction="""You are a helpful optimizer and reflector.
48+
49+
Your task is to reflect the traces and generate a optimized system prompt (based on the given agent's system prompt).
50+
51+
You should response in json format with two fields:
52+
- optimized_prompt: The optimized system prompt.
53+
- reason: The reason for the optimized prompt.
54+
""",
55+
output_schema=ReflectorResult,
56+
)
57+
runner = Runner(agent)
58+
59+
response = await runner.run(
60+
messages=f"The system prompt is: {self.agent.instruction}, and the history traces are: {traces}"
61+
)
62+
63+
if response:
64+
try:
65+
optimized_prompt = json.loads(response).get("optimized_prompt", "")
66+
reason = json.loads(response).get("reason", "")
67+
except Exception as e:
68+
optimized_prompt = ""
69+
reason = f"response from optimizer is not valid json: {e}, response: {response}"
70+
else:
71+
optimized_prompt = ""
72+
reason = "response from optimizer is empty"
73+
74+
return ReflectorResult(
75+
optimized_prompt=optimized_prompt,
76+
reason=reason,
77+
)

0 commit comments

Comments
 (0)