fix: preserve agent debug conversation context

This commit is contained in:
2026-07-17 16:06:43 +08:00
parent cadf44e0b8
commit 537978082a
7 changed files with 92 additions and 15 deletions

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from datetime import datetime
from typing import Literal
from pydantic import BaseModel, Field
@@ -77,12 +78,18 @@ class PromptSaveRequest(BaseModel):
promptContent: str = Field(min_length=1)
class AgentDebugHistoryMessage(BaseModel):
role: Literal["user", "assistant"]
content: str = Field(min_length=1, max_length=20000)
class AgentDebugRequest(BaseModel):
promptContent: str = Field(min_length=1)
modelId: int = Field(gt=0)
knowledgeIds: list[int] = Field(default_factory=list)
knowledgeVersions: dict[int, int] = Field(default_factory=dict)
question: str = Field(min_length=1, max_length=2000)
history: list[AgentDebugHistoryMessage] = Field(default_factory=list, max_length=100)
temperature: float | None = Field(default=None, ge=0, le=2)
topP: float | None = Field(default=None, ge=0, le=1)
topK: int | None = Field(default=None, ge=1, le=1000)

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
import asyncio
from collections.abc import AsyncIterator
from types import SimpleNamespace
from sqlalchemy.orm import Session
@@ -12,31 +13,33 @@ from app.services.admin_service import OperationLogService
from app.services.knowledge_agent_service import KnowledgeAgentService
from app.services.model_stream_service import ModelStreamService
from app.services.reasoning_policy_service import ReasoningPolicyService
from app.services.rag_service import PromptService, RagResult
from app.services.rag_service import RagResult
class AgentDebugService:
@staticmethod
async def build_result(db: Session, payload: AgentDebugRequest) -> RagResult:
history = [
SimpleNamespace(id=index + 1, role=item.role, content=item.content)
for index, item in enumerate(payload.history)
]
rag_result = await KnowledgeAgentService.build_result(
db,
question=payload.question,
history=history,
version_overrides=payload.knowledgeVersions,
preview_knowledge_ids=payload.knowledgeIds,
prompt_override=payload.promptContent,
)
debug_messages = [
{"role": "system", "content": payload.promptContent.strip()},
*(rag_result.messages or []),
]
return RagResult(
question=rag_result.question,
knowledge_scopes=rag_result.knowledge_scopes,
chunks=rag_result.chunks,
prompt=PromptService.render_messages(debug_messages),
prompt=rag_result.prompt,
allow_general_knowledge=rag_result.allow_general_knowledge,
retrieval_log_id=rag_result.retrieval_log_id,
tool_trace=rag_result.tool_trace,
messages=debug_messages,
messages=rag_result.messages,
)
@staticmethod

View File

@@ -83,6 +83,7 @@ class KnowledgeAgentService:
version_overrides: dict[int, int] | None = None,
preview_knowledge_ids: list[int] | None = None,
context_trace: list[dict] | None = None,
prompt_override: str | None = None,
) -> RagResult:
started = perf_counter()
catalog = cls.get_knowledge_catalog(
@@ -205,6 +206,7 @@ class KnowledgeAgentService:
history,
session_summary,
summary_up_to_message_id,
prompt_override=prompt_override,
)
return RagResult(
question=question,
@@ -309,15 +311,23 @@ class KnowledgeAgentService:
text = question.strip()
if len(text) <= 16:
return True
if re.search(r"(上面|前面|之前|刚才|此前|前一个|原来).{0,8}(问题|内容|回答|练习|流程)", text):
return True
if re.search(r"(再|重新|继续).{0,6}(回答|解释|说明|分析|看看)", text):
return True
return bool(re.search(r"(这个|那个|上述|上面|前面|其中|第二|继续|然后呢|怎么办|怎么做|什么意思|为什么)$", text))
@staticmethod
def _fallback_rewrite(question: str, history) -> str:
previous_user = next(
(message.content.strip() for message in reversed(history) if message.role == "user" and message.content.strip()),
"",
)
return f"关于“{previous_user}”的追问:{question.strip()}" if previous_user else question.strip()
previous_users = [
message.content.strip()
for message in history
if message.role == "user" and message.content.strip()
][-3:]
if not previous_users:
return question.strip()
context = "\n".join(f"历史问题{index + 1}{content}" for index, content in enumerate(previous_users))
return f"结合以下历史问题回答当前追问:\n{context}\n当前追问:{question.strip()}"
@staticmethod
def get_knowledge_catalog(

View File

@@ -118,8 +118,9 @@ class PromptService:
history: list[ChatMessage] | None = None,
session_summary: str | None = None,
summary_up_to_message_id: int | None = None,
prompt_override: str | None = None,
) -> list[dict[str, str]]:
prompt = cls._load_active_prompt(db)
prompt = prompt_override.strip() if prompt_override and prompt_override.strip() else cls._load_active_prompt(db)
# 知识库上下文
context = "\n\n".join(cls._format_chunk(index, chunk) for index, chunk in enumerate(chunks, start=1))