Сторонний OpenAI совместимый endpoint не гарантирует поддержку встроенного веб поиска: это зависит от конкретного провайдера и модели.[5] Более универсальный вариант — сначала выполнить поиск через Tavily, а затем передать найденные материалы вместе с TXT данными в запрос к модели.[1][3] Вызовы Chat Completions сами...
Ответ на исследование

Create a landscape editorial hero image for this Studio Global article: 我想让其在分析数据的时候连接网络搜索,帮我改一下代码,另外它会有记忆吗?我之前喂给它的东西会记得吗. Article summary: 可以,但你当前使用的是第三方 OpenAI 兼容接口,无法确定 deepseek v4 flash 是否原生支持联网工具。官方 OpenAI 的内置网页搜索主要通过 Responses API 提供,而第三方 base url 不一定兼容该功能。[5] 因此,下面采用更通用的方案:程序先调用 Tavily 搜索互联网,再把搜索结果连同 TXT 数据一起交给模型分析;Tavily 支持通过 API Key 调用搜索接口并返回结构化结果。[. Topic tags: deepresearch, general web, openai, agents, prompt engineering. Style: premium digital editorial illustration, source-backed research mood, clean composition, high detail, modern web publication hero. Use reference image context only for broad subject, composition, and topical grounding; do not copy the exact image. Avoid: logos, brand marks, copyrighted characters, real person likenesses, fake screenshots, UI text, readable text, watermarks, charts with fake numbers, clickbait thumbnails, icons, and tiny thumbnail layout
Если модель должна учитывать не только TXT-файл, но и актуальные сведения из интернета, лучше не рассчитывать на «магическое» подключение веб-поиска внутри стороннего OpenAI-совместимого API. Встроенный поиск OpenAI доступен через Responses API, однако произвольный base_url может не поддерживать этот инструмент.5
Для вашего сценария надёжнее разделить задачу на два этапа:
Tavily предоставляет API с аутентификацией по API-ключу и возвращает структурированные результаты поиска.1
3
Установите зависимости:
pip install openai requests
Задайте ключи через переменные окружения. В Windows PowerShell:
$env:AI_API_KEY="ваш ключ AI API"
$env:AI_BASE_URL="https://адрес-совместимого-api/v1"
$env:TAVILY_API_KEY="ваш ключ Tavily"
В конфигурации Python можно оставить такие параметры:
import os
from pathlib import Path
API_KEY = os.getenv("AI_API_KEY", "")
BASE_URL = os.getenv("AI_BASE_URL", "")
TAVILY_API_KEY = os.getenv("TAVILY_API_KEY", "")
MODEL_NAME = "deepseek-v4-flash"
TXT_FILE = Path("data.txt")
FINAL_OUTPUT_FILE = Path("analysis_result.txt")
WEB_SOURCE_OUTPUT_FILE = Path("web_sources.txt")
ENABLE_WEB_SEARCH = True
TAVILY_SEARCH_URL = "https://api.tavily.com/search"
SEARCH_RESULTS_PER_QUERY = 5
SEARCH_DEPTH = "advanced"
Сам запрос к Tavily может выглядеть так:
import requests
def search_tavily(query: str) -> list[dict]:
if not TAVILY_API_KEY:
raise ValueError("Не задана переменная TAVILY_API_KEY")
response = requests.post(
TAVILY_SEARCH_URL,
headers={
"Authorization": f"Bearer {TAVILY_API_KEY}",
"Content-Type": "application/json",
},
json={
"query": query,
"search_depth": SEARCH_DEPTH,
"max_results": SEARCH_RESULTS_PER_QUERY,
"include_answer": False,
"include_raw_content": False,
"include_images": False,
},
timeout=60,
)
response.raise_for_status()
return response.json().get("results", [])
После этого результаты нужно превратить в компактный контекст для модели. Важно сохранить заголовок, URL и краткое содержание каждой страницы, чтобы модель могла ссылаться на конкретный источник:
def format_web_context(results: list[dict], max_chars: int = 18000) -> str:
blocks = []
total_chars = 0
for index, item in enumerate(results, start=1):
title = str(item.get("title", "Без заголовка")).strip()
url = str(item.get("url", "")).strip()
content = str(item.get("content", "")).strip()[:1200]
block = (
f"[W{index}]\n"
f"Заголовок: {title}\n"
f"URL: {url}\n"
f"Краткое содержание: {content}\n"
)
if blocks and total_chars + len(block) > max_chars:
break
blocks.append(block)
total_chars += len(block)
return "\n".join(blocks) or "Нет доступных результатов веб-поиска."
В итоговом запросе явно объясните модели, что именно является данными, а что — внешними материалами:
user_prompt = f"""
Проанализируй данные из TXT-файла.
Правила:
- символы x и X означают пропуск или недействительное значение;
- не считай x и X числом 0;
- не выдумывай значения, которых нет в данных;
- факты из TXT не требуют внешних ссылок;
- если используешь веб-материалы, ставь ссылки [W1], [W2] и так далее;
- отделяй наблюдения по данным от общих физических объяснений;
- если доказательств недостаточно, напиши «доказательств недостаточно».
================ DATA BEGIN ================
{txt_chunk}
================= DATA END =================
================ WEB BEGIN =================
{web_context}
================= WEB END ==================
"""
Для поиска можно использовать заранее заданные запросы, например:
queries = [
"MOSFET gate length threshold voltage Idsat Ioff DIBL",
"subthreshold swing short channel effects semiconductor device",
"VtSat VtLin IdSat IdLin Ioff tradeoff physical interpretation",
]
all_results = []
seen_urls = set()
for query in queries:
for result in search_tavily(query):
url = str(result.get("url", "")).strip()
if url and url not in seen_urls:
seen_urls.add(url)
all_results.append(result)
web_context = format_web_context(all_results)
Сохранять список найденных страниц в web_sources.txt полезно для проверки: поисковая выдача может быть неполной, а краткое содержание страницы не заменяет чтение первоисточника.
В приведённом коде есть строка:
content = response.choices.message.content
У choices обычно возвращается список вариантов ответа, поэтому следует обратиться к первому элементу:
content = response.choices.message.content
Иначе программа может завершиться ошибкой ещё до сохранения отчёта.
Нет, сам по себе вызов chat.completions.create() не означает, что модель навсегда запомнила предыдущие данные. Использование одного и того же объекта client или одного названия модели также не создаёт долговременную память. Историю и необходимый контекст приложение должно хранить самостоятельно и передавать в следующем запросе.2
6
В вашем варианте предусмотрена простая локальная память:
ENABLE_PERSISTENT_MEMORY = False
MEMORY_FILE = Path("analysis_memory.txt")
MEMORY_INPUT_MAX_CHARS = 12000
MEMORY_FILE_MAX_CHARS = 50000
Если изменить настройку на True, программа сможет:
analysis_memory.txt;Пример минимальной реализации:
from datetime import datetime
def load_memory() -> str:
if not ENABLE_PERSISTENT_MEMORY or not MEMORY_FILE.exists():
return ""
text = MEMORY_FILE.read_text(encoding="utf-8")
return text[-MEMORY_INPUT_MAX_CHARS:]
def save_memory(report: str) -> None:
if not ENABLE_PERSISTENT_MEMORY:
return
old_text = ""
if MEMORY_FILE.exists():
old_text = MEMORY_FILE.read_text(encoding="utf-8")
record = (
f"\n\n{'=' * 60}\n"
f"Время: {datetime.now():%Y-%m-%d %H:%M:%S}\n"
f"Файл: {TXT_FILE.name}\n"
f"{'=' * 60}\n"
f"{report}\n"
)
new_text = (old_text + record)[-MEMORY_FILE_MAX_CHARS:]
MEMORY_FILE.write_text(new_text, encoding="utf-8")
При этом такая память хранит не «знания модели», а текст, который программа снова отправляет ей в контексте запроса. Если анализируются разные устройства или проекты, лучше отключать эту функцию либо использовать отдельный файл памяти для каждого проекта. Иначе старые выводы могут повлиять на интерпретацию новых данных.
В предложенной схеме сохраняется только финальный отчёт, а не весь исходный TXT-файл. Поэтому модель не сможет восстановить все прежние строки данных, если они не попали в сохранённый отчёт. Кроме того, исторический текст не должен считаться доказательством: при конфликте приоритет имеют текущие данные и проверенные внешние источники.
Итого: для веб-доступа используйте Tavily как отдельный поисковый слой, передавайте результаты модели с идентификаторами [W1], [W2], а память реализуйте явно — через файл, базу данных или собственное хранилище истории. Автоматическая память у текущего Chat Completions-вызова не появляется.
Studio Global AI
На этой странице есть ответ, подтвержденный источником, который вы можете продолжить внутри Studio Global.
Сторонний OpenAI совместимый endpoint не гарантирует поддержку встроенного веб поиска: это зависит от конкретного провайдера и модели.[5]
Сторонний OpenAI совместимый endpoint не гарантирует поддержку встроенного веб поиска: это зависит от конкретного провайдера и модели.[5] Более универсальный вариант — сначала выполнить поиск через Tavily, а затем передать найденные материалы вместе с TXT данными в запрос к модели.[1][3]
Вызовы Chat Completions сами по себе не сохраняют историю: предыдущий контекст нужно хранить в приложении и отправлять повторно.[2][6]