feat(serving): replace MLflow run logging with native trace spans
Convert ml-serving from isolated MLflow runs to nested traces using mlflow.start_span_no_context(). The recommend endpoint now emits a full span tree: recommend (CHAIN) → build_context (TOOL), agent:* (AGENT) ×N, llm_orchestrator (LLM). Compute and infer endpoints each emit a single span. Supporting changes: - mlflow-skinny>=3.1.0 added to requirements - MLflow configured with --serve-artifacts + mlflow-artifacts:/ default root for cross-container artifact proxy (spans now persist from ml-serving) - --allowed-hosts extended to include mlflow:5000 (SDK includes port in Host) - science_destiny slider wired through prompts.py and recommend endpoint - Config page exposes science/destiny slider (0=data-driven, 100=intuitive) - Tip page shows rationale inline on tap Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -124,17 +124,52 @@ _SYS_V4_ORCHESTRATOR = (
|
||||
)
|
||||
|
||||
|
||||
def _science_destiny_instruction(science_destiny: int) -> str:
|
||||
"""Translate 0-100 slider into a prompt instruction.
|
||||
|
||||
0 = pure science: prioritise patterns, data, measurable progress.
|
||||
100 = pure destiny: prioritise meaning, intuition, deeper purpose.
|
||||
50 = balanced (no extra instruction injected).
|
||||
"""
|
||||
if science_destiny <= 20:
|
||||
return (
|
||||
"The user strongly prefers data-driven advice. "
|
||||
"Ground every tip in observable patterns, streaks, or measurable progress. "
|
||||
"Avoid abstract or motivational language."
|
||||
)
|
||||
if science_destiny <= 40:
|
||||
return (
|
||||
"The user leans toward evidence-based guidance. "
|
||||
"Anchor tips in patterns and metrics where possible."
|
||||
)
|
||||
if science_destiny >= 80:
|
||||
return (
|
||||
"The user strongly believes in intuition and meaning. "
|
||||
"Frame tips around purpose, values, and deeper intention rather than metrics."
|
||||
)
|
||||
if science_destiny >= 60:
|
||||
return (
|
||||
"The user leans toward intuitive, meaning-driven advice. "
|
||||
"Weave in purpose and intention alongside practicality."
|
||||
)
|
||||
return "" # balanced — no extra instruction
|
||||
|
||||
|
||||
def build_orchestrator_messages(
|
||||
agent_outputs: list[dict],
|
||||
tasks: list[dict],
|
||||
hour_of_day: int,
|
||||
day_of_week: int,
|
||||
science_destiny: int = 50,
|
||||
) -> list[dict]:
|
||||
"""Build the [system, user] message list for the orchestrator LLM call.
|
||||
|
||||
agent_outputs: list of {agent_id, prompt_text} dicts.
|
||||
Falls back to raw task summary when agent_outputs is empty.
|
||||
"""
|
||||
style_hint = _science_destiny_instruction(science_destiny)
|
||||
system = _SYS_V4_ORCHESTRATOR + (f"\n\n{style_hint}" if style_hint else "")
|
||||
|
||||
lines = [f"Current time: {hour_of_day:02d}:00, day_of_week={day_of_week}", ""]
|
||||
if agent_outputs:
|
||||
lines.append("Context from analysis agents:")
|
||||
@@ -150,7 +185,7 @@ def build_orchestrator_messages(
|
||||
lines.append(f" - {t.get('content', '?')}")
|
||||
lines.append("\nGenerate one tip as a JSON object. Write the tip content in English only.")
|
||||
return [
|
||||
{"role": "system", "content": _SYS_V4_ORCHESTRATOR},
|
||||
{"role": "system", "content": system},
|
||||
{"role": "user", "content": "\n".join(lines)},
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user