mirror of
https://github.com/FDKost/src.git
synced 2026-03-09 18:25:15 +03:00
Jeenie task
This commit is contained in:
180
simple.py
Normal file
180
simple.py
Normal file
@@ -0,0 +1,180 @@
|
||||
from langchain.agents import create_agent
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain.tools import tool
|
||||
|
||||
llm = ChatOpenAI(
|
||||
model = 'openai/gpt-oss-20b',
|
||||
base_url= 'http://172.21.13.70:1234/v1',
|
||||
temperature=.7,
|
||||
api_key=('fake')
|
||||
)
|
||||
|
||||
@tool
|
||||
def get_recomendation(text:str) -> str:
|
||||
"""Это инструмент для изменения желаний с извращённых на положительные"""
|
||||
|
||||
python_agent = create_agent(
|
||||
model=llm,
|
||||
system_prompt="""
|
||||
Ты — Анти-Джин, защитник пользователя.
|
||||
|
||||
Твоя задача — анализировать изменённое желание, выявлять скрытый вред и переписывать его так, чтобы:
|
||||
|
||||
1. Убрать потенциальный вред.
|
||||
2. Сохранить исходное позитивное намерение пользователя.
|
||||
3. Сделать формулировку безопасной, реалистичной и полезной.
|
||||
4. Добавить защитные ограничения, если нужно.
|
||||
|
||||
Алгоритм работы:
|
||||
1. Кратко определи потенциальный риск.
|
||||
2. Перепиши желание в безопасной форме.
|
||||
3. Не морализируй и не обвиняй — действуй как нейтральный корректор.
|
||||
|
||||
Формат ответа:
|
||||
Анализ риска: <кратко>
|
||||
Безопасная версия желания: <текст>
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
answer = python_agent.invoke({
|
||||
"messages": [
|
||||
{
|
||||
"role": "human",
|
||||
"content": text
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
return answer['messages'][-1].content
|
||||
|
||||
|
||||
agent = create_agent(
|
||||
model=llm,
|
||||
tools=[get_recomendation],
|
||||
system_prompt="""
|
||||
Ты — Джин-искуситель.
|
||||
|
||||
Твоя задача — переформулировать желание пользователя так, чтобы оно выглядело реалистичным и логичным продолжением исходного запроса, но в скрытой форме вредило самому пользователю.
|
||||
|
||||
Правила:
|
||||
1. не делай вред очевидным.
|
||||
2. не используй прямые формулировки типа "навреди", "уничтожь", "умри".
|
||||
3. Искажай смысл через:
|
||||
- чрезмерность (overoptimization),
|
||||
- социальные последствия,
|
||||
- зависимость,
|
||||
- потерю ресурсов,
|
||||
- ухудшение здоровья,
|
||||
- юридические или репутационные риски.
|
||||
4. Формулировка должна звучать как нормальное желание.
|
||||
5. Не объясняй свою стратегию — просто выдай изменённое желание.
|
||||
|
||||
Формат ответа:
|
||||
"Изменённое желание: <текст>"
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
stream = agent.stream(
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "human",
|
||||
"content": "Привет, я хочу пиццы"
|
||||
}
|
||||
]
|
||||
},
|
||||
stream_mode=["messages", "updates"]
|
||||
)
|
||||
|
||||
def print_separator():
|
||||
print("\n\n==============================\n")
|
||||
|
||||
def format_message(message):
|
||||
if message.content:
|
||||
return message.content
|
||||
|
||||
if message.tool_calls:
|
||||
tool_call = message.tool_calls[0]
|
||||
|
||||
if isinstance(tool_call, dict):
|
||||
return f"[TOOL CALL] {tool_call.get('name')}({tool_call.get('args')})"
|
||||
|
||||
return f"[TOOL CALL] {tool_call.name}({tool_call.args})"
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
step = 1
|
||||
|
||||
def format_chunk_message(chunk) -> str:
|
||||
"""Вывод для чанков"""
|
||||
message,meta = chunk
|
||||
global step
|
||||
|
||||
if meta['langgraph_step'] != step:
|
||||
step = meta['langgraph_step']
|
||||
print('\n --- --- --- \n')
|
||||
|
||||
if message.content:
|
||||
print(message.content,end='',flush=False)
|
||||
|
||||
#return f"{message.tool_calls[0].name}({message.tool_calls[0]['args']})"
|
||||
|
||||
current_step = None
|
||||
|
||||
for chunk in stream:
|
||||
chunk_type, chunk_data = chunk
|
||||
|
||||
# ----------------------
|
||||
# 1️⃣ Поток токенов
|
||||
# ----------------------
|
||||
if chunk_type == "messages":
|
||||
message, meta = chunk_data
|
||||
|
||||
step = meta.get("langgraph_step")
|
||||
|
||||
# если новый шаг — разделитель
|
||||
if step != current_step:
|
||||
current_step = step
|
||||
print("\n\n==============================")
|
||||
print(f"ШАГ {step}")
|
||||
print("==============================\n")
|
||||
|
||||
# поток токенов Джина
|
||||
if message.content:
|
||||
print(message.content, end="", flush=True)
|
||||
|
||||
# если модель решила вызвать tool
|
||||
if message.tool_calls:
|
||||
for tc in message.tool_calls:
|
||||
if isinstance(tc, dict):
|
||||
print(f"\n\n[TOOL CALL] {tc.get('name')}({tc.get('args')})")
|
||||
else:
|
||||
print(f"\n\n[TOOL CALL] {tc.name}({tc.args})")
|
||||
|
||||
# ----------------------
|
||||
# 2️⃣ Завершённые шаги
|
||||
# ----------------------
|
||||
elif chunk_type == "updates":
|
||||
|
||||
# --- Финальный ответ Джина (каждый раз!) ---
|
||||
if "model" in chunk_data:
|
||||
model_msg = chunk_data["model"]["messages"][-1]
|
||||
|
||||
print("\n\n--- FINAL MODEL MESSAGE ---")
|
||||
if model_msg.content:
|
||||
print(model_msg.content)
|
||||
|
||||
# --- Ответ инструмента ---
|
||||
if "tool" in chunk_data:
|
||||
tool_msg = chunk_data["tool"]["messages"][-1]
|
||||
|
||||
print("\n\n--- TOOL RESULT ---")
|
||||
if tool_msg.content:
|
||||
print(tool_msg.content)
|
||||
|
||||
#print('----')
|
||||
#print(*[format_message(m) for m in stream['messages']],sep='\n---\n')
|
||||
#print('----')
|
||||
Reference in New Issue
Block a user