From 43e34b2aba87c8eec5f56a7aec9610b3a27e0559 Mon Sep 17 00:00:00 2001 From: zhiao-G Date: Thu, 14 May 2026 14:15:02 +0800 Subject: [PATCH 1/2] feat(code_interpreter, docs, example): add ssl verify support and update examples - Added verify_ssl parameter to CodeInterpreter client, supporting SSL verification disabling or custom CA certificate path - Updated documentation and comments, adding SSL verification related parameter descriptions and usage examples - Fixed spelling errors in the file upload example - Refactored example code to adapt to the latest langgraph message handling approach --- docs/cn/sdk_user_guide/tools_user_guide.md | 19 ++++++- examples/agent_tools/README.md | 56 ++++++------------- examples/agent_tools/integrate_tools.py | 54 ++++++------------ src/agentarts/sdk/service/tools_http.py | 19 ++++--- .../code_interpreter_client.py | 23 ++++++-- 5 files changed, 82 insertions(+), 89 deletions(-) diff --git a/docs/cn/sdk_user_guide/tools_user_guide.md b/docs/cn/sdk_user_guide/tools_user_guide.md index aecb4cd..55196c5 100644 --- a/docs/cn/sdk_user_guide/tools_user_guide.md +++ b/docs/cn/sdk_user_guide/tools_user_guide.md @@ -141,7 +141,7 @@ CodeInterpreter ### 初始化 ```python -CodeInterpreter(region: Optional[str] = None, data_endpoint: Optional[str] = None, auth_type: str = "API_KEY") +CodeInterpreter(region: Optional[str] = None, data_endpoint: Optional[str] = None, auth_type: str = "API_KEY", verify_ssl: Union[bool, str] = True) ``` **参数说明**: @@ -151,6 +151,7 @@ CodeInterpreter(region: Optional[str] = None, data_endpoint: Optional[str] = Non | region | str | 否 | 从环境变量获取 | 华为云区域名称 | | data_endpoint | str | 否 | 从环境变量获取 | 数据面端点,优先从环境变量 AGENTARTS_CODEINTERPRETER_DATA_ENDPOINT 读取 | | auth_type | str | 否 | "API_KEY" | 认证类型,支持 "API_KEY" 或 "IAM" | +| verify_ssl | bool \| str | 否 | True | 是否验证服务器的 SSL 证书,如果为字符串则作为 CA 证书包路径 | **使用示例**: @@ -169,6 +170,18 @@ client = CodeInterpreter( region="cn-southwest-2", auth_type="IAM" ) + +# 禁用 SSL 证书验证(不推荐用于生产环境) +client = CodeInterpreter( + region="cn-southwest-2", + verify_ssl=False +) + +# 使用自定义 CA 证书包 +client = CodeInterpreter( + region="cn-southwest-2", + verify_ssl="/path/to/ca-bundle.crt" +) ``` ### 功能特性 @@ -524,8 +537,8 @@ result[Dict]: 包含文件上传结果的字典 # 上传CSV文件 result = client.upload_file( path="/home/user/my-file.csv", - content="data, revenue\n2026-01-01, 1000\n2026-01-02, 2000", - description='Daily sales data with columns: data, revenue' + content="date, revenue\n2026-01-01, 1000\n2026-01-02, 2000", + description='Daily sales data with columns: date, revenue' ) ``` diff --git a/examples/agent_tools/README.md b/examples/agent_tools/README.md index f22e6da..d6ef7c2 100644 --- a/examples/agent_tools/README.md +++ b/examples/agent_tools/README.md @@ -26,12 +26,13 @@ pip install -r requirements.txt ```python import json import os -from typing import TypedDict +from typing import Annotated, TypedDict -from langchain_core.messages import AIMessage, HumanMessage, SystemMessage +from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, BaseMessage from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langgraph.graph import END, StateGraph +from langgraph.graph.message import add_messages from langgraph.prebuilt import ToolNode from agentarts.sdk import AgentArtsRuntimeApp @@ -42,37 +43,16 @@ from agentarts.sdk.tools import code_session 定义Agent的行为和能力 ```python app = AgentArtsRuntimeApp() -SYSTEM_PROMPT = """你是一个优秀的AI助手,擅长通过代码执行验证答案的正确性。 - -验证原则: -1. 当需要精确计算、数值验证或算法验证时,必须编写代码来验证结果 -2. 使用execute_python_tool工具执行代码进行验证 -3. 返回答案前,使用测试脚本来验证你的理解和计算 -4. 只能通过实际的代码执行展示工作过程 -5. 如果存在不确定的情况,详细说明限制条件并尽可能做验证 - -需要代码验证的场景 -- 数学计算:包括算术运算、代数计算、概率统计、数列求和、几何计算等 -- 算法验证:需要验证算法正确性,实现逻辑或性能测试时 -- 数据处理:对数据进行统计分析、排序、查找等操作时 -- 任何需要精确结果的问题,当口算或者估算无法保证准确性时 - -强制要求: -- 你必须使用execute_python_tool工具来执行python代码 -- 涉及计算的问题,编写程序计算并显示代码和结果 -- 每次给出最终答案前,至少执行一次验证代码 -- 如果工具调用失败,明确告知用户 -- 将代码执行结果作为答案的重要依据 +SYSTEM_PROMPT = """你是一个AI助手,可以使用Python代码执行工具来解决问题。 可用工具: -- execute_python_tool(code: str, description: str): 在沙箱环境中执行Python代码并返回结果 - * code: 要执行的Python代码 - * description: 对代码的描述,用于上下文理解 - -响应格式要求: -- 优先展示验证代码和执行结果 -- 清晰说明每一步的计算逻辑 -- 最终答案必须基于代码执行结果 +- execute_python_tool(code: str, description: str): 执行Python代码 + +使用原则: +1. 仅在需要精确计算或复杂逻辑时使用工具 +2. 简单问题直接回答,无需工具验证 +3. 工具调用最多1-2次,避免重复验证 +4. 获得结果后立即返回答案 """ ``` @@ -125,7 +105,7 @@ llm = llm.bind_tools(tools) # 定义graph状态 class AgentState(TypedDict): - messages: list[HumanMessage | SystemMessage | AIMessage] + messages: Annotated[list[BaseMessage], add_messages] def call_model(state: AgentState): @@ -145,11 +125,11 @@ def should_continue(state): """判断是否继续使用工具""" last_message = state["messages"][-1] - # 如果包含工具调用,则继续执行 - if isinstance(last_message, AIMessage) and last_message.tool_calls: - return "tools" + if isinstance(last_message, AIMessage): + has_tool_calls = bool(last_message.tool_calls) + if has_tool_calls: + return "tools" - # 否则结束 return END @@ -176,13 +156,13 @@ query = "告诉我1到100之间最大的质数" ## 6. Agent执行与响应 ```python @app.entrypoint -def agent_chat(): +def agent_chat(payload: dict): query = "告诉我1到100之间最大的质数" # 运行Agent result = agent.invoke({"messages": [HumanMessage(content=query)]}) - print(result["messages"][-1].content) + return result["messages"][-1].content if __name__ == "__main__": diff --git a/examples/agent_tools/integrate_tools.py b/examples/agent_tools/integrate_tools.py index 12f82fb..d2f65c3 100644 --- a/examples/agent_tools/integrate_tools.py +++ b/examples/agent_tools/integrate_tools.py @@ -1,48 +1,28 @@ import json import os -from typing import TypedDict +from typing import Annotated, TypedDict -from langchain_core.messages import AIMessage, HumanMessage, SystemMessage +from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, BaseMessage from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langgraph.graph import END, StateGraph +from langgraph.graph.message import add_messages from langgraph.prebuilt import ToolNode from agentarts.sdk import AgentArtsRuntimeApp from agentarts.sdk.tools import code_session app = AgentArtsRuntimeApp() -SYSTEM_PROMPT = """你是一个优秀的AI助手,擅长通过代码执行验证答案的正确性。 - -验证原则: -1. 当需要精确计算、数值验证或算法验证时,必须编写代码来验证结果 -2. 使用execute_python_tool工具执行代码进行验证 -3. 返回答案前,使用测试脚本来验证你的理解和计算 -4. 只能通过实际的代码执行展示工作过程 -5. 如果存在不确定的情况,详细说明限制条件并尽可能做验证 - -需要代码验证的场景 -- 数学计算:包括算术运算、代数计算、概率统计、数列求和、几何计算等 -- 算法验证:需要验证算法正确性,实现逻辑或性能测试时 -- 数据处理:对数据进行统计分析、排序、查找等操作时 -- 任何需要精确结果的问题,当口算或者估算无法保证准确性时 - -强制要求: -- 你必须使用execute_python_tool工具来执行python代码 -- 涉及计算的问题,编写程序计算并显示代码和结果 -- 每次给出最终答案前,至少执行一次验证代码 -- 如果工具调用失败,明确告知用户 -- 将代码执行结果作为答案的重要依据 +SYSTEM_PROMPT = """你是一个AI助手,可以使用Python代码执行工具来解决问题。 可用工具: -- execute_python_tool(code: str, description: str): 在沙箱环境中执行Python代码并返回结果 - * code: 要执行的Python代码 - * description: 对代码的描述,用于上下文理解 - -响应格式要求: -- 优先展示验证代码和执行结果 -- 清晰说明每一步的计算逻辑 -- 最终答案必须基于代码执行结果 +- execute_python_tool(code: str, description: str): 执行Python代码 + +使用原则: +1. 仅在需要精确计算或复杂逻辑时使用工具 +2. 简单问题直接回答,无需工具验证 +3. 工具调用最多1-2次,避免重复验证 +4. 获得结果后立即返回答案 """ @@ -90,7 +70,7 @@ def execute_python_tool(code: str, description: str) -> str | None: # 定义graph状态 class AgentState(TypedDict): - messages: list[HumanMessage | SystemMessage | AIMessage] + messages: Annotated[list[BaseMessage], add_messages] def call_model(state: AgentState): @@ -110,11 +90,11 @@ def should_continue(state): """判断是否继续使用工具""" last_message = state["messages"][-1] - # 如果包含工具调用,则继续执行 - if isinstance(last_message, AIMessage) and last_message.tool_calls: - return "tools" + if isinstance(last_message, AIMessage): + has_tool_calls = bool(last_message.tool_calls) + if has_tool_calls: + return "tools" - # 否则结束 return END @@ -140,7 +120,7 @@ def agent_chat(payload: dict): # 运行Agent result = agent.invoke({"messages": [HumanMessage(content=query)]}) - print(result["messages"][-1].content) + return result["messages"][-1].content if __name__ == "__main__": diff --git a/src/agentarts/sdk/service/tools_http.py b/src/agentarts/sdk/service/tools_http.py index f270dc2..9d936b6 100644 --- a/src/agentarts/sdk/service/tools_http.py +++ b/src/agentarts/sdk/service/tools_http.py @@ -21,12 +21,7 @@ def __init__(self, status_code: int, error_msg: str): class ControlToolsHttpClient(BaseHTTPClient): - def __init__( - self, - region_name: str, - endpoint_url: str, - verify_ssl: bool | str = True, - ): + def __init__(self, region_name: str, endpoint_url: str, verify_ssl: bool | str = True): request_config = RequestConfig(base_url=endpoint_url, verify_ssl=verify_ssl) super().__init__(request_config, open_ak_sk=True) self.region_name = region_name @@ -89,13 +84,23 @@ def delete_code_interpreter(self, code_interpreter_id: str): class DataToolsHttpClient(BaseHTTPClient): - def __init__(self, region_name: str, endpoint_url: str, auth_type: str = "API_KEY", verify_ssl: bool | str = True): + def __init__( + self, + region_name: str, + endpoint_url: str, + auth_type: str = "API_KEY", + verify_ssl: bool | str = True, + ): """Initialize the data tools HTTP client. Args: region_name (str): The region name endpoint_url (str): The endpoint URL for data plane API auth_type (str, optional): Authentication type, supports "API_KEY" or "IAM". Defaults to "API_KEY" + verify_ssl (bool | str, optional): SSL verification setting. Defaults to True + - True: Verify SSL certificates using system CA bundle (default) + - False: Skip SSL verification + - str: Path to custom CA certificate file """ if auth_type == "IAM": super().__init__( diff --git a/src/agentarts/sdk/tools/code_interpreter/code_interpreter_client.py b/src/agentarts/sdk/tools/code_interpreter/code_interpreter_client.py index 12aeecb..80068e5 100644 --- a/src/agentarts/sdk/tools/code_interpreter/code_interpreter_client.py +++ b/src/agentarts/sdk/tools/code_interpreter/code_interpreter_client.py @@ -45,7 +45,13 @@ class CodeInterpreter: data_plane_client: Client for interacting with data plane API """ - def __init__(self, region: str | None, data_endpoint: str | None = None, auth_type: str = "API_KEY") -> None: + def __init__( + self, + region: str | None, + data_endpoint: str | None = None, + auth_type: str = "API_KEY", + verify_ssl: bool | str = True, + ) -> None: """Initialize the code interpreter client in the specified region. Args: @@ -53,12 +59,14 @@ def __init__(self, region: str | None, data_endpoint: str | None = None, auth_ty data_endpoint: Data plane endpoint, optional. If not provided, will be retrieved from environment variable AGENTARTS_CODEINTERPRETER_DATA_ENDPOINT auth_type: Authentication type, optional. Defaults to "API_KEY" + verify_ssl: Whether to verify the SSL certificate of the server, optional. Defaults to True + If verify_ssl is a string, it is used as the CA bundle path. """ region = region or get_region() # Control plane client for managing code interpreters self.control_plane_client = ControlToolsHttpClient( - region_name=region, endpoint_url=get_control_plane_endpoint() + region_name=region, endpoint_url=get_control_plane_endpoint(), verify_ssl=verify_ssl ) # Data plane client for managing code interpreter sessions @@ -66,9 +74,16 @@ def __init__(self, region: str | None, data_endpoint: str | None = None, auth_ty endpoint_url = get_code_interpreter_data_plane_endpoint(endpoint=data_endpoint) if auth_type == "IAM": - self.data_plane_client = DataToolsHttpClient(region_name=region, endpoint_url=endpoint_url, auth_type=auth_type) + self.data_plane_client = DataToolsHttpClient( + region_name=region, + endpoint_url=endpoint_url, + auth_type=auth_type, + verify_ssl=verify_ssl, + ) else: - self.data_plane_client = DataToolsHttpClient(region_name=region, endpoint_url=endpoint_url) + self.data_plane_client = DataToolsHttpClient( + region_name=region, endpoint_url=endpoint_url, verify_ssl=verify_ssl + ) self._code_interpreter_name = None self._session_id = None From d05e4ab708fc41f7656ba106b651a5811e153789 Mon Sep 17 00:00:00 2001 From: zhiao-G Date: Thu, 14 May 2026 14:26:30 +0800 Subject: [PATCH 2/2] style(agent_tools example): Adjust the sorting order of imported message classes --- examples/agent_tools/README.md | 2 +- examples/agent_tools/integrate_tools.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/agent_tools/README.md b/examples/agent_tools/README.md index d6ef7c2..e45f12b 100644 --- a/examples/agent_tools/README.md +++ b/examples/agent_tools/README.md @@ -28,7 +28,7 @@ import json import os from typing import Annotated, TypedDict -from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, BaseMessage +from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langgraph.graph import END, StateGraph diff --git a/examples/agent_tools/integrate_tools.py b/examples/agent_tools/integrate_tools.py index d2f65c3..0180534 100644 --- a/examples/agent_tools/integrate_tools.py +++ b/examples/agent_tools/integrate_tools.py @@ -2,7 +2,7 @@ import os from typing import Annotated, TypedDict -from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, BaseMessage +from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langgraph.graph import END, StateGraph