xintongsong commented on code in PR #211:
URL: https://github.com/apache/flink-agents/pull/211#discussion_r2378477044
##########
python/flink_agents/api/agent.py:
##########
@@ -128,239 +132,34 @@ def add_action(
self._actions[name] = (events, func, config if config else None)
return self
- def add_prompt(self, name: str, prompt: Prompt) -> "Agent":
- """Add prompt to agent.
-
- Parameters
- ----------
- name : str
- The name of the prompt, should be unique in the same Agent.
- prompt: Prompt
- The prompt to be used in the agent.
-
- Returns:
- -------
- Agent
- The modified Agent instance.
- """
- if ResourceType.PROMPT not in self._resources:
- self._resources[ResourceType.PROMPT] = {}
- if name in self._resources[ResourceType.PROMPT]:
- msg = f"Prompt {name} already defined"
- raise ValueError(msg)
- self._resources[ResourceType.PROMPT][name] = prompt
- return self
-
- def add_tool(self, name: str, func: Callable) -> "Agent":
- """Add function tool to agent.
-
- Parameters
- ----------
- name : str
- The name of the tool, should be unique in the same Agent.
- func: Callable
- The execution function of the tool.
-
- Returns:
- -------
- Agent
- The modified Agent instance.
- """
- if ResourceType.TOOL not in self._resources:
- self._resources[ResourceType.TOOL] = {}
- if name in self._resources[ResourceType.TOOL]:
- msg = f"Function tool {name} already defined"
- raise ValueError(msg)
- self._resources[ResourceType.TOOL][name] = func
- return self
-
- def add_chat_model_connection(
- self, name: str, connection: Type[BaseChatModelConnection], **kwargs:
Any
+ def add_resource(
+ self, name: str, instance: SerializableResource |
ResourceDescriptor | Callable
) -> "Agent":
- """Add chat model connection to agent.
+ """Add resource to agent instance.
Parameters
----------
name : str
- The name of the chat model connection, should be unique in the
same Agent.
- connection: Type[BaseChatModelConnection]
- The type of chat model connection.
- **kwargs: Any
- Initialize keyword arguments passed to the chat model connection.
-
- Returns:
- -------
- Agent
- The modified Agent instance.
- """
- if ResourceType.CHAT_MODEL_CONNECTION not in self._resources:
- self._resources[ResourceType.CHAT_MODEL_CONNECTION] = {}
- if name in self._resources[ResourceType.CHAT_MODEL_CONNECTION]:
- msg = f"Chat model connection {name} already defined"
- raise ValueError(msg)
- kwargs["name"] = name
- self._resources[ResourceType.CHAT_MODEL_CONNECTION][name] =
(connection, kwargs)
- return self
-
- def add_chat_model_setup(
- self, name: str, chat_model: Type[BaseChatModelSetup], **kwargs: Any
- ) -> "Agent":
- """Add chat model setup to agent.
-
- Parameters
- ----------
- name : str
- The name of the chat model, should be unique in the same Agent.
- chat_model: Type[BaseChatModel]
- The type of chat model.
- **kwargs: Any
- Initialize keyword arguments passed to the chat model setup.
-
- Returns:
- -------
- Agent
- The modified Agent instance.
- """
- if ResourceType.CHAT_MODEL not in self._resources:
- self._resources[ResourceType.CHAT_MODEL] = {}
- if name in self._resources[ResourceType.CHAT_MODEL]:
- msg = f"Chat model setup {name} already defined"
- raise ValueError(msg)
- kwargs["name"] = name
- self._resources[ResourceType.CHAT_MODEL][name] = (chat_model, kwargs)
- return self
-
- def add_embedding_model_connection(
- self, name: str, connection: Type[BaseEmbeddingModelConnection],
**kwargs: Any
- ) -> "Agent":
- """Add embedding model connection to agent.
-
- Parameters
- ----------
- name : str
- The name of the embedding model connection, should be unique in
the same
- Agent.
- connection: Type[BaseEmbeddingModelConnection]
- The type of embedding model connection.
- **kwargs: Any
- Initialize keyword arguments passed to the embedding model
connection.
-
- Returns:
- -------
- Agent
- The modified Agent instance.
- """
- if ResourceType.EMBEDDING_MODEL_CONNECTION not in self._resources:
- self._resources[ResourceType.EMBEDDING_MODEL_CONNECTION] = {}
- if name in self._resources[ResourceType.EMBEDDING_MODEL_CONNECTION]:
- msg = f"Embedding model connection {name} already defined"
- raise ValueError(msg)
- kwargs["name"] = name
- self._resources[ResourceType.EMBEDDING_MODEL_CONNECTION][name] =
(connection, kwargs)
- return self
-
- def add_embedding_model_setup(
- self, name: str, embedding_model: Type[BaseEmbeddingModelSetup],
**kwargs: Any
- ) -> "Agent":
- """Add embedding model setup to agent.
-
- Parameters
- ----------
- name : str
- The name of the embedding model, should be unique in the same
Agent.
- embedding_model: Type[BaseEmbeddingModelSetup]
- The type of embedding model.
- **kwargs: Any
- Initialize keyword arguments passed to the embedding model setup.
-
- Returns:
- -------
- Agent
- The modified Agent instance.
- """
- if ResourceType.EMBEDDING_MODEL not in self._resources:
- self._resources[ResourceType.EMBEDDING_MODEL] = {}
- if name in self._resources[ResourceType.EMBEDDING_MODEL]:
- msg = f"Embedding model setup {name} already defined"
- raise ValueError(msg)
- kwargs["name"] = name
- self._resources[ResourceType.EMBEDDING_MODEL][name] =
(embedding_model, kwargs)
- return self
-
- def add_mcp_server(self, name: str, mcp_server: MCPServer) -> "Agent":
- """Add an MCP server to the agent.
-
- Parameters
- ----------
- name : str
- The name of the MCP server, should be unique in the same Agent.
- mcp_server : MCPServer
- The MCP server resource instance.
+ The name of the prompt, should be unique in the same Agent.
+ instance: SerializableResource | ResourceDescriptor | Callable
+ The serializable resource instance, or the descriptor of resource,
+ or the tool function.
Returns:
-------
Agent
- The modified Agent instance.
+ The agent to add the resource.
"""
- if name in self._resources[ResourceType.MCP_SERVER]:
- msg = f"MCP server {name} already defined"
+ if isinstance(instance, SerializableResource):
+ resource_type = instance.resource_type()
+ elif isinstance(instance, Callable):
+ resource_type = ResourceType.TOOL
Review Comment:
It's a bit fragile to assume all the callables are tools. We might introduce
something like `Tool.from_function()`, similar to `Prompt.from_text()`.
##########
python/flink_agents/api/chat_models/chat_model.py:
##########
@@ -181,10 +185,17 @@ def chat(self, messages: Sequence[ChatMessage], **kwargs:
Any) -> ChatMessage:
else:
prompt = self.prompt
- input_variable = {}
+ prompt_messages = []
for msg in messages:
- input_variable.update(msg.extra_args)
- messages = prompt.format_messages(**input_variable)
+ # Only apply user prompt on user message, to avoid throw away
llm and
+ # tool response.
+ if msg.role == MessageRole.USER:
+ prompt_messages.extend(
+ prompt.format_messages(role=MessageRole.USER,
**msg.extra_args)
+ )
+ else:
+ prompt_messages.append(msg)
+ messages = prompt_messages
Review Comment:
I think for each message passed into `chat()`, we should do both updating
the variables and appending the message to the prompts.
##########
python/flink_agents/examples/quickstart/resources/product_review.txt:
##########
@@ -1,5 +1,6 @@
{"id": "B010RRWKT4", "review": "Love these! I have 3 pairs...they're so
comfortable - I'm on my feet all day & my feet actually don't hurt at the end
of the day when I wear these :)\nI've learned to get these 1/2 size
smaller....I'm normally a size 7 and the 6 1/2 fit perfectly"}
{"id": "B000YFSR4W", "review": "comfy fit"}
+{"id": "B000YFSR4W", "review": "The magazine was already damaged when I
received it — the whole book was wet!"}
Review Comment:
Maybe adding a bit more shipping issues?
##########
python/flink_agents/examples/quickstart/agents/resources.py:
##########
@@ -0,0 +1,131 @@
+################################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#################################################################################
+from flink_agents.api.chat_message import ChatMessage, MessageRole
+from flink_agents.api.prompts.prompt import Prompt
+from flink_agents.api.resource import ResourceDescriptor
+from flink_agents.integrations.chat_models.ollama_chat_model import (
+ OllamaChatModelConnection,
+)
+
+# Prompt for review analysis agent.
+review_analysis_system_prompt_str = """
+ Analyze the user review and product information to determine a
+ satisfaction score (1-5) and potential reasons for dissatisfaction.
+
+ Example input format:
+ {{
+ "id": "12345",
+ "review": "The headphones broke after one week of use. Very poor
quality."
+ }}
+
+ Ensure your response can be parsed by Python JSON, using this format as an
example:
+ {{
+ "id": "12345",
+ "score": 1,
+ "reasons": [
+ "poor quality"
+ ]
+ }}
+
+ Please note that if a product review includes dissatisfaction with the
shipping process,
+ you should first notify the shipping manager using the appropriate tools.
After executing
+ the tools, strictly follow the example above to provide your score and
reason — there is
+ no need to disclose whether the tool was used.
+ """
+
+review_analysis_prompt = Prompt.from_messages(
+ messages=[
+ ChatMessage(
+ role=MessageRole.SYSTEM,
+ content=review_analysis_system_prompt_str,
+ ),
+ ChatMessage(
+ role=MessageRole.USER,
+ content="""
+ "input":
+ {input}
+ """,
+ ),
+ ],
+)
+
+# Prompt for product suggestion agent.
+product_suggestion_prompt_str = """
+ Based on the rating distribution and user dissatisfaction reasons,
generate three actionable suggestions for product improvement.
+
+ Input format:
+ {{
+ "id": "1",
+ "score_histogram": ["10%", "20%", "10%", "15%", "45%"],
+ "unsatisfied_reasons": ["reason1", "reason2", "reason3"]
+ }}
+
+ Ensure that your response can be parsed by Python json,use the
following format as an example:
+ {{
+ "suggestion_list": [
+ "suggestion1",
+ "suggestion2",
+ "suggestion3"
+ ]
+ }}
+
+ input:
+ {input}
+ """
+product_suggestion_prompt = Prompt.from_text(product_suggestion_prompt_str)
+
+# Prompt for review analysis react agent.
+review_analysis_react_prompt = Prompt.from_messages(
Review Comment:
Why is this different from `review_analysis_prompt`? We should explain in
the example.
##########
python/flink_agents/examples/quickstart/agents/resources.py:
##########
@@ -0,0 +1,131 @@
+################################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#################################################################################
+from flink_agents.api.chat_message import ChatMessage, MessageRole
Review Comment:
I think we can also move the custom types and tools here.
##########
python/flink_agents/examples/quickstart/agents/resources.py:
##########
@@ -0,0 +1,131 @@
+################################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#################################################################################
+from flink_agents.api.chat_message import ChatMessage, MessageRole
Review Comment:
File name: custom_types_and_resources.py
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]