Skip to content

Commit 832518e

Browse files
committed
basic agentic flow
1 parent 68fa2fd commit 832518e

File tree

5 files changed

+73
-2
lines changed

5 files changed

+73
-2
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
**This is a mirror of [service repo](https://github.com/road-core/service.git). This repo will target to implement agentic flow. Currently in experimental stage.**
44

5+
- Dummy functions are used to define tools
6+
- Only works with GPT
7+
- Basic implementation
8+
9+
---
510
Road Core Service (RCS) is an AI powered assistant that runs on OpenShift
611
and provides answers to product questions using backend LLM services. Currently
712
[OpenAI](https://openai.com/), [Azure

ols/src/prompts/prompt_generator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def _generate_prompt_gpt(self) -> tuple[ChatPromptTemplate, dict]:
9090
prompt_message.append(MessagesPlaceholder("chat_history"))
9191

9292
prompt_message.append(HumanMessagePromptTemplate.from_template("{query}"))
93+
prompt_message.append(MessagesPlaceholder(variable_name="agent_scratchpad"))
9394
return ChatPromptTemplate.from_messages(prompt_message), llm_input_values
9495

9596
def _generate_prompt_granite(self) -> tuple[PromptTemplate, dict]:
@@ -111,6 +112,7 @@ def _generate_prompt_granite(self) -> tuple[PromptTemplate, dict]:
111112
prompt_message = prompt_message + "\n{chat_history}"
112113

113114
prompt_message = prompt_message + "\n<|user|>\n{query}\n<|assistant|>\n"
115+
# prompt_message = prompt_message + "\n{agent_scratchpad}"
114116
return PromptTemplate.from_template(prompt_message), llm_input_values
115117

116118
def generate_prompt(

ols/src/query_helpers/docs_summarizer.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
from langchain.chains import LLMChain
77
from llama_index.core import VectorStoreIndex
8+
from langchain_core.messages import HumanMessage
9+
from langchain.agents import AgentExecutor, create_tool_calling_agent
810

911
from ols import config
1012
from ols.app.metrics import TokenMetricUpdater
@@ -13,6 +15,7 @@
1315
from ols.constants import RAG_CONTENT_LIMIT, GenericLLMParameters
1416
from ols.src.prompts.prompt_generator import GeneratePrompt
1517
from ols.src.prompts.prompts import QUERY_SYSTEM_INSTRUCTION
18+
from ols.src.tools.func_def import tools
1619
from ols.src.query_helpers.query_helper import QueryHelper
1720
from ols.utils.token_handler import TokenHandler
1821

@@ -90,6 +93,16 @@ def summarize(
9093
temp_prompt, temp_prompt_input = GeneratePrompt(
9194
query, ["sample"], ["ai: sample"], self._system_prompt
9295
).generate_prompt(self.model)
96+
97+
temp_msg_placeholder = None
98+
if "granite" in self.model:
99+
# temp_msg_placeholder = ""
100+
pass
101+
else:
102+
temp_msg_placeholder = [HumanMessage(content="")]
103+
104+
if temp_msg_placeholder is not None:
105+
temp_prompt_input["agent_scratchpad"] = temp_msg_placeholder
93106
available_tokens = token_handler.calculate_and_check_available_tokens(
94107
temp_prompt.format(**temp_prompt_input),
95108
model_config.context_window_size,
@@ -119,6 +132,8 @@ def summarize(
119132
# Tokens-check: We trigger the computation of the token count
120133
# without care about the return value. This is to ensure that
121134
# the query is within the token limit.
135+
if temp_msg_placeholder is not None:
136+
llm_input_values["agent_scratchpad"] = temp_msg_placeholder
122137
token_handler.calculate_and_check_available_tokens(
123138
final_prompt.format(**llm_input_values),
124139
model_config.context_window_size,
@@ -131,18 +146,29 @@ def summarize(
131146
verbose=verbose,
132147
)
133148

149+
if "granite" in self.model:
150+
model_engine = chat_engine
151+
else:
152+
agent = create_tool_calling_agent(bare_llm, tools, final_prompt)
153+
model_engine = AgentExecutor(agent=agent, tools=tools, verbose=True)
154+
134155
with TokenMetricUpdater(
135156
llm=bare_llm,
136157
provider=provider_config.type,
137158
model=self.model,
138159
) as token_counter:
139-
summary = chat_engine.invoke(
160+
summary = model_engine.invoke(
161+
# summary = agent_executor.invoke(
162+
verbose=True,
140163
input=llm_input_values,
141164
config={"callbacks": [token_counter]},
142165
)
143166

144167
# retrieve text response returned from LLM, strip whitespace characters from beginning/end
145-
response = summary["text"].strip()
168+
if "text" in summary:
169+
response = summary["text"].strip()
170+
else:
171+
response = summary["output"].strip()
146172

147173
if len(rag_context) == 0:
148174
logger.debug("Using llm to answer the query without reference content")

ols/src/tools/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Functions/Tools definition."""

ols/src/tools/func_def.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""Functions/Tools definition."""
2+
3+
from typing import Optional
4+
5+
from langchain.tools import tool
6+
7+
8+
# Using dummy functions for experimentation
9+
@tool
10+
def get_pods(namespace: str) -> str:
11+
"""Get pod names from specific namespace."""
12+
if namespace == "lightspeed":
13+
return f"{namespace}_pod1"
14+
return "I don't have information"
15+
16+
17+
# @tool
18+
# def get_pods_memory(namespace: str = None, pod: str = None) -> float:
19+
# """Get memory usage by namespace."""
20+
# if pod:
21+
# pass
22+
# elif namespace == "lightspeed":
23+
# pod = get_pods(namespace)
24+
# else:
25+
# return "I don't have information"
26+
# return 2 * len(pod)
27+
28+
29+
@tool
30+
def get_pods_memory(pod: Optional[str] = None) -> float:
31+
"""Get memory usage by namespace."""
32+
if pod:
33+
return 2 * len(pod)
34+
return "I don't have information"
35+
36+
37+
tools = [get_pods, get_pods_memory]

0 commit comments

Comments
 (0)