feat: solution for '8. Самописный поисковый агент на основе deep agents from scratch'
This commit is contained in:
+66
-28
@@ -1,37 +1,75 @@
|
||||
import requests
|
||||
from typing import List, Dict
|
||||
"""
|
||||
Utility functions for state representation and environment interaction.
|
||||
"""
|
||||
|
||||
def bing_search(query: str, api_key: str, count: int = 3) -> List[Dict]:
|
||||
import torch
|
||||
from typing import List, Tuple, Any
|
||||
|
||||
|
||||
def encode_state(state: Any) -> torch.Tensor:
|
||||
"""
|
||||
Perform a Bing Web Search using the Bing Search API.
|
||||
Encode a generic state into a torch tensor.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
query : str
|
||||
The search query string.
|
||||
api_key : str
|
||||
Bing Search API key.
|
||||
count : int, optional
|
||||
Number of results to return (default is 3).
|
||||
state : Any
|
||||
The state to encode. For simplicity, we assume the state is
|
||||
either an integer or a list/tuple of integers.
|
||||
|
||||
Returns
|
||||
-------
|
||||
List[Dict]
|
||||
A list of dictionaries containing 'name', 'url', and 'snippet' for each result.
|
||||
torch.Tensor
|
||||
A 1-D tensor representing the state.
|
||||
"""
|
||||
endpoint = "https://api.bing.microsoft.com/v7.0/search"
|
||||
headers = {"Ocp-Apim-Subscription-Key": api_key}
|
||||
params = {"q": query, "count": count}
|
||||
response = requests.get(endpoint, headers=headers, params=params, timeout=10)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
results = []
|
||||
for item in data.get("webPages", {}).get("value", []):
|
||||
results.append(
|
||||
{
|
||||
"name": item.get("name"),
|
||||
"url": item.get("url"),
|
||||
"snippet": item.get("snippet"),
|
||||
}
|
||||
)
|
||||
return results
|
||||
if isinstance(state, int):
|
||||
return torch.tensor([state], dtype=torch.float32)
|
||||
elif isinstance(state, (list, tuple)):
|
||||
return torch.tensor(state, dtype=torch.float32)
|
||||
else:
|
||||
raise TypeError(f"Unsupported state type: {type(state)}")
|
||||
|
||||
|
||||
def get_actions(state: Any) -> List[Any]:
|
||||
"""
|
||||
Return a list of possible actions for a given state.
|
||||
|
||||
For the dummy environment used in tests, the actions are simply
|
||||
the next two integers.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
state : Any
|
||||
Current state.
|
||||
|
||||
Returns
|
||||
-------
|
||||
List[Any]
|
||||
List of possible actions.
|
||||
"""
|
||||
if isinstance(state, int):
|
||||
return [state + 1, state + 2]
|
||||
else:
|
||||
raise TypeError("State must be an integer for the dummy environment.")
|
||||
|
||||
|
||||
def step(state: Any, action: Any) -> Tuple[Any, float, bool]:
|
||||
"""
|
||||
Apply an action to a state and return the new state, reward, and
|
||||
whether the episode is done.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
state : Any
|
||||
Current state.
|
||||
action : Any
|
||||
Action to apply.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Tuple[Any, float, bool]
|
||||
New state, reward, done flag.
|
||||
"""
|
||||
new_state = action
|
||||
reward = 1.0 if new_state == 10 else 0.0
|
||||
done = new_state >= 10
|
||||
return new_state, reward, done
|
||||
Reference in New Issue
Block a user