Skip to content

Commit e0a3137

Browse files
committed
example: update from main repo
1 parent 1f3c7cf commit e0a3137

File tree

8 files changed

+513
-38
lines changed

8 files changed

+513
-38
lines changed

examples/basic/chat.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ def main(
4141
model: str = typer.Option("", "--model", "-m", help="model name"),
4242
no_stream: bool = typer.Option(False, "--nostream", "-ns", help="no streaming"),
4343
nocache: bool = typer.Option(False, "--nocache", "-nc", help="don't use cache"),
44-
query: str = typer.Option("", "--query", "-q", help="initial user query or msg"),
4544
sys_msg: str = typer.Option(
4645
"You are a helpful assistant. Be concise in your answers.",
4746
"--sysmsg",
@@ -83,14 +82,7 @@ def main(
8382
)
8483
agent = ChatAgent(config)
8584
task = Task(agent)
86-
# OpenAI models are ok with just a system msg,
87-
# but in some scenarios, other (e.g. llama) models
88-
# seem to do better when kicked off with a sys msg and a user msg.
89-
# In those cases we may want to do task.run("hello") instead.
90-
if query:
91-
task.run(query)
92-
else:
93-
task.run()
85+
task.run("hello")
9486

9587

9688
if __name__ == "__main__":
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
"""
2+
Function-calling example using a local LLM, with ollama.
3+
4+
"Function-calling" refers to the ability of the LLM to generate
5+
a structured response, typically a JSON object, instead of a plain text response,
6+
which is then interpreted by your code to perform some action.
7+
This is also referred to in various scenarios as "Tools", "Actions" or "Plugins".
8+
See more here: https://langroid.github.io/langroid/quick-start/chat-agent-tool/
9+
10+
Run like this (to run with llama-3.1-8b-instant via groq):
11+
12+
python3 examples/basic/text-to-structured.py -m groq/llama-3.1-8b-instant
13+
14+
Other models to try it with:
15+
- ollama/qwen2.5-coder
16+
- ollama/qwen2.5
17+
18+
19+
See here for how to set up a Local LLM to work with Langroid:
20+
https://langroid.github.io/langroid/tutorials/local-llm-setup/
21+
22+
23+
"""
24+
25+
import os
26+
from typing import List, Literal
27+
import fire
28+
import json
29+
from rich.prompt import Prompt
30+
31+
from langroid.pydantic_v1 import BaseModel, Field
32+
import langroid as lr
33+
from langroid.utils.configuration import settings
34+
from langroid.agent.tool_message import ToolMessage
35+
from langroid.agent.tools.orchestration import ResultTool
36+
import langroid.language_models as lm
37+
38+
# for best results:
39+
DEFAULT_LLM = lm.OpenAIChatModel.GPT4o
40+
41+
os.environ["TOKENIZERS_PARALLELISM"] = "false"
42+
43+
# (1) Define the desired structure via Pydantic.
44+
# The "Field" annotations are optional, and are included in the system message
45+
# if provided, and help with generation accuracy.
46+
47+
48+
class Wifi(BaseModel):
49+
name: str
50+
51+
52+
class HomeSettings(BaseModel):
53+
App: List[str] = Field(..., description="List of apps found in text")
54+
wifi: List[Wifi] = Field(..., description="List of wifi networks found in text")
55+
brightness: Literal["low", "medium", "high"] = Field(
56+
..., description="Brightness level found in text"
57+
)
58+
59+
60+
# (2) Define the Tool class for the LLM to use, to produce the above structure.
61+
class HomeAutomationTool(lr.agent.ToolMessage):
62+
"""Tool to extract Home Automation structure from text"""
63+
64+
request: str = "home_automation_tool"
65+
purpose: str = """
66+
To extract <home_settings> structure from a given text.
67+
"""
68+
home_settings: HomeSettings = Field(
69+
..., description="Home Automation settings from given text"
70+
)
71+
72+
def handle(self) -> str:
73+
"""Handle LLM's structured output if it matches HomeAutomationTool structure"""
74+
print(
75+
f"""
76+
SUCCESS! Got Valid Home Automation Settings:
77+
{json.dumps(self.home_settings.dict(), indent=2)}
78+
"""
79+
)
80+
return ResultTool(settings=self.home_settings)
81+
82+
@classmethod
83+
def examples(cls) -> List["ToolMessage"]:
84+
# Used to provide few-shot examples in the system prompt
85+
return [
86+
(
87+
"""
88+
I have extracted apps Spotify and Netflix,
89+
wifi HomeWifi, and brightness medium
90+
""",
91+
cls(
92+
home_settings=HomeSettings(
93+
App=["Spotify", "Netflix"],
94+
wifi=[Wifi(name="HomeWifi")],
95+
brightness="medium",
96+
)
97+
),
98+
)
99+
]
100+
101+
102+
def app(
103+
m: str = DEFAULT_LLM, # model
104+
d: bool = False, # pass -d to enable debug mode (see prompts etc)
105+
nc: bool = False, # pass -nc to disable cache-retrieval (i.e. get fresh answers)
106+
):
107+
settings.debug = d
108+
settings.cache = not nc
109+
# create LLM config
110+
llm_cfg = lm.OpenAIGPTConfig(
111+
chat_model=m or DEFAULT_LLM,
112+
chat_context_length=4096, # set this based on model
113+
max_output_tokens=100,
114+
temperature=0.2,
115+
stream=True,
116+
timeout=45,
117+
)
118+
119+
tool_name = HomeAutomationTool.default_value("request")
120+
config = lr.ChatAgentConfig(
121+
llm=llm_cfg,
122+
system_message=f"""
123+
You are an expert in extracting home automation settings from text.
124+
When user gives a piece of text, use the TOOL `{tool_name}`
125+
to present the extracted structured information.
126+
""",
127+
)
128+
129+
agent = lr.ChatAgent(config)
130+
131+
# (4) Enable the Tool for this agent --> this auto-inserts JSON instructions
132+
# and few-shot examples (specified in the tool defn above) into the system message
133+
agent.enable_message(HomeAutomationTool)
134+
135+
# (5) Create task and run it to start an interactive loop
136+
# Specialize the task to return a ResultTool object
137+
task = lr.Task(agent, interactive=False)[ResultTool]
138+
139+
# set up a loop to extract Home Automation settings from text
140+
while True:
141+
text = Prompt.ask("[blue]Enter text (or q/x to exit)")
142+
if not text or text.lower() in ["x", "q"]:
143+
break
144+
result = task.run(text)
145+
assert isinstance(result, ResultTool)
146+
assert isinstance(result.settings, HomeSettings)
147+
148+
149+
if __name__ == "__main__":
150+
fire.Fire(app)

examples/data-qa/sql-chat/sql_chat.py

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@
2929

3030
from utils import get_database_uri, fix_uri
3131
from langroid.agent.special.sql.sql_chat_agent import (
32-
SQLChatAgent,
3332
SQLChatAgentConfig,
33+
make_sql_chat_task,
3434
)
35-
from langroid.agent.task import Task, TaskConfig
3635
from langroid.language_models.openai_gpt import OpenAIChatModel, OpenAIGPTConfig
3736
from langroid.utils.configuration import set_global, Settings
3837
from langroid.utils.constants import SEND_TO
@@ -182,28 +181,22 @@ def main(
182181

183182
print(table)
184183

185-
agent = SQLChatAgent(
186-
config=SQLChatAgentConfig(
187-
name="sql",
188-
database_uri=database_uri,
189-
use_tools=tools,
190-
use_functions_api=not tools,
191-
show_stats=False,
192-
context_descriptions=context_descriptions, # Add context descriptions to the config
193-
use_schema_tools=schema_tools,
194-
addressing_prefix=SEND_TO,
195-
llm=OpenAIGPTConfig(
196-
chat_model=OpenAIChatModel.GPT4,
197-
),
198-
)
199-
)
200-
task_config = TaskConfig(addressing_prefix=SEND_TO)
201-
task = Task(
202-
agent,
203-
interactive=False,
204-
only_user_quits_root=True,
205-
config=task_config,
184+
agent_config = SQLChatAgentConfig(
185+
name="sql",
186+
database_uri=database_uri,
187+
use_tools=tools,
188+
use_functions_api=not tools,
189+
show_stats=False,
190+
chat_mode=True,
191+
context_descriptions=context_descriptions, # Add context descriptions to the config
192+
use_schema_tools=schema_tools,
193+
addressing_prefix=SEND_TO,
194+
llm=OpenAIGPTConfig(
195+
chat_model=OpenAIChatModel.GPT4,
196+
),
206197
)
198+
199+
task = make_sql_chat_task(agent_config, interactive=True, use_helper=True)
207200
task.run()
208201

209202

examples/docqa/chat-search.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@
66
77
Run like this:
88
9-
python3 examples/docqa/chat-search.py
9+
python3 examples/docqa/chat-search.py -m groq/llama-3.1-70b-versatile
10+
11+
The -m arg is optional, defaults to GPT4o
1012
1113
Optional args:
1214
-nc : turn off caching (i.e. don't retrieve cached LLM responses)
1315
-d: debug mode, to show all intermediate results
1416
-f: use OpenAI functions api instead of tools
15-
-m <model_name>: (e.g. -m ollama/mistral:7b-instruct-v0.2-q4_K_M)
17+
-m <model_name>: run with a specific LLM
1618
(defaults to GPT4-Turbo if blank)
1719
18-
(See here for guide to using local LLMs with Langroid:)
20+
See here for guide to using local LLMs with Langroid:
1921
https://langroid.github.io/langroid/tutorials/local-llm-setup/
2022
"""
2123

examples/docqa/chat.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@
55
Run like this:
66
python3 examples/docqa/chat.py
77
8+
To change the model, use the --model flag, e.g.:
9+
10+
python3 examples/docqa/chat.py --model ollama/mistral:7b-instruct-v0.2-q8_0
11+
12+
To change the embedding model, use the --embed flag, e.g.:
13+
14+
python3 examples/docqa/chat.py --embed BAAI/bge-large-en-v1.5
15+
16+
See here for how to set up a Local LLM to work with Langroid:
17+
https://langroid.github.io/langroid/tutorials/local-llm-setup/
18+
819
"""
920

1021
import typer
@@ -48,6 +59,7 @@ def main(
4859
chat_context_length=16_000, # adjust as needed
4960
temperature=0.2,
5061
max_output_tokens=300,
62+
timeout=60,
5163
)
5264

5365
config = DocChatAgentConfig(

0 commit comments

Comments
 (0)