veadk-python 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of veadk-python might be problematic. Click here for more details.
- veadk/__init__.py +31 -0
- veadk/a2a/__init__.py +13 -0
- veadk/a2a/agent_card.py +45 -0
- veadk/a2a/remote_ve_agent.py +19 -0
- veadk/a2a/ve_a2a_server.py +77 -0
- veadk/a2a/ve_agent_executor.py +78 -0
- veadk/a2a/ve_task_store.py +37 -0
- veadk/agent.py +253 -0
- veadk/cli/__init__.py +13 -0
- veadk/cli/main.py +278 -0
- veadk/cli/services/agentpilot/__init__.py +17 -0
- veadk/cli/services/agentpilot/agentpilot.py +77 -0
- veadk/cli/services/veapig/__init__.py +17 -0
- veadk/cli/services/veapig/apig.py +224 -0
- veadk/cli/services/veapig/apig_utils.py +332 -0
- veadk/cli/services/vefaas/__init__.py +17 -0
- veadk/cli/services/vefaas/template/deploy.py +44 -0
- veadk/cli/services/vefaas/template/src/app.py +30 -0
- veadk/cli/services/vefaas/template/src/config.py +58 -0
- veadk/cli/services/vefaas/vefaas.py +346 -0
- veadk/cli/services/vefaas/vefaas_utils.py +408 -0
- veadk/cli/services/vetls/__init__.py +17 -0
- veadk/cli/services/vetls/vetls.py +87 -0
- veadk/cli/studio/__init__.py +13 -0
- veadk/cli/studio/agent_processor.py +247 -0
- veadk/cli/studio/fast_api.py +232 -0
- veadk/cli/studio/model.py +116 -0
- veadk/cloud/__init__.py +13 -0
- veadk/cloud/cloud_agent_engine.py +144 -0
- veadk/cloud/cloud_app.py +123 -0
- veadk/cloud/template/app.py +30 -0
- veadk/cloud/template/config.py +55 -0
- veadk/config.py +131 -0
- veadk/consts.py +17 -0
- veadk/database/__init__.py +17 -0
- veadk/database/base_database.py +45 -0
- veadk/database/database_factory.py +80 -0
- veadk/database/kv/__init__.py +13 -0
- veadk/database/kv/redis_database.py +109 -0
- veadk/database/local_database.py +43 -0
- veadk/database/relational/__init__.py +13 -0
- veadk/database/relational/mysql_database.py +114 -0
- veadk/database/vector/__init__.py +13 -0
- veadk/database/vector/opensearch_vector_database.py +205 -0
- veadk/database/vector/type.py +50 -0
- veadk/database/viking/__init__.py +13 -0
- veadk/database/viking/viking_database.py +378 -0
- veadk/database/viking/viking_memory_db.py +521 -0
- veadk/evaluation/__init__.py +17 -0
- veadk/evaluation/adk_evaluator/__init__.py +13 -0
- veadk/evaluation/adk_evaluator/adk_evaluator.py +291 -0
- veadk/evaluation/base_evaluator.py +242 -0
- veadk/evaluation/deepeval_evaluator/__init__.py +17 -0
- veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +223 -0
- veadk/evaluation/eval_set_file_loader.py +28 -0
- veadk/evaluation/eval_set_recorder.py +91 -0
- veadk/evaluation/utils/prometheus.py +142 -0
- veadk/knowledgebase/__init__.py +17 -0
- veadk/knowledgebase/knowledgebase.py +83 -0
- veadk/knowledgebase/knowledgebase_database_adapter.py +259 -0
- veadk/memory/__init__.py +13 -0
- veadk/memory/long_term_memory.py +119 -0
- veadk/memory/memory_database_adapter.py +235 -0
- veadk/memory/short_term_memory.py +124 -0
- veadk/memory/short_term_memory_processor.py +90 -0
- veadk/prompts/__init__.py +13 -0
- veadk/prompts/agent_default_prompt.py +30 -0
- veadk/prompts/prompt_evaluator.py +20 -0
- veadk/prompts/prompt_memory_processor.py +55 -0
- veadk/prompts/prompt_optimization.py +158 -0
- veadk/runner.py +252 -0
- veadk/tools/__init__.py +13 -0
- veadk/tools/builtin_tools/__init__.py +13 -0
- veadk/tools/builtin_tools/lark.py +67 -0
- veadk/tools/builtin_tools/las.py +23 -0
- veadk/tools/builtin_tools/vesearch.py +49 -0
- veadk/tools/builtin_tools/web_scraper.py +76 -0
- veadk/tools/builtin_tools/web_search.py +192 -0
- veadk/tools/demo_tools.py +58 -0
- veadk/tools/load_knowledgebase_tool.py +144 -0
- veadk/tools/sandbox/__init__.py +13 -0
- veadk/tools/sandbox/browser_sandbox.py +27 -0
- veadk/tools/sandbox/code_sandbox.py +30 -0
- veadk/tools/sandbox/computer_sandbox.py +27 -0
- veadk/tracing/__init__.py +13 -0
- veadk/tracing/base_tracer.py +172 -0
- veadk/tracing/telemetry/__init__.py +13 -0
- veadk/tracing/telemetry/exporters/__init__.py +13 -0
- veadk/tracing/telemetry/exporters/apiserver_exporter.py +60 -0
- veadk/tracing/telemetry/exporters/apmplus_exporter.py +101 -0
- veadk/tracing/telemetry/exporters/base_exporter.py +28 -0
- veadk/tracing/telemetry/exporters/cozeloop_exporter.py +69 -0
- veadk/tracing/telemetry/exporters/inmemory_exporter.py +88 -0
- veadk/tracing/telemetry/exporters/tls_exporter.py +78 -0
- veadk/tracing/telemetry/metrics/__init__.py +13 -0
- veadk/tracing/telemetry/metrics/opentelemetry_metrics.py +73 -0
- veadk/tracing/telemetry/opentelemetry_tracer.py +167 -0
- veadk/types.py +23 -0
- veadk/utils/__init__.py +13 -0
- veadk/utils/logger.py +59 -0
- veadk/utils/misc.py +33 -0
- veadk/utils/patches.py +85 -0
- veadk/utils/volcengine_sign.py +199 -0
- veadk/version.py +15 -0
- veadk_python-0.1.0.dist-info/METADATA +124 -0
- veadk_python-0.1.0.dist-info/RECORD +110 -0
- veadk_python-0.1.0.dist-info/WHEEL +5 -0
- veadk_python-0.1.0.dist-info/entry_points.txt +2 -0
- veadk_python-0.1.0.dist-info/licenses/LICENSE +201 -0
- veadk_python-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,124 @@
|
|
|
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 os
|
|
16
|
+
from typing import Literal
|
|
17
|
+
|
|
18
|
+
from google.adk.sessions import DatabaseSessionService, InMemorySessionService
|
|
19
|
+
|
|
20
|
+
from veadk.config import getenv
|
|
21
|
+
from veadk.utils.logger import get_logger
|
|
22
|
+
|
|
23
|
+
from .short_term_memory_processor import ShortTermMemoryProcessor
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
DEFAULT_LOCAL_DATABASE_PATH = "/tmp/veadk_local_database.db"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ShortTermMemory:
|
|
31
|
+
"""
|
|
32
|
+
Short term memory class.
|
|
33
|
+
|
|
34
|
+
This class is used to store short term memory.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
backend: Literal["local", "database", "mysql"] = "local",
|
|
40
|
+
db_url: str = "",
|
|
41
|
+
enable_memory_optimization: bool = False,
|
|
42
|
+
):
|
|
43
|
+
self.backend = backend
|
|
44
|
+
self.db_url = db_url
|
|
45
|
+
|
|
46
|
+
if self.backend == "mysql":
|
|
47
|
+
host = getenv("DATABASE_MYSQL_HOST")
|
|
48
|
+
user = getenv("DATABASE_MYSQL_USER")
|
|
49
|
+
password = getenv("DATABASE_MYSQL_PASSWORD")
|
|
50
|
+
database = getenv("DATABASE_MYSQL_DATABASE")
|
|
51
|
+
db_url = f"mysql+pymysql://{user}:{password}@{host}/{database}"
|
|
52
|
+
|
|
53
|
+
self.db_url = db_url
|
|
54
|
+
self.backend = "database"
|
|
55
|
+
|
|
56
|
+
if self.backend == "local":
|
|
57
|
+
logger.warning(
|
|
58
|
+
f"Short term memory backend: {self.backend}, the history will be lost after application shutdown."
|
|
59
|
+
)
|
|
60
|
+
self.session_service = InMemorySessionService()
|
|
61
|
+
elif self.backend == "database":
|
|
62
|
+
if self.db_url == "" or self.db_url is None:
|
|
63
|
+
logger.warning(
|
|
64
|
+
f"The `db_url` {self.db_url} is an empty or None string."
|
|
65
|
+
)
|
|
66
|
+
self._use_default_database()
|
|
67
|
+
else:
|
|
68
|
+
try:
|
|
69
|
+
self.session_service = DatabaseSessionService(db_url=self.db_url)
|
|
70
|
+
logger.info("Connected to database.")
|
|
71
|
+
except Exception as e:
|
|
72
|
+
logger.error(
|
|
73
|
+
f"Failed to connect to database {self.db_url}, error: {e}."
|
|
74
|
+
)
|
|
75
|
+
self._use_default_database()
|
|
76
|
+
else:
|
|
77
|
+
raise ValueError(f"Unknown short term memory backend: {self.backend}")
|
|
78
|
+
|
|
79
|
+
if enable_memory_optimization and backend == "database":
|
|
80
|
+
self.processor = ShortTermMemoryProcessor()
|
|
81
|
+
intercept_get_session = self.processor.patch()
|
|
82
|
+
self.session_service.get_session = intercept_get_session(
|
|
83
|
+
self.session_service.get_session
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
def _use_default_database(self):
|
|
87
|
+
self.db_url = DEFAULT_LOCAL_DATABASE_PATH
|
|
88
|
+
logger.info(f"Using default local database {self.db_url}")
|
|
89
|
+
if not os.path.exists(self.db_url):
|
|
90
|
+
self.create_local_sqlite3_db(self.db_url)
|
|
91
|
+
self.session_service = DatabaseSessionService(db_url="sqlite:///" + self.db_url)
|
|
92
|
+
|
|
93
|
+
def create_local_sqlite3_db(self, path: str):
|
|
94
|
+
import sqlite3
|
|
95
|
+
|
|
96
|
+
conn = sqlite3.connect(path)
|
|
97
|
+
conn.close()
|
|
98
|
+
logger.debug(f"Create local sqlite3 database {path} done.")
|
|
99
|
+
|
|
100
|
+
async def create_session(
|
|
101
|
+
self,
|
|
102
|
+
app_name: str,
|
|
103
|
+
user_id: str,
|
|
104
|
+
session_id: str,
|
|
105
|
+
):
|
|
106
|
+
if isinstance(self.session_service, DatabaseSessionService):
|
|
107
|
+
list_sessions_response = await self.session_service.list_sessions(
|
|
108
|
+
app_name=app_name, user_id=user_id
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
logger.debug(
|
|
112
|
+
f"Loaded {len(list_sessions_response.sessions)} sessions from db {self.db_url}."
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if (
|
|
116
|
+
await self.session_service.get_session(
|
|
117
|
+
app_name=app_name, user_id=user_id, session_id=session_id
|
|
118
|
+
)
|
|
119
|
+
is None
|
|
120
|
+
):
|
|
121
|
+
# create a new session for this running
|
|
122
|
+
await self.session_service.create_session(
|
|
123
|
+
app_name=app_name, user_id=user_id, session_id=session_id
|
|
124
|
+
)
|
|
@@ -0,0 +1,90 @@
|
|
|
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 functools
|
|
16
|
+
import json
|
|
17
|
+
|
|
18
|
+
from google.adk.events.event import Event
|
|
19
|
+
from google.adk.sessions import Session
|
|
20
|
+
from google.genai.types import Content, Part
|
|
21
|
+
from litellm import completion
|
|
22
|
+
|
|
23
|
+
from veadk.config import getenv
|
|
24
|
+
from veadk.prompts.prompt_memory_processor import render_prompt
|
|
25
|
+
from veadk.utils.logger import get_logger
|
|
26
|
+
|
|
27
|
+
logger = get_logger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ShortTermMemoryProcessor:
|
|
31
|
+
def __init__(self) -> None: ...
|
|
32
|
+
|
|
33
|
+
def patch(self):
|
|
34
|
+
"""Patch the `get_session` function"""
|
|
35
|
+
|
|
36
|
+
def intercept_get_session(func):
|
|
37
|
+
@functools.wraps(func)
|
|
38
|
+
async def wrapper(*args, **kwargs):
|
|
39
|
+
session = await func(*args, **kwargs)
|
|
40
|
+
if session:
|
|
41
|
+
abstracted_session = self.after_load_session(session)
|
|
42
|
+
else:
|
|
43
|
+
abstracted_session = session
|
|
44
|
+
return abstracted_session
|
|
45
|
+
|
|
46
|
+
return wrapper
|
|
47
|
+
|
|
48
|
+
return intercept_get_session
|
|
49
|
+
|
|
50
|
+
def after_load_session(self, session: Session) -> Session:
|
|
51
|
+
messages = []
|
|
52
|
+
for event in session.events:
|
|
53
|
+
content = event.content
|
|
54
|
+
message = {
|
|
55
|
+
"role": content.role,
|
|
56
|
+
"content": content.parts[0].text,
|
|
57
|
+
}
|
|
58
|
+
messages.append(message)
|
|
59
|
+
|
|
60
|
+
prompt = render_prompt(messages=str(messages))
|
|
61
|
+
res = completion(
|
|
62
|
+
model=getenv("MODEL_AGENT_PROVIDER") + "/" + getenv("MODEL_AGENT_NAME"),
|
|
63
|
+
base_url=getenv("MODEL_AGENT_API_BASE"),
|
|
64
|
+
api_key=getenv("MODEL_AGENT_API_KEY"),
|
|
65
|
+
messages=[
|
|
66
|
+
{
|
|
67
|
+
"role": "user",
|
|
68
|
+
"content": prompt,
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
)
|
|
72
|
+
extracted_messages = json.loads(res.choices[0].message.content)
|
|
73
|
+
logger.debug(f"Abstracted messages: {extracted_messages}")
|
|
74
|
+
|
|
75
|
+
session.events = []
|
|
76
|
+
for message in extracted_messages:
|
|
77
|
+
session.events.append(
|
|
78
|
+
Event(
|
|
79
|
+
author="memory_optimizer",
|
|
80
|
+
content=Content(
|
|
81
|
+
role=message["role"],
|
|
82
|
+
parts=[
|
|
83
|
+
Part(
|
|
84
|
+
text=message["content"],
|
|
85
|
+
)
|
|
86
|
+
],
|
|
87
|
+
),
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
return session
|
|
@@ -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.
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
DEFAULT_INSTRUCTION = """You an AI agent created by the VeADK team.
|
|
16
|
+
|
|
17
|
+
You excel at the following tasks:
|
|
18
|
+
1. Data science
|
|
19
|
+
- Information gathering and fact-checking
|
|
20
|
+
- Data processing and analysis
|
|
21
|
+
2. Documentation
|
|
22
|
+
- Writing multi-chapter articles and in-depth research reports
|
|
23
|
+
3. Coding & Programming
|
|
24
|
+
- Creating websites, applications, and tools
|
|
25
|
+
- Solve problems and bugs in code (e.g., Python, JavaScript, SQL, ...)
|
|
26
|
+
- If necessary, using programming to solve various problems beyond development
|
|
27
|
+
4. If user gives you tools, finish various tasks that can be accomplished using tools and available resources
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
DEFAULT_DESCRIPTION = """An AI agent developed by the VeADK team, specialized in data science, documentation, and software development."""
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
eval_principle_prompt = """
|
|
16
|
+
You are a LLM for evaluating other models' responses. Note:
|
|
17
|
+
- The response maybe generated by some uncertainty tools (e.g., online-search, random number), you just need to consider whether the response is human-readable, rather than focus on the specific content. Because the specific content maybe different at different time.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
criteria_prompt = "Determine whether the actual output is factually correct based on the expected output."
|
|
@@ -0,0 +1,55 @@
|
|
|
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 jinja2 import Template
|
|
16
|
+
|
|
17
|
+
MEMORY_PROCESSOR_SYSTEM_PROMPT = """I will give you a series of messages of memory, including messages from user and assistant.
|
|
18
|
+
|
|
19
|
+
You should help me to recognize important information from the messages, and build some new messages.
|
|
20
|
+
|
|
21
|
+
For example, for the following messages:
|
|
22
|
+
[
|
|
23
|
+
{
|
|
24
|
+
"role": "user",
|
|
25
|
+
"content": "Hello, tell me the weather of Beijing, and remember my secret is `abc001`"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"role": "assistant",
|
|
29
|
+
"content": "The weather of Beijing is sunny, and the temperature is 25 degree Celsius. I have remember that your secret is `abc001`."
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
You should extract the important information from the messages, and build new messages if needed (in JSON format):
|
|
34
|
+
[
|
|
35
|
+
{
|
|
36
|
+
"role": "user",
|
|
37
|
+
"content": "My secret is `abc001`."
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
The actual messages are:
|
|
42
|
+
{{ messages }}
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def render_prompt(messages: list[dict]):
|
|
47
|
+
template = Template(MEMORY_PROCESSOR_SYSTEM_PROMPT)
|
|
48
|
+
|
|
49
|
+
context = {
|
|
50
|
+
"messages": messages,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
rendered_prompt = template.render(context)
|
|
54
|
+
|
|
55
|
+
return rendered_prompt
|
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
"""
|
|
16
|
+
This file is used to optimize prompt in AgentPilot.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import asyncio
|
|
22
|
+
from typing import Callable
|
|
23
|
+
|
|
24
|
+
from google.adk.tools import FunctionTool
|
|
25
|
+
from google.adk.tools.mcp_tool import MCPToolset
|
|
26
|
+
from jinja2 import Template
|
|
27
|
+
|
|
28
|
+
from veadk import Agent
|
|
29
|
+
|
|
30
|
+
# prompt = """
|
|
31
|
+
# <role>
|
|
32
|
+
# An experienced prompt optimizer.
|
|
33
|
+
# </role>
|
|
34
|
+
|
|
35
|
+
# <task>
|
|
36
|
+
# Please optimize prompt to make it more efficient.
|
|
37
|
+
# The prompt will be used as a system prompt and instruction of an agent.
|
|
38
|
+
# The definition and context (i.e., tools) of the agent will be provided.
|
|
39
|
+
# </task>
|
|
40
|
+
|
|
41
|
+
# <agent_info>
|
|
42
|
+
# name: {{ agent.name }}
|
|
43
|
+
# model: {{ agent.model }}
|
|
44
|
+
# description: {{ agent.description }}
|
|
45
|
+
# </agent_info>
|
|
46
|
+
|
|
47
|
+
# <agent_tools_info>
|
|
48
|
+
# {% for tool in tools %}
|
|
49
|
+
# <tool>
|
|
50
|
+
# name: {{ tool.name }}
|
|
51
|
+
# type: {{ tool.type }}
|
|
52
|
+
# description: {{ tool.description }}
|
|
53
|
+
# arguments: {{ tool.arguments }}
|
|
54
|
+
# </tool>
|
|
55
|
+
# {% endfor %}
|
|
56
|
+
# </agent_tools_info>
|
|
57
|
+
# """.strip()
|
|
58
|
+
|
|
59
|
+
prompt = """
|
|
60
|
+
Please help me to optimize the following agent prompt:
|
|
61
|
+
{{ original_prompt }}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
The following information is your references:
|
|
65
|
+
<agent_info>
|
|
66
|
+
name: {{ agent.name }}
|
|
67
|
+
model: {{ agent.model }}
|
|
68
|
+
description: {{ agent.description }}
|
|
69
|
+
</agent_info>
|
|
70
|
+
|
|
71
|
+
<agent_tools_info>
|
|
72
|
+
{% for tool in tools %}
|
|
73
|
+
<tool>
|
|
74
|
+
name: {{ tool.name }}
|
|
75
|
+
type: {{ tool.type }}
|
|
76
|
+
description: {{ tool.description }}
|
|
77
|
+
arguments: {{ tool.arguments }}
|
|
78
|
+
</tool>
|
|
79
|
+
{% endfor %}
|
|
80
|
+
</agent_tools_info>
|
|
81
|
+
|
|
82
|
+
Please note that in your optimized prompt:
|
|
83
|
+
- the above referenced information is not necessary. For example, the tools list of agent is not necessary in the optimized prompt, because it maybe too long. You should use the tool information to optimize the original prompt rather than simply add tool list in prompt.
|
|
84
|
+
- The max length of optimized prompt should be less 4096 tokens.
|
|
85
|
+
""".strip()
|
|
86
|
+
|
|
87
|
+
prompt_with_feedback = """
|
|
88
|
+
After you optimization, my current prompt is:
|
|
89
|
+
{{ prompt }}
|
|
90
|
+
|
|
91
|
+
I did some evaluations with the optimized prompt, and the feedback is: {{ feedback }}
|
|
92
|
+
|
|
93
|
+
Please continue to optimize the prompt based on the feedback.
|
|
94
|
+
""".strip()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def render_prompt_feedback_with_jinja2(agent: Agent, feedback: str):
|
|
98
|
+
template = Template(prompt_with_feedback)
|
|
99
|
+
|
|
100
|
+
context = {
|
|
101
|
+
"prompt": agent.instruction,
|
|
102
|
+
"feedback": feedback,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
rendered_prompt = template.render(context)
|
|
106
|
+
|
|
107
|
+
return rendered_prompt
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def render_prompt_with_jinja2(agent: Agent):
|
|
111
|
+
template = Template(prompt)
|
|
112
|
+
|
|
113
|
+
tools = []
|
|
114
|
+
for tool in agent.tools:
|
|
115
|
+
if isinstance(tool, Callable):
|
|
116
|
+
type = "function"
|
|
117
|
+
|
|
118
|
+
_tool = FunctionTool(tool)
|
|
119
|
+
tools.append(
|
|
120
|
+
{
|
|
121
|
+
"name": _tool.name,
|
|
122
|
+
"description": _tool.description,
|
|
123
|
+
"arguments": str(
|
|
124
|
+
_tool._get_declaration().model_dump()["parameters"]
|
|
125
|
+
),
|
|
126
|
+
"type": type,
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
elif isinstance(tool, MCPToolset):
|
|
130
|
+
type = "tool"
|
|
131
|
+
|
|
132
|
+
_tools = asyncio.run(tool.get_tools())
|
|
133
|
+
for _tool in _tools:
|
|
134
|
+
tools.append(
|
|
135
|
+
{
|
|
136
|
+
"name": _tool.name,
|
|
137
|
+
"description": _tool.description,
|
|
138
|
+
"arguments": str(
|
|
139
|
+
_tool._get_declaration().model_dump()["parameters"]
|
|
140
|
+
),
|
|
141
|
+
"type": type,
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
context = {
|
|
146
|
+
"original_prompt": agent.instruction,
|
|
147
|
+
"agent": {
|
|
148
|
+
"name": agent.name,
|
|
149
|
+
"model": agent.model_name,
|
|
150
|
+
"description": agent.description,
|
|
151
|
+
# "tools": str(agent.tools),
|
|
152
|
+
},
|
|
153
|
+
"tools": tools,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
rendered_prompt = template.render(context)
|
|
157
|
+
|
|
158
|
+
return rendered_prompt
|