Add zai-sdk dependency and update model references to glm-4.5-air
This commit is contained in:
@@ -21,7 +21,7 @@ def main() -> None:
|
||||
)
|
||||
parser.add_argument(
|
||||
"--reasoning-model",
|
||||
default="GLM-4.7",
|
||||
default="glm-4.5-air",
|
||||
help="Model for the final answer",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -18,6 +18,7 @@ dependencies = [
|
||||
"langgraph-api",
|
||||
"fastapi",
|
||||
"tavily-python",
|
||||
"zai-sdk",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -9,21 +9,21 @@ class Configuration(BaseModel):
|
||||
"""The configuration for the agent."""
|
||||
|
||||
query_generator_model: str = Field(
|
||||
default="GLM-4.7",
|
||||
default="glm-4.5-air",
|
||||
metadata={
|
||||
"description": "The name of the language model to use for the agent's query generation."
|
||||
},
|
||||
)
|
||||
|
||||
reflection_model: str = Field(
|
||||
default="GLM-4.7",
|
||||
default="glm-4.5-air",
|
||||
metadata={
|
||||
"description": "The name of the language model to use for the agent's reflection."
|
||||
},
|
||||
)
|
||||
|
||||
answer_model: str = Field(
|
||||
default="GLM-4.7",
|
||||
default="glm-4.5-air",
|
||||
metadata={
|
||||
"description": "The name of the language model to use for the agent's answer."
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ from langgraph.graph import START, END
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
from langchain_openai import ChatOpenAI
|
||||
from tavily import TavilyClient
|
||||
from zai import ZhipuAiClient
|
||||
|
||||
from agent.state import (
|
||||
OverallState,
|
||||
@@ -40,6 +41,7 @@ if os.getenv("TAVILY_API_KEY") is None:
|
||||
raise ValueError("TAVILY_API_KEY is not set")
|
||||
|
||||
tavily_client = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
|
||||
zhipu_client = ZhipuAiClient(api_key=os.getenv("OPENAI_API_KEY"))
|
||||
SchemaT = TypeVar("SchemaT", bound=BaseModel)
|
||||
|
||||
|
||||
@@ -73,13 +75,17 @@ def _extract_json_payload(content: str) -> str:
|
||||
|
||||
|
||||
def _invoke_json_model(
|
||||
llm: ChatOpenAI,
|
||||
model: str,
|
||||
prompt: str,
|
||||
schema: type[SchemaT],
|
||||
) -> SchemaT:
|
||||
"""Invoke the model for JSON text and validate it with Pydantic."""
|
||||
result = llm.invoke(prompt)
|
||||
content = result.content if isinstance(result.content, str) else str(result.content)
|
||||
"""Invoke the model via zai-sdk JSON mode and validate with Pydantic."""
|
||||
response = zhipu_client.chat.completions.create(
|
||||
model=model,
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
response_format={"type": "json_object"},
|
||||
)
|
||||
content = response.choices[0].message.content
|
||||
json_payload = _extract_json_payload(content)
|
||||
|
||||
try:
|
||||
@@ -93,22 +99,25 @@ def _invoke_json_model(
|
||||
def _supports_native_structured_output(model: str) -> bool:
|
||||
"""Return whether the selected model should use LangChain structured output."""
|
||||
normalized = model.strip().lower()
|
||||
return normalized.startswith("glm-4.7")
|
||||
return not normalized.startswith("glm")
|
||||
|
||||
|
||||
def _invoke_structured_model(
|
||||
llm: ChatOpenAI,
|
||||
model: str,
|
||||
prompt: str,
|
||||
schema: type[SchemaT],
|
||||
) -> SchemaT:
|
||||
"""Use native structured output when supported, otherwise fall back to JSON parsing."""
|
||||
"""Use direct provider JSON mode for GLM, otherwise try native structured output."""
|
||||
if not _supports_native_structured_output(model):
|
||||
return _invoke_json_model(model, prompt, schema)
|
||||
|
||||
if _supports_native_structured_output(model):
|
||||
try:
|
||||
llm = create_llm(model, temperature=1.0)
|
||||
return llm.with_structured_output(schema).invoke(prompt)
|
||||
except ValueError:
|
||||
return _invoke_json_model(llm, prompt, schema)
|
||||
return _invoke_json_model(llm, prompt, schema)
|
||||
return _invoke_json_model(model, prompt, schema)
|
||||
return _invoke_json_model(model, prompt, schema)
|
||||
|
||||
|
||||
# Nodes
|
||||
@@ -130,8 +139,6 @@ def generate_query(state: OverallState, config: RunnableConfig) -> QueryGenerati
|
||||
if state.get("initial_search_query_count") is None:
|
||||
state["initial_search_query_count"] = configurable.number_of_initial_queries
|
||||
|
||||
llm = create_llm(configurable.query_generator_model, temperature=1.0)
|
||||
|
||||
current_date = get_current_date()
|
||||
formatted_prompt = query_writer_instructions.format(
|
||||
current_date=current_date,
|
||||
@@ -139,7 +146,6 @@ def generate_query(state: OverallState, config: RunnableConfig) -> QueryGenerati
|
||||
number_queries=state["initial_search_query_count"],
|
||||
)
|
||||
result = _invoke_structured_model(
|
||||
llm,
|
||||
configurable.query_generator_model,
|
||||
formatted_prompt,
|
||||
SearchQueryList,
|
||||
@@ -216,9 +222,7 @@ def reflection(state: OverallState, config: RunnableConfig) -> ReflectionState:
|
||||
research_topic=get_research_topic(state["messages"]),
|
||||
summaries="\n\n---\n\n".join(state["web_research_result"]),
|
||||
)
|
||||
llm = create_llm(reasoning_model, temperature=1.0)
|
||||
result = _invoke_structured_model(
|
||||
llm,
|
||||
reasoning_model,
|
||||
formatted_prompt,
|
||||
Reflection,
|
||||
|
||||
@@ -25,12 +25,10 @@ Format:
|
||||
Example:
|
||||
|
||||
Topic: What revenue grew more last year apple stock or the number of people buying an iphone
|
||||
```json
|
||||
{{
|
||||
"rationale": "To answer this comparative growth question accurately, we need specific data points on Apple's stock performance and iPhone sales metrics. These queries target the precise financial information needed: company revenue trends, product-specific unit sales figures, and stock price movement over the same fiscal period for direct comparison.",
|
||||
"query": ["Apple total revenue growth fiscal year 2024", "iPhone unit sales growth fiscal year 2024", "Apple stock price growth fiscal year 2024"]
|
||||
}}
|
||||
```
|
||||
|
||||
Context: {research_topic}"""
|
||||
|
||||
@@ -67,13 +65,11 @@ Output Format:
|
||||
- "follow_up_queries": Write a specific question to address this gap
|
||||
|
||||
Example:
|
||||
```json
|
||||
{{
|
||||
"is_sufficient": true, // or false
|
||||
"knowledge_gap": "The summary lacks information about performance metrics and benchmarks", // "" if is_sufficient is true
|
||||
"follow_up_queries": ["What are typical performance benchmarks and metrics used to evaluate [specific technology]?"] // [] if is_sufficient is true
|
||||
"is_sufficient": true,
|
||||
"knowledge_gap": "",
|
||||
"follow_up_queries": []
|
||||
}}
|
||||
```
|
||||
|
||||
Reflect carefully on the Summaries to identify knowledge gaps and produce a follow-up query. Then, produce your output following this JSON format:
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export const InputForm: React.FC<InputFormProps> = ({
|
||||
}) => {
|
||||
const [internalInputValue, setInternalInputValue] = useState("");
|
||||
const [effort, setEffort] = useState("medium");
|
||||
const [model, setModel] = useState("GLM-4.7");
|
||||
const [model, setModel] = useState("glm-4.5-air");
|
||||
|
||||
const handleInternalSubmit = (e?: React.FormEvent) => {
|
||||
if (e) e.preventDefault();
|
||||
@@ -135,6 +135,14 @@ export const InputForm: React.FC<InputFormProps> = ({
|
||||
<SelectValue placeholder="Model" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="bg-neutral-700 border-neutral-600 text-neutral-300 cursor-pointer">
|
||||
<SelectItem
|
||||
value="glm-4.5-air"
|
||||
className="hover:bg-neutral-600 focus:bg-neutral-600 cursor-pointer"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<Zap className="h-4 w-4 mr-2 text-emerald-400" /> glm-4.5-air
|
||||
</div>
|
||||
</SelectItem>
|
||||
<SelectItem
|
||||
value="GLM-4.7"
|
||||
className="hover:bg-neutral-600 focus:bg-neutral-600 cursor-pointer"
|
||||
|
||||
@@ -33,7 +33,7 @@ export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-neutral-500">
|
||||
Powered by GLM-4.7, Tavily, and LangChain LangGraph.
|
||||
Powered by glm-4.5-air, GLM-4.7, Tavily, and LangChain LangGraph.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user